OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 16 matching lines...) Expand all Loading... |
27 #define ArrayBuffer_h | 27 #define ArrayBuffer_h |
28 | 28 |
29 #include "wtf/ArrayBufferContents.h" | 29 #include "wtf/ArrayBufferContents.h" |
30 #include "wtf/HashSet.h" | 30 #include "wtf/HashSet.h" |
31 #include "wtf/PassRefPtr.h" | 31 #include "wtf/PassRefPtr.h" |
32 #include "wtf/RefCounted.h" | 32 #include "wtf/RefCounted.h" |
33 #include "wtf/WTFExport.h" | 33 #include "wtf/WTFExport.h" |
34 | 34 |
35 namespace WTF { | 35 namespace WTF { |
36 | 36 |
37 class ArrayBuffer; | |
38 class ArrayBufferView; | 37 class ArrayBufferView; |
39 | 38 |
40 class WTF_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> { | 39 class WTF_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> { |
41 public: | 40 public: |
42 static inline PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned
elementByteSize); | |
43 static inline PassRefPtr<ArrayBuffer> create(ArrayBuffer*); | |
44 static inline PassRefPtr<ArrayBuffer> create(const void* source, unsigned by
teLength); | |
45 static inline PassRefPtr<ArrayBuffer> create(ArrayBufferContents&); | 41 static inline PassRefPtr<ArrayBuffer> create(ArrayBufferContents&); |
46 | 42 |
| 43 static inline PassRefPtr<ArrayBuffer> createOrNull(ArrayBuffer*); |
| 44 static inline PassRefPtr<ArrayBuffer> createOrNull(const void* source, unsig
ned byteLength); |
47 static inline PassRefPtr<ArrayBuffer> createOrNull(unsigned numElements, uns
igned elementByteSize); | 45 static inline PassRefPtr<ArrayBuffer> createOrNull(unsigned numElements, uns
igned elementByteSize); |
48 | 46 |
| 47 static inline PassRefPtr<ArrayBuffer> deprecatedCreateOrCrash(const void* so
urce, unsigned byteLength); |
| 48 static inline PassRefPtr<ArrayBuffer> deprecatedCreateOrCrash(unsigned numEl
ements, unsigned elementByteSize); |
| 49 |
49 // Only for use by XMLHttpRequest::responseArrayBuffer and Internals::serial
izeObject | 50 // Only for use by XMLHttpRequest::responseArrayBuffer and Internals::serial
izeObject |
50 // (through DOMArrayBuffer::createUninitialized). | 51 // (through DOMArrayBuffer::createUninitialized). |
51 static inline PassRefPtr<ArrayBuffer> createUninitialized(unsigned numElemen
ts, unsigned elementByteSize); | 52 static inline PassRefPtr<ArrayBuffer> createUninitializedOrNull(unsigned num
Elements, unsigned elementByteSize); |
52 | 53 |
53 static inline PassRefPtr<ArrayBuffer> createShared(unsigned numElements, uns
igned elementByteSize); | 54 static inline PassRefPtr<ArrayBuffer> createSharedOrNull(unsigned numElement
s, unsigned elementByteSize); |
54 static inline PassRefPtr<ArrayBuffer> createShared(const void* source, unsig
ned byteLength); | 55 static inline PassRefPtr<ArrayBuffer> createSharedOrNull(const void* source,
unsigned byteLength); |
55 | 56 |
56 inline void* data(); | 57 inline void* data(); |
57 inline const void* data() const; | 58 inline const void* data() const; |
58 inline unsigned byteLength() const; | 59 inline unsigned byteLength() const; |
59 | 60 |
60 // Creates a new ArrayBuffer object with copy of bytes in this object | 61 // Creates a new ArrayBuffer object with copy of bytes in this object |
61 // ranging from |begin| upto but not including |end|. | 62 // ranging from |begin| upto but not including |end|. |
62 inline PassRefPtr<ArrayBuffer> slice(int begin, int end) const; | 63 inline PassRefPtr<ArrayBuffer> sliceOrNull(int begin, int end) const; |
63 inline PassRefPtr<ArrayBuffer> slice(int begin) const; | 64 inline PassRefPtr<ArrayBuffer> sliceOrNull(int begin) const; |
64 | 65 |
65 void addView(ArrayBufferView*); | 66 void addView(ArrayBufferView*); |
66 void removeView(ArrayBufferView*); | 67 void removeView(ArrayBufferView*); |
67 | 68 |
68 bool transfer(ArrayBufferContents&); | 69 bool transfer(ArrayBufferContents&); |
69 bool shareContentsWith(ArrayBufferContents&); | 70 bool shareContentsWith(ArrayBufferContents&); |
70 bool isNeutered() const { return m_isNeutered; } | 71 bool isNeutered() const { return m_isNeutered; } |
71 bool isShared() const { return m_contents.isShared(); } | 72 bool isShared() const { return m_contents.isShared(); } |
72 | 73 |
73 ~ArrayBuffer() { } | 74 ~ArrayBuffer() { } |
74 | 75 |
75 protected: | 76 protected: |
76 inline explicit ArrayBuffer(ArrayBufferContents&); | 77 inline explicit ArrayBuffer(ArrayBufferContents&); |
77 | 78 |
78 private: | 79 private: |
79 static inline PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned
elementByteSize, ArrayBufferContents::InitializationPolicy); | 80 static inline PassRefPtr<ArrayBuffer> create(unsigned numElements, unsigned
elementByteSize, ArrayBufferContents::InitializationPolicy, ArrayBufferContents:
:OutOfMemoryPolicy); |
80 static inline PassRefPtr<ArrayBuffer> createOrNull(unsigned numElements, uns
igned elementByteSize, ArrayBufferContents::InitializationPolicy); | 81 static inline PassRefPtr<ArrayBuffer> createSharedOrNull(unsigned numElement
s, unsigned elementByteSize, ArrayBufferContents::InitializationPolicy); |
81 static inline PassRefPtr<ArrayBuffer> createShared(unsigned numElements, uns
igned elementByteSize, ArrayBufferContents::InitializationPolicy); | |
82 | 82 |
83 inline PassRefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const
; | 83 inline PassRefPtr<ArrayBuffer> sliceOrNullImpl(unsigned begin, unsigned end)
const; |
84 inline unsigned clampIndex(int index) const; | 84 inline unsigned clampIndex(int index) const; |
85 static inline int clampValue(int x, int left, int right); | 85 static inline int clampValue(int x, int left, int right); |
86 | 86 |
87 ArrayBufferContents m_contents; | 87 ArrayBufferContents m_contents; |
88 ArrayBufferView* m_firstView; | 88 ArrayBufferView* m_firstView; |
89 bool m_isNeutered; | 89 bool m_isNeutered; |
90 }; | 90 }; |
91 | 91 |
92 int ArrayBuffer::clampValue(int x, int left, int right) | 92 int ArrayBuffer::clampValue(int x, int left, int right) |
93 { | 93 { |
94 ASSERT(left <= right); | 94 ASSERT(left <= right); |
95 if (x < left) | 95 if (x < left) |
96 x = left; | 96 x = left; |
97 if (right < x) | 97 if (right < x) |
98 x = right; | 98 x = right; |
99 return x; | 99 return x; |
100 } | 100 } |
101 | 101 |
102 PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned eleme
ntByteSize) | 102 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull(unsigned numElements, unsigned
elementByteSize) |
103 { | 103 { |
104 return create(numElements, elementByteSize, ArrayBufferContents::ZeroInitial
ize); | 104 return create(numElements, elementByteSize, ArrayBufferContents::ZeroInitial
ize, ArrayBufferContents::NullDataIfOutOfMemory); |
105 } | 105 } |
106 | 106 |
107 PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBuffer* other) | 107 PassRefPtr<ArrayBuffer> ArrayBuffer::deprecatedCreateOrCrash(unsigned numElement
s, unsigned elementByteSize) |
| 108 { |
| 109 return create(numElements, elementByteSize, ArrayBufferContents::ZeroInitial
ize, ArrayBufferContents::CrashIfOutOfMemory_DEPRECATED); |
| 110 } |
| 111 |
| 112 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull(ArrayBuffer* other) |
108 { | 113 { |
109 // TODO(binji): support creating a SharedArrayBuffer by copying another Arra
yBuffer? | 114 // TODO(binji): support creating a SharedArrayBuffer by copying another Arra
yBuffer? |
110 ASSERT(!other->isShared()); | 115 ASSERT(!other->isShared()); |
111 return ArrayBuffer::create(other->data(), other->byteLength()); | 116 return ArrayBuffer::createOrNull(other->data(), other->byteLength()); |
112 } | 117 } |
113 | 118 |
114 PassRefPtr<ArrayBuffer> ArrayBuffer::create(const void* source, unsigned byteLen
gth) | 119 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull(const void* source, unsigned b
yteLength) |
115 { | 120 { |
116 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::NotShared,
ArrayBufferContents::ZeroInitialize); | 121 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::NotShared,
ArrayBufferContents::ZeroInitialize, ArrayBufferContents::NullDataIfOutOfMemory)
; |
117 RELEASE_ASSERT(contents.data()); | 122 if (!contents.data()) |
| 123 return nullptr; |
| 124 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); |
| 125 memcpy(buffer->data(), source, byteLength); |
| 126 return buffer.release(); |
| 127 } |
| 128 |
| 129 PassRefPtr<ArrayBuffer> ArrayBuffer::deprecatedCreateOrCrash(const void* source,
unsigned byteLength) |
| 130 { |
| 131 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::NotShared,
ArrayBufferContents::ZeroInitialize, ArrayBufferContents::CrashIfOutOfMemory_DEP
RECATED); |
| 132 ASSERT(contents.data()); |
118 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); | 133 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); |
119 memcpy(buffer->data(), source, byteLength); | 134 memcpy(buffer->data(), source, byteLength); |
120 return buffer.release(); | 135 return buffer.release(); |
121 } | 136 } |
122 | 137 |
123 PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBufferContents& contents) | 138 PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBufferContents& contents) |
124 { | 139 { |
125 RELEASE_ASSERT(contents.data()); | 140 RELEASE_ASSERT(contents.data()); |
126 return adoptRef(new ArrayBuffer(contents)); | 141 return adoptRef(new ArrayBuffer(contents)); |
127 } | 142 } |
128 | 143 |
129 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull(unsigned numElements, unsigned
elementByteSize) | 144 PassRefPtr<ArrayBuffer> ArrayBuffer::createUninitializedOrNull(unsigned numEleme
nts, unsigned elementByteSize) |
130 { | 145 { |
131 return createOrNull(numElements, elementByteSize, ArrayBufferContents::ZeroI
nitialize); | 146 return create(numElements, elementByteSize, ArrayBufferContents::DontInitial
ize, ArrayBufferContents::NullDataIfOutOfMemory); |
132 } | 147 } |
133 | 148 |
134 PassRefPtr<ArrayBuffer> ArrayBuffer::createUninitialized(unsigned numElements, u
nsigned elementByteSize) | 149 PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned eleme
ntByteSize, ArrayBufferContents::InitializationPolicy initPolicy, ArrayBufferCon
tents::OutOfMemoryPolicy oomPolicy) |
135 { | 150 { |
136 return create(numElements, elementByteSize, ArrayBufferContents::DontInitial
ize); | 151 ArrayBufferContents contents(numElements, elementByteSize, ArrayBufferConten
ts::NotShared, initPolicy, oomPolicy); |
137 } | |
138 | |
139 PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, unsigned eleme
ntByteSize, ArrayBufferContents::InitializationPolicy policy) | |
140 { | |
141 ArrayBufferContents contents(numElements, elementByteSize, ArrayBufferConten
ts::NotShared, policy); | |
142 RELEASE_ASSERT(contents.data()); | |
143 return adoptRef(new ArrayBuffer(contents)); | |
144 } | |
145 | |
146 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull(unsigned numElements, unsigned
elementByteSize, ArrayBufferContents::InitializationPolicy policy) | |
147 { | |
148 ArrayBufferContents contents(numElements, elementByteSize, ArrayBufferConten
ts::NotShared, policy); | |
149 if (!contents.data()) | 152 if (!contents.data()) |
150 return nullptr; | 153 return nullptr; |
151 return adoptRef(new ArrayBuffer(contents)); | 154 return adoptRef(new ArrayBuffer(contents)); |
152 } | 155 } |
153 | 156 |
154 PassRefPtr<ArrayBuffer> ArrayBuffer::createShared(unsigned numElements, unsigned
elementByteSize) | 157 PassRefPtr<ArrayBuffer> ArrayBuffer::createSharedOrNull(unsigned numElements, un
signed elementByteSize) |
155 { | 158 { |
156 return createShared(numElements, elementByteSize, ArrayBufferContents::ZeroI
nitialize); | 159 return createSharedOrNull(numElements, elementByteSize, ArrayBufferContents:
:ZeroInitialize); |
157 } | 160 } |
158 | 161 |
159 PassRefPtr<ArrayBuffer> ArrayBuffer::createShared(const void* source, unsigned b
yteLength) | 162 PassRefPtr<ArrayBuffer> ArrayBuffer::createSharedOrNull(const void* source, unsi
gned byteLength) |
160 { | 163 { |
161 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::Shared, Arr
ayBufferContents::ZeroInitialize); | 164 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::Shared, Arr
ayBufferContents::ZeroInitialize, ArrayBufferContents::NullDataIfOutOfMemory); |
162 RELEASE_ASSERT(contents.data()); | 165 if (!contents.data()) |
| 166 return nullptr; |
163 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); | 167 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); |
164 memcpy(buffer->data(), source, byteLength); | 168 memcpy(buffer->data(), source, byteLength); |
165 return buffer.release(); | 169 return buffer.release(); |
166 } | 170 } |
167 | 171 |
168 PassRefPtr<ArrayBuffer> ArrayBuffer::createShared(unsigned numElements, unsigned
elementByteSize, ArrayBufferContents::InitializationPolicy policy) | 172 PassRefPtr<ArrayBuffer> ArrayBuffer::createSharedOrNull(unsigned numElements, un
signed elementByteSize, ArrayBufferContents::InitializationPolicy policy) |
169 { | 173 { |
170 ArrayBufferContents contents(numElements, elementByteSize, ArrayBufferConten
ts::Shared, policy); | 174 ArrayBufferContents contents(numElements, elementByteSize, ArrayBufferConten
ts::Shared, policy, ArrayBufferContents::NullDataIfOutOfMemory); |
171 RELEASE_ASSERT(contents.data()); | 175 if (!contents.data()) |
| 176 return nullptr; |
172 return adoptRef(new ArrayBuffer(contents)); | 177 return adoptRef(new ArrayBuffer(contents)); |
173 } | 178 } |
174 | 179 |
175 ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) | 180 ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) |
176 : m_firstView(0), m_isNeutered(false) | 181 : m_firstView(0), m_isNeutered(false) |
177 { | 182 { |
178 if (contents.isShared()) | 183 if (contents.isShared()) |
179 contents.shareWith(m_contents); | 184 contents.shareWith(m_contents); |
180 else | 185 else |
181 contents.transfer(m_contents); | 186 contents.transfer(m_contents); |
182 } | 187 } |
183 | 188 |
184 void* ArrayBuffer::data() | 189 void* ArrayBuffer::data() |
185 { | 190 { |
186 return m_contents.data(); | 191 return m_contents.data(); |
187 } | 192 } |
188 | 193 |
189 const void* ArrayBuffer::data() const | 194 const void* ArrayBuffer::data() const |
190 { | 195 { |
191 return m_contents.data(); | 196 return m_contents.data(); |
192 } | 197 } |
193 | 198 |
194 unsigned ArrayBuffer::byteLength() const | 199 unsigned ArrayBuffer::byteLength() const |
195 { | 200 { |
196 return m_contents.sizeInBytes(); | 201 return m_contents.sizeInBytes(); |
197 } | 202 } |
198 | 203 |
199 PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin, int end) const | 204 PassRefPtr<ArrayBuffer> ArrayBuffer::sliceOrNull(int begin, int end) const |
200 { | 205 { |
201 return sliceImpl(clampIndex(begin), clampIndex(end)); | 206 return sliceOrNullImpl(clampIndex(begin), clampIndex(end)); |
202 } | 207 } |
203 | 208 |
204 PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin) const | 209 PassRefPtr<ArrayBuffer> ArrayBuffer::sliceOrNull(int begin) const |
205 { | 210 { |
206 return sliceImpl(clampIndex(begin), byteLength()); | 211 return sliceOrNullImpl(clampIndex(begin), byteLength()); |
207 } | 212 } |
208 | 213 |
209 PassRefPtr<ArrayBuffer> ArrayBuffer::sliceImpl(unsigned begin, unsigned end) con
st | 214 PassRefPtr<ArrayBuffer> ArrayBuffer::sliceOrNullImpl(unsigned begin, unsigned en
d) const |
210 { | 215 { |
211 unsigned size = begin <= end ? end - begin : 0; | 216 unsigned size = begin <= end ? end - begin : 0; |
212 return ArrayBuffer::create(static_cast<const char*>(data()) + begin, size); | 217 return ArrayBuffer::createOrNull(static_cast<const char*>(data()) + begin, s
ize); |
213 } | 218 } |
214 | 219 |
215 unsigned ArrayBuffer::clampIndex(int index) const | 220 unsigned ArrayBuffer::clampIndex(int index) const |
216 { | 221 { |
217 unsigned currentLength = byteLength(); | 222 unsigned currentLength = byteLength(); |
218 if (index < 0) | 223 if (index < 0) |
219 index = currentLength + index; | 224 index = currentLength + index; |
220 return clampValue(index, 0, currentLength); | 225 return clampValue(index, 0, currentLength); |
221 } | 226 } |
222 | 227 |
223 } // namespace WTF | 228 } // namespace WTF |
224 | 229 |
225 using WTF::ArrayBuffer; | 230 using WTF::ArrayBuffer; |
226 | 231 |
227 #endif // ArrayBuffer_h | 232 #endif // ArrayBuffer_h |
OLD | NEW |