1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | #ifndef NAN_TYPEDARRAY_CONTENTS_H_
|
10 | #define NAN_TYPEDARRAY_CONTENTS_H_
|
11 |
|
12 | template<typename T>
|
13 | class TypedArrayContents {
|
14 | public:
|
15 | inline explicit TypedArrayContents(v8::Local<v8::Value> from) :
|
16 | length_(0), data_(NULL) {
|
17 | HandleScope scope;
|
18 |
|
19 | size_t length = 0;
|
20 | void* data = NULL;
|
21 |
|
22 | #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
|
23 | (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
|
24 |
|
25 | if (from->IsArrayBufferView()) {
|
26 | v8::Local<v8::ArrayBufferView> array =
|
27 | v8::Local<v8::ArrayBufferView>::Cast(from);
|
28 |
|
29 | const size_t byte_length = array->ByteLength();
|
30 | const ptrdiff_t byte_offset = array->ByteOffset();
|
31 | v8::Local<v8::ArrayBuffer> buffer = array->Buffer();
|
32 |
|
33 | length = byte_length / sizeof(T);
|
34 |
|
35 |
|
36 | #if (V8_MAJOR_VERSION >= 8)
|
37 | data = static_cast<char*>(buffer->GetBackingStore()->Data()) + byte_offset;
|
38 | #else
|
39 | data = static_cast<char*>(buffer->GetContents().Data()) + byte_offset;
|
40 | #endif
|
41 | }
|
42 |
|
43 | #else
|
44 |
|
45 | if (from->IsObject() && !from->IsNull()) {
|
46 | v8::Local<v8::Object> array = v8::Local<v8::Object>::Cast(from);
|
47 |
|
48 | MaybeLocal<v8::Value> buffer = Get(array,
|
49 | New<v8::String>("buffer").ToLocalChecked());
|
50 | MaybeLocal<v8::Value> byte_length = Get(array,
|
51 | New<v8::String>("byteLength").ToLocalChecked());
|
52 | MaybeLocal<v8::Value> byte_offset = Get(array,
|
53 | New<v8::String>("byteOffset").ToLocalChecked());
|
54 |
|
55 | if (!buffer.IsEmpty() &&
|
56 | !byte_length.IsEmpty() && byte_length.ToLocalChecked()->IsUint32() &&
|
57 | !byte_offset.IsEmpty() && byte_offset.ToLocalChecked()->IsUint32()) {
|
58 | data = array->GetIndexedPropertiesExternalArrayData();
|
59 | if(data) {
|
60 | length = byte_length.ToLocalChecked()->Uint32Value() / sizeof(T);
|
61 | }
|
62 | }
|
63 | }
|
64 |
|
65 | #endif
|
66 |
|
67 | #if defined(_MSC_VER) && _MSC_VER >= 1900 || __cplusplus >= 201103L
|
68 | assert(reinterpret_cast<uintptr_t>(data) % alignof (T) == 0);
|
69 | #elif defined(_MSC_VER) && _MSC_VER >= 1600 || defined(__GNUC__)
|
70 | assert(reinterpret_cast<uintptr_t>(data) % __alignof(T) == 0);
|
71 | #else
|
72 | assert(reinterpret_cast<uintptr_t>(data) % sizeof (T) == 0);
|
73 | #endif
|
74 |
|
75 | length_ = length;
|
76 | data_ = static_cast<T*>(data);
|
77 | }
|
78 |
|
79 | inline size_t length() const { return length_; }
|
80 | inline T* operator*() { return data_; }
|
81 | inline const T* operator*() const { return data_; }
|
82 |
|
83 | private:
|
84 | NAN_DISALLOW_ASSIGN_COPY_MOVE(TypedArrayContents)
|
85 |
|
86 |
|
87 | void *operator new(size_t size);
|
88 | void operator delete(void *, size_t) {
|
89 | abort();
|
90 | }
|
91 |
|
92 | size_t length_;
|
93 | T* data_;
|
94 | };
|
95 |
|
96 | #endif
|