OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * | 3 // found in the LICENSE file. |
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 | 4 |
26 #ifndef ArrayBuffer_h | 5 #include "platform/wtf/typed_arrays/ArrayBuffer.h" |
27 #define ArrayBuffer_h | |
28 | 6 |
29 #include "wtf/Assertions.h" | 7 // The contents of this header was moved to platform/wtf as part of |
30 #include "wtf/HashSet.h" | 8 // WTF migration project. See the following post for details: |
31 #include "wtf/PassRefPtr.h" | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
32 #include "wtf/RefCounted.h" | |
33 #include "wtf/WTFExport.h" | |
34 #include "wtf/typed_arrays/ArrayBufferContents.h" | |
35 | |
36 namespace WTF { | |
37 | |
38 class ArrayBuffer; | |
39 class ArrayBufferView; | |
40 | |
41 class WTF_EXPORT ArrayBuffer : public RefCounted<ArrayBuffer> { | |
42 public: | |
43 static inline PassRefPtr<ArrayBuffer> create(unsigned numElements, | |
44 unsigned elementByteSize); | |
45 static inline PassRefPtr<ArrayBuffer> create(ArrayBuffer*); | |
46 static inline PassRefPtr<ArrayBuffer> create(const void* source, | |
47 unsigned byteLength); | |
48 static inline PassRefPtr<ArrayBuffer> create(ArrayBufferContents&); | |
49 | |
50 static inline PassRefPtr<ArrayBuffer> createOrNull(unsigned numElements, | |
51 unsigned elementByteSize); | |
52 | |
53 // Only for use by DOMArrayBuffer::createUninitializedOrNull(). | |
54 static inline PassRefPtr<ArrayBuffer> createUninitializedOrNull( | |
55 unsigned numElements, | |
56 unsigned elementByteSize); | |
57 | |
58 static inline PassRefPtr<ArrayBuffer> createShared(unsigned numElements, | |
59 unsigned elementByteSize); | |
60 static inline PassRefPtr<ArrayBuffer> createShared(const void* source, | |
61 unsigned byteLength); | |
62 | |
63 inline void* data(); | |
64 inline const void* data() const; | |
65 inline void* dataShared(); | |
66 inline const void* dataShared() const; | |
67 inline void* dataMaybeShared(); | |
68 inline const void* dataMaybeShared() const; | |
69 inline unsigned byteLength() const; | |
70 | |
71 // Creates a new ArrayBuffer object with copy of bytes in this object | |
72 // ranging from |begin| upto but not including |end|. | |
73 inline PassRefPtr<ArrayBuffer> slice(int begin, int end) const; | |
74 inline PassRefPtr<ArrayBuffer> slice(int begin) const; | |
75 | |
76 void addView(ArrayBufferView*); | |
77 void removeView(ArrayBufferView*); | |
78 | |
79 bool transfer(ArrayBufferContents&); | |
80 bool shareContentsWith(ArrayBufferContents&); | |
81 bool isNeutered() const { return m_isNeutered; } | |
82 bool isShared() const { return m_contents.isShared(); } | |
83 | |
84 ~ArrayBuffer() {} | |
85 | |
86 protected: | |
87 inline explicit ArrayBuffer(ArrayBufferContents&); | |
88 | |
89 private: | |
90 static inline PassRefPtr<ArrayBuffer> create( | |
91 unsigned numElements, | |
92 unsigned elementByteSize, | |
93 ArrayBufferContents::InitializationPolicy); | |
94 static inline PassRefPtr<ArrayBuffer> createOrNull( | |
95 unsigned numElements, | |
96 unsigned elementByteSize, | |
97 ArrayBufferContents::InitializationPolicy); | |
98 static inline PassRefPtr<ArrayBuffer> createShared( | |
99 unsigned numElements, | |
100 unsigned elementByteSize, | |
101 ArrayBufferContents::InitializationPolicy); | |
102 | |
103 inline PassRefPtr<ArrayBuffer> sliceImpl(unsigned begin, unsigned end) const; | |
104 inline unsigned clampIndex(int index) const; | |
105 static inline int clampValue(int x, int left, int right); | |
106 | |
107 ArrayBufferContents m_contents; | |
108 ArrayBufferView* m_firstView; | |
109 bool m_isNeutered; | |
110 }; | |
111 | |
112 int ArrayBuffer::clampValue(int x, int left, int right) { | |
113 DCHECK_LE(left, right); | |
114 if (x < left) | |
115 x = left; | |
116 if (right < x) | |
117 x = right; | |
118 return x; | |
119 } | |
120 | |
121 PassRefPtr<ArrayBuffer> ArrayBuffer::create(unsigned numElements, | |
122 unsigned elementByteSize) { | |
123 return create(numElements, elementByteSize, | |
124 ArrayBufferContents::ZeroInitialize); | |
125 } | |
126 | |
127 PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBuffer* other) { | |
128 // TODO(binji): support creating a SharedArrayBuffer by copying another | |
129 // ArrayBuffer? | |
130 DCHECK(!other->isShared()); | |
131 return ArrayBuffer::create(other->data(), other->byteLength()); | |
132 } | |
133 | |
134 PassRefPtr<ArrayBuffer> ArrayBuffer::create(const void* source, | |
135 unsigned byteLength) { | |
136 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::NotShared, | |
137 ArrayBufferContents::DontInitialize); | |
138 if (UNLIKELY(!contents.data())) | |
139 OOM_CRASH(); | |
140 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); | |
141 memcpy(buffer->data(), source, byteLength); | |
142 return buffer.release(); | |
143 } | |
144 | |
145 PassRefPtr<ArrayBuffer> ArrayBuffer::create(ArrayBufferContents& contents) { | |
146 RELEASE_ASSERT(contents.dataMaybeShared()); | |
147 return adoptRef(new ArrayBuffer(contents)); | |
148 } | |
149 | |
150 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull(unsigned numElements, | |
151 unsigned elementByteSize) { | |
152 return createOrNull(numElements, elementByteSize, | |
153 ArrayBufferContents::ZeroInitialize); | |
154 } | |
155 | |
156 PassRefPtr<ArrayBuffer> ArrayBuffer::createUninitializedOrNull( | |
157 unsigned numElements, | |
158 unsigned elementByteSize) { | |
159 return createOrNull(numElements, elementByteSize, | |
160 ArrayBufferContents::DontInitialize); | |
161 } | |
162 | |
163 PassRefPtr<ArrayBuffer> ArrayBuffer::create( | |
164 unsigned numElements, | |
165 unsigned elementByteSize, | |
166 ArrayBufferContents::InitializationPolicy policy) { | |
167 ArrayBufferContents contents(numElements, elementByteSize, | |
168 ArrayBufferContents::NotShared, policy); | |
169 RELEASE_ASSERT(contents.data()); | |
170 return adoptRef(new ArrayBuffer(contents)); | |
171 } | |
172 | |
173 PassRefPtr<ArrayBuffer> ArrayBuffer::createOrNull( | |
174 unsigned numElements, | |
175 unsigned elementByteSize, | |
176 ArrayBufferContents::InitializationPolicy policy) { | |
177 ArrayBufferContents contents(numElements, elementByteSize, | |
178 ArrayBufferContents::NotShared, policy); | |
179 if (!contents.data()) | |
180 return nullptr; | |
181 return adoptRef(new ArrayBuffer(contents)); | |
182 } | |
183 | |
184 PassRefPtr<ArrayBuffer> ArrayBuffer::createShared(unsigned numElements, | |
185 unsigned elementByteSize) { | |
186 return createShared(numElements, elementByteSize, | |
187 ArrayBufferContents::ZeroInitialize); | |
188 } | |
189 | |
190 PassRefPtr<ArrayBuffer> ArrayBuffer::createShared(const void* source, | |
191 unsigned byteLength) { | |
192 ArrayBufferContents contents(byteLength, 1, ArrayBufferContents::Shared, | |
193 ArrayBufferContents::DontInitialize); | |
194 RELEASE_ASSERT(contents.dataShared()); | |
195 RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents)); | |
196 memcpy(buffer->dataShared(), source, byteLength); | |
197 return buffer.release(); | |
198 } | |
199 | |
200 PassRefPtr<ArrayBuffer> ArrayBuffer::createShared( | |
201 unsigned numElements, | |
202 unsigned elementByteSize, | |
203 ArrayBufferContents::InitializationPolicy policy) { | |
204 ArrayBufferContents contents(numElements, elementByteSize, | |
205 ArrayBufferContents::Shared, policy); | |
206 RELEASE_ASSERT(contents.dataShared()); | |
207 return adoptRef(new ArrayBuffer(contents)); | |
208 } | |
209 | |
210 ArrayBuffer::ArrayBuffer(ArrayBufferContents& contents) | |
211 : m_firstView(0), m_isNeutered(false) { | |
212 if (contents.isShared()) | |
213 contents.shareWith(m_contents); | |
214 else | |
215 contents.transfer(m_contents); | |
216 } | |
217 | |
218 void* ArrayBuffer::data() { | |
219 return m_contents.data(); | |
220 } | |
221 | |
222 const void* ArrayBuffer::data() const { | |
223 return m_contents.data(); | |
224 } | |
225 | |
226 void* ArrayBuffer::dataShared() { | |
227 return m_contents.dataShared(); | |
228 } | |
229 | |
230 const void* ArrayBuffer::dataShared() const { | |
231 return m_contents.dataShared(); | |
232 } | |
233 | |
234 void* ArrayBuffer::dataMaybeShared() { | |
235 return m_contents.dataMaybeShared(); | |
236 } | |
237 | |
238 const void* ArrayBuffer::dataMaybeShared() const { | |
239 return m_contents.dataMaybeShared(); | |
240 } | |
241 | |
242 unsigned ArrayBuffer::byteLength() const { | |
243 return m_contents.sizeInBytes(); | |
244 } | |
245 | |
246 PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin, int end) const { | |
247 return sliceImpl(clampIndex(begin), clampIndex(end)); | |
248 } | |
249 | |
250 PassRefPtr<ArrayBuffer> ArrayBuffer::slice(int begin) const { | |
251 return sliceImpl(clampIndex(begin), byteLength()); | |
252 } | |
253 | |
254 PassRefPtr<ArrayBuffer> ArrayBuffer::sliceImpl(unsigned begin, | |
255 unsigned end) const { | |
256 unsigned size = begin <= end ? end - begin : 0; | |
257 return ArrayBuffer::create(static_cast<const char*>(data()) + begin, size); | |
258 } | |
259 | |
260 unsigned ArrayBuffer::clampIndex(int index) const { | |
261 unsigned currentLength = byteLength(); | |
262 if (index < 0) | |
263 index = currentLength + index; | |
264 return clampValue(index, 0, currentLength); | |
265 } | |
266 | |
267 } // namespace WTF | |
268 | |
269 using WTF::ArrayBuffer; | |
270 | |
271 #endif // ArrayBuffer_h | |
OLD | NEW |