-
Notifications
You must be signed in to change notification settings - Fork 499
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added helper class for accessing contents of typedarrays
move typedarray contents to v8 misc helper docs fix style errors, use const and more descriptive types more style tweaks style tweaks, assert on alignment and missing typedarrays remove alignof, do not assert fail on versions < 0.8 add better alignment checks for msc, g++ and c++11 fix up signature use __cplusplus for checking if alignof available, unify msc and gnuc fallbacks, defer assigning to data_ until after assertion add failing test case for node 0.12 access buffer property from arraybufferview before reading in order to force v8 to externalize it change docs to force CI to rerun remove unneeded type qualifiers which trigger spurious warnings on gcc
- Loading branch information
1 parent
9bf9b8b
commit 17b5129
Showing
7 changed files
with
258 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/********************************************************************* | ||
* NAN - Native Abstractions for Node.js | ||
* | ||
* Copyright (c) 2015 NAN contributors | ||
* | ||
* MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md> | ||
********************************************************************/ | ||
|
||
#ifndef NAN_TYPEDARRAY_CONTENTS_H_ | ||
#define NAN_TYPEDARRAY_CONTENTS_H_ | ||
|
||
template<typename T> | ||
class TypedArrayContents { | ||
public: | ||
NAN_INLINE explicit TypedArrayContents(v8::Local<v8::Value> from) : | ||
length_(0), data_(NULL) { | ||
|
||
size_t length = 0; | ||
void* data = NULL; | ||
|
||
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \ | ||
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3)) | ||
|
||
if (from->IsArrayBufferView()) { | ||
v8::Local<v8::ArrayBufferView> array = | ||
v8::Local<v8::ArrayBufferView>::Cast(from); | ||
|
||
const size_t byte_length = array->ByteLength(); | ||
const ptrdiff_t byte_offset = array->ByteOffset(); | ||
v8::Local<v8::ArrayBuffer> buffer = array->Buffer(); | ||
|
||
length = byte_length / sizeof(T); | ||
data = static_cast<char*>(buffer->GetContents().Data()) + byte_offset; | ||
} | ||
|
||
#else | ||
|
||
if (from->IsObject() && !from->IsNull()) { | ||
v8::Local<v8::Object> array = v8::Local<v8::Object>::Cast(from); | ||
|
||
MaybeLocal<v8::Value> buffer = Get(array, | ||
New<v8::String>("buffer").ToLocalChecked()); | ||
MaybeLocal<v8::Value> byte_length = Get(array, | ||
New<v8::String>("byteLength").ToLocalChecked()); | ||
MaybeLocal<v8::Value> byte_offset = Get(array, | ||
New<v8::String>("byteOffset").ToLocalChecked()); | ||
|
||
if (!buffer.IsEmpty() && | ||
!byte_length.IsEmpty() && byte_length.ToLocalChecked()->IsUint32() && | ||
!byte_offset.IsEmpty() && byte_offset.ToLocalChecked()->IsUint32()) { | ||
data = array->GetIndexedPropertiesExternalArrayData(); | ||
if(data) { | ||
length = byte_length.ToLocalChecked()->Uint32Value() / sizeof(T); | ||
} | ||
} | ||
} | ||
|
||
#endif | ||
|
||
#if defined(_MSC_VER) || defined(__GNUC__) | ||
assert(reinterpret_cast<uintptr_t>(data) % __alignof(T) == 0); | ||
#elif __cplusplus >= 201103L | ||
assert(reinterpret_cast<uintptr_t>(data) % alignof(T) == 0); | ||
#else | ||
assert(reinterpret_cast<uintptr_t>(data) % sizeof(T) == 0); | ||
#endif | ||
|
||
length_ = length; | ||
data_ = static_cast<T*>(data); | ||
} | ||
|
||
NAN_INLINE size_t length() const { return length_; } | ||
NAN_INLINE T* operator*() { return data_; } | ||
NAN_INLINE const T* operator*() const { return data_; } | ||
|
||
private: | ||
NAN_DISALLOW_ASSIGN_COPY_MOVE(TypedArrayContents) | ||
|
||
//Disable heap allocation | ||
void *operator new(size_t size); | ||
void operator delete(void *, size_t); | ||
|
||
size_t length_; | ||
T* data_; | ||
}; | ||
|
||
#endif // NAN_TYPEDARRAY_CONTENTS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/********************************************************************* | ||
* NAN - Native Abstractions for Node.js | ||
* | ||
* Copyright (c) 2015 NAN contributors | ||
* | ||
* MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md> | ||
********************************************************************/ | ||
|
||
#include <nan.h> | ||
|
||
#include <stdint.h> | ||
|
||
using namespace Nan; // NOLINT(build/namespaces) | ||
|
||
NAN_METHOD(ReadU8) { | ||
TypedArrayContents<uint8_t> data(info[0]); | ||
|
||
v8::Local<v8::Array> result = New<v8::Array>(data.length()); | ||
for (size_t i=0; i<data.length(); i++) { | ||
Set(result, i, New<v8::Number>((*data)[i])); | ||
} | ||
|
||
info.GetReturnValue().Set(result); | ||
} | ||
|
||
NAN_METHOD(ReadI32) { | ||
TypedArrayContents<int32_t> data(info[0]); | ||
|
||
v8::Local<v8::Array> result = New<v8::Array>(data.length()); | ||
for (size_t i=0; i<data.length(); i++) { | ||
Set(result, i, New<v8::Number>((*data)[i])); | ||
} | ||
|
||
info.GetReturnValue().Set(result); | ||
} | ||
|
||
NAN_METHOD(ReadFloat) { | ||
TypedArrayContents<float> data(info[0]); | ||
|
||
v8::Local<v8::Array> result = New<v8::Array>(data.length());\ | ||
for (size_t i=0; i<data.length(); i++) { | ||
Set(result, i, New<v8::Number>((*data)[i])); | ||
} | ||
|
||
info.GetReturnValue().Set(result); | ||
} | ||
|
||
NAN_METHOD(ReadDouble) { | ||
TypedArrayContents<double> data(info[0]); | ||
|
||
v8::Local<v8::Array> result = New<v8::Array>(data.length()); | ||
for (size_t i=0; i<data.length(); i++) { | ||
Set(result, i, New<v8::Number>((*data)[i])); | ||
} | ||
|
||
info.GetReturnValue().Set(result); | ||
} | ||
|
||
NAN_MODULE_INIT(Init) { | ||
NAN_EXPORT(target, ReadU8); | ||
NAN_EXPORT(target, ReadI32); | ||
NAN_EXPORT(target, ReadFloat); | ||
NAN_EXPORT(target, ReadDouble); | ||
} | ||
|
||
NODE_MODULE(typedarrays, Init) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
const test = require('tap').test | ||
, testRoot = require('path').resolve(__dirname, '..') | ||
, bindings = require('bindings')({ module_root: testRoot, bindings: 'typedarrays' }); | ||
|
||
test('typedarrays - simple cases', function (t) { | ||
if (typeof Uint8Array !== 'function') { | ||
|
||
t.pass('typedarrays not supported'); | ||
t.end(); | ||
|
||
} else { | ||
|
||
var zeros = new Uint8Array(5) | ||
t.same(bindings.ReadU8(zeros), [0,0,0,0,0]) | ||
|
||
var y = zeros[0] | ||
t.equals(y, 0) | ||
t.same(bindings.ReadU8(zeros), [0,0,0,0,0]) | ||
|
||
var u8array = new Uint8Array([1, 255, 3]); | ||
t.same(bindings.ReadU8(u8array), [1, 255, 3]); | ||
t.same(bindings.ReadU8(u8array.subarray(1)), [255, 3]); | ||
t.same(bindings.ReadU8(u8array.subarray(0, 2)), [1, 255]); | ||
t.same(bindings.ReadU8(u8array.subarray(1, 2)), [255]); | ||
|
||
t.same(bindings.ReadU8(new Uint8Array(u8array)), [1, 255, 3]); | ||
t.same(bindings.ReadU8(new Uint8Array(u8array.subarray(1))), [255, 3]); | ||
t.same(bindings.ReadU8(new Uint8Array(u8array.subarray(0, 2))), [1, 255]); | ||
t.same(bindings.ReadU8(new Uint8Array(u8array.subarray(1, 2))), [255]); | ||
|
||
t.same(bindings.ReadU8((new Uint8Array(u8array.buffer)).subarray(1)), [255, 3]); | ||
|
||
|
||
var i32array = new Int32Array([0, 1, -1, 1073741824, -1073741824]); | ||
t.same(bindings.ReadI32(i32array), [0, 1, -1, 1073741824, -1073741824]); | ||
|
||
var f32array = new Float32Array([1, -1, Infinity, -Infinity, 0, +0, -0]); | ||
t.same(bindings.ReadFloat(f32array), [1, -1, Infinity, -Infinity, 0, +0, -0]); | ||
t.same(bindings.ReadFloat(f32array.subarray(1)), [-1, Infinity, -Infinity, 0, +0, -0]); | ||
t.same(bindings.ReadFloat(f32array.subarray(0,4)), [1, -1, Infinity, -Infinity]); | ||
t.same(bindings.ReadFloat(f32array.subarray(1,3)), [-1, Infinity]); | ||
|
||
t.end(); | ||
} | ||
}); | ||
|
||
test('typedarrays - bad arguments', function (t) { | ||
if (typeof Uint8Array !== 'function') { | ||
|
||
t.pass('typedarrays not supported'); | ||
t.end(); | ||
|
||
} else { | ||
|
||
t.same(bindings.ReadU8(0), []); | ||
t.same(bindings.ReadU8(1), []); | ||
t.same(bindings.ReadU8(null), []); | ||
t.same(bindings.ReadU8(), []); | ||
t.same(bindings.ReadU8('foobar'), []); | ||
t.same(bindings.ReadU8([]), []); | ||
t.same(bindings.ReadU8([1,2]), []); | ||
t.same(bindings.ReadU8({}), []); | ||
t.same(bindings.ReadU8(Uint8Array), []); | ||
t.same(bindings.ReadU8(new Float32Array(0)), []); | ||
|
||
t.same(bindings.ReadU8({ | ||
byteLength: 10000000, | ||
byteOffset: 100000, | ||
buffer: null | ||
}), []) | ||
|
||
t.end(); | ||
} | ||
}); |