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 | data = static_cast<char*>(buffer->GetContents().Data()) + byte_offset;
|
35 | }
|
36 |
|
37 | #else
|
38 |
|
39 | if (from->IsObject() && !from->IsNull()) {
|
40 | v8::Local<v8::Object> array = v8::Local<v8::Object>::Cast(from);
|
41 |
|
42 | MaybeLocal<v8::Value> buffer = Get(array,
|
43 | New<v8::String>("buffer").ToLocalChecked());
|
44 | MaybeLocal<v8::Value> byte_length = Get(array,
|
45 | New<v8::String>("byteLength").ToLocalChecked());
|
46 | MaybeLocal<v8::Value> byte_offset = Get(array,
|
47 | New<v8::String>("byteOffset").ToLocalChecked());
|
48 |
|
49 | if (!buffer.IsEmpty() &&
|
50 | !byte_length.IsEmpty() && byte_length.ToLocalChecked()->IsUint32() &&
|
51 | !byte_offset.IsEmpty() && byte_offset.ToLocalChecked()->IsUint32()) {
|
52 | data = array->GetIndexedPropertiesExternalArrayData();
|
53 | if(data) {
|
54 | length = byte_length.ToLocalChecked()->Uint32Value() / sizeof(T);
|
55 | }
|
56 | }
|
57 | }
|
58 |
|
59 | #endif
|
60 |
|
61 | #if defined(_MSC_VER) && _MSC_VER >= 1900 || __cplusplus >= 201103L
|
62 | assert(reinterpret_cast<uintptr_t>(data) % alignof (T) == 0);
|
63 | #elif defined(_MSC_VER) && _MSC_VER >= 1600 || defined(__GNUC__)
|
64 | assert(reinterpret_cast<uintptr_t>(data) % __alignof(T) == 0);
|
65 | #else
|
66 | assert(reinterpret_cast<uintptr_t>(data) % sizeof (T) == 0);
|
67 | #endif
|
68 |
|
69 | length_ = length;
|
70 | data_ = static_cast<T*>(data);
|
71 | }
|
72 |
|
73 | inline size_t length() const { return length_; }
|
74 | inline T* operator*() { return data_; }
|
75 | inline const T* operator*() const { return data_; }
|
76 |
|
77 | private:
|
78 | NAN_DISALLOW_ASSIGN_COPY_MOVE(TypedArrayContents)
|
79 |
|
80 |
|
81 | void *operator new(size_t size);
|
82 | void operator delete(void *, size_t) {
|
83 | abort();
|
84 | }
|
85 |
|
86 | size_t length_;
|
87 | T* data_;
|
88 | };
|
89 |
|
90 | #endif
|