[WK2] Small Caps font variant issue for Italic fonts
[framework/web/webkit-efl.git] / Source / WTF / wtf / ArrayBufferView.h
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef ArrayBufferView_h
27 #define ArrayBufferView_h
28
29 #include <wtf/ArrayBuffer.h>
30
31 #include <algorithm>
32 #include <limits.h>
33 #include <wtf/PassRefPtr.h>
34 #include <wtf/RefCounted.h>
35 #include <wtf/RefPtr.h>
36
37 namespace WTF {
38
39 class WTF_EXPORT_PRIVATE_RTTI ArrayBufferView : public RefCounted<ArrayBufferView> {
40   public:
41     enum ViewType {
42         TypeInt8,
43         TypeUint8,
44         TypeUint8Clamped,
45         TypeInt16,
46         TypeUint16,
47         TypeInt32,
48         TypeUint32,
49         TypeFloat32,
50         TypeFloat64,
51         TypeDataView
52     };
53     virtual ViewType getType() const = 0;
54
55     PassRefPtr<ArrayBuffer> buffer() const
56     {
57         return m_buffer;
58     }
59
60     void* baseAddress() const
61     {
62         return m_baseAddress;
63     }
64
65     unsigned byteOffset() const
66     {
67         return m_byteOffset;
68     }
69
70     virtual unsigned byteLength() const = 0;
71
72     WTF_EXPORT_PRIVATE_NO_RTTI virtual ~ArrayBufferView();
73
74   protected:
75     WTF_EXPORT_PRIVATE_NO_RTTI ArrayBufferView(PassRefPtr<ArrayBuffer>, unsigned byteOffset);
76
77     inline bool setImpl(ArrayBufferView*, unsigned byteOffset);
78
79     inline bool setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset);
80
81     inline bool zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength);
82
83     static inline void calculateOffsetAndLength(int start, int end, unsigned arraySize,
84                                          unsigned* offset, unsigned* length);
85
86     // Helper to verify that a given sub-range of an ArrayBuffer is
87     // within range.
88     template <typename T>
89     static bool verifySubRange(PassRefPtr<ArrayBuffer> buffer,
90                                unsigned byteOffset,
91                                unsigned numElements)
92     {
93         if (!buffer)
94             return false;
95         if (sizeof(T) > 1 && byteOffset % sizeof(T))
96             return false;
97         if (byteOffset > buffer->byteLength())
98             return false;
99         unsigned remainingElements = (buffer->byteLength() - byteOffset) / sizeof(T);
100         if (numElements > remainingElements)
101             return false;
102         return true;
103     }
104
105     // Input offset is in number of elements from this array's view;
106     // output offset is in number of bytes from the underlying buffer's view.
107     template <typename T>
108     static void clampOffsetAndNumElements(PassRefPtr<ArrayBuffer> buffer,
109                                           unsigned arrayByteOffset,
110                                           unsigned *offset,
111                                           unsigned *numElements)
112     {
113         unsigned maxOffset = (UINT_MAX - arrayByteOffset) / sizeof(T);
114         if (*offset > maxOffset) {
115             *offset = buffer->byteLength();
116             *numElements = 0;
117             return;
118         }
119         *offset = arrayByteOffset + *offset * sizeof(T);
120         *offset = std::min(buffer->byteLength(), *offset);
121         unsigned remainingElements = (buffer->byteLength() - *offset) / sizeof(T);
122         *numElements = std::min(remainingElements, *numElements);
123     }
124
125     WTF_EXPORT_PRIVATE_NO_RTTI virtual void neuter();
126
127     // This is the address of the ArrayBuffer's storage, plus the byte offset.
128     void* m_baseAddress;
129
130     unsigned m_byteOffset;
131
132   private:
133     friend class ArrayBuffer;
134     RefPtr<ArrayBuffer> m_buffer;
135     ArrayBufferView* m_prevView;
136     ArrayBufferView* m_nextView;
137 };
138
139 bool ArrayBufferView::setImpl(ArrayBufferView* array, unsigned byteOffset)
140 {
141     if (byteOffset > byteLength()
142         || byteOffset + array->byteLength() > byteLength()
143         || byteOffset + array->byteLength() < byteOffset) {
144         // Out of range offset or overflow
145         return false;
146     }
147     
148     char* base = static_cast<char*>(baseAddress());
149     memmove(base + byteOffset, array->baseAddress(), array->byteLength());
150     return true;
151 }
152
153 bool ArrayBufferView::setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset)
154 {
155     if (byteOffset > byteLength()
156         || byteOffset + dataByteLength > byteLength()
157         || byteOffset + dataByteLength < byteOffset) {
158         // Out of range offset or overflow
159         return false;
160     }
161     
162     char* base = static_cast<char*>(baseAddress());
163     memmove(base + byteOffset, data, dataByteLength);
164     return true;
165 }
166
167 bool ArrayBufferView::zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength)
168 {
169     if (byteOffset > byteLength()
170         || byteOffset + rangeByteLength > byteLength()
171         || byteOffset + rangeByteLength < byteOffset) {
172         // Out of range offset or overflow
173         return false;
174     }
175     
176     char* base = static_cast<char*>(baseAddress());
177     memset(base + byteOffset, 0, rangeByteLength);
178     return true;
179 }
180
181 void ArrayBufferView::calculateOffsetAndLength(int start, int end, unsigned arraySize,
182                                                unsigned* offset, unsigned* length)
183 {
184     if (start < 0)
185         start += arraySize;
186     if (start < 0)
187         start = 0;
188     if (end < 0)
189         end += arraySize;
190     if (end < 0)
191         end = 0;
192     if (static_cast<unsigned>(end) > arraySize)
193         end = arraySize;
194     if (end < start)
195         end = start;
196     *offset = static_cast<unsigned>(start);
197     *length = static_cast<unsigned>(end - start);
198 }
199
200 } // namespace WTF
201
202 using WTF::ArrayBufferView;
203
204 #endif // ArrayBufferView_h