lib: enable TypedArray and DataView for the v8 module
This commit allow passing `TypedArray` and `DataView` to: - v8.deserialize() - new v8.Deserializer() - v8.serializer.writeRawBytes() PR-URL: https://github.com/nodejs/node/pull/23953 Refs: https://github.com/nodejs/node/issues/1826 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
parent
8bd6df8927
commit
56881b0d95
@ -185,7 +185,7 @@ Uses a [`DefaultSerializer`][] to serialize `value` into a buffer.
|
|||||||
added: v8.0.0
|
added: v8.0.0
|
||||||
-->
|
-->
|
||||||
|
|
||||||
* `buffer` {Buffer|Uint8Array} A buffer returned by [`serialize()`][].
|
* `buffer` {Buffer|TypedArray|DataView} A buffer returned by [`serialize()`][].
|
||||||
|
|
||||||
Uses a [`DefaultDeserializer`][] with default options to read a JS value
|
Uses a [`DefaultDeserializer`][] with default options to read a JS value
|
||||||
from a buffer.
|
from a buffer.
|
||||||
@ -252,7 +252,7 @@ For use inside of a custom [`serializer._writeHostObject()`][].
|
|||||||
|
|
||||||
#### serializer.writeRawBytes(buffer)
|
#### serializer.writeRawBytes(buffer)
|
||||||
|
|
||||||
* `buffer` {Buffer|Uint8Array}
|
* `buffer` {Buffer|TypedArray|DataView}
|
||||||
|
|
||||||
Write raw bytes into the serializer’s internal buffer. The deserializer
|
Write raw bytes into the serializer’s internal buffer. The deserializer
|
||||||
will require a way to compute the length of the buffer.
|
will require a way to compute the length of the buffer.
|
||||||
@ -308,7 +308,7 @@ added: v8.0.0
|
|||||||
|
|
||||||
#### new Deserializer(buffer)
|
#### new Deserializer(buffer)
|
||||||
|
|
||||||
* `buffer` {Buffer|Uint8Array} A buffer returned by
|
* `buffer` {Buffer|TypedArray|DataView} A buffer returned by
|
||||||
[`serializer.releaseBuffer()`][].
|
[`serializer.releaseBuffer()`][].
|
||||||
|
|
||||||
Creates a new `Deserializer` object.
|
Creates a new `Deserializer` object.
|
||||||
|
@ -266,9 +266,9 @@ void SerializerContext::WriteRawBytes(const FunctionCallbackInfo<Value>& args) {
|
|||||||
SerializerContext* ctx;
|
SerializerContext* ctx;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
|
||||||
|
|
||||||
if (!args[0]->IsUint8Array()) {
|
if (!args[0]->IsArrayBufferView()) {
|
||||||
return node::THROW_ERR_INVALID_ARG_TYPE(
|
return node::THROW_ERR_INVALID_ARG_TYPE(
|
||||||
ctx->env(), "source must be a Uint8Array");
|
ctx->env(), "source must be a TypedArray or a DataView");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->serializer_.WriteRawBytes(Buffer::Data(args[0]),
|
ctx->serializer_.WriteRawBytes(Buffer::Data(args[0]),
|
||||||
@ -317,9 +317,9 @@ MaybeLocal<Object> DeserializerContext::ReadHostObject(Isolate* isolate) {
|
|||||||
void DeserializerContext::New(const FunctionCallbackInfo<Value>& args) {
|
void DeserializerContext::New(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
|
||||||
if (!args[0]->IsUint8Array()) {
|
if (!args[0]->IsArrayBufferView()) {
|
||||||
return node::THROW_ERR_INVALID_ARG_TYPE(
|
return node::THROW_ERR_INVALID_ARG_TYPE(
|
||||||
env, "buffer must be a Uint8Array");
|
env, "buffer must be a TypedArray or a DataView");
|
||||||
}
|
}
|
||||||
|
|
||||||
new DeserializerContext(env, args.This(), args[0]);
|
new DeserializerContext(env, args.This(), args[0]);
|
||||||
|
@ -98,6 +98,47 @@ const deserializerTypeError =
|
|||||||
assert.strictEqual(des.readValue().val, hostObject);
|
assert.strictEqual(des.readValue().val, hostObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test ensures that `v8.Serializer.writeRawBytes()` support
|
||||||
|
// `TypedArray` and `DataView`.
|
||||||
|
{
|
||||||
|
const text = 'hostObjectTag';
|
||||||
|
const data = Buffer.from(text);
|
||||||
|
const arrayBufferViews = common.getArrayBufferViews(data);
|
||||||
|
|
||||||
|
// `buf` is one of `TypedArray` or `DataView`.
|
||||||
|
function testWriteRawBytes(buf) {
|
||||||
|
let writeHostObjectCalled = false;
|
||||||
|
const ser = new v8.DefaultSerializer();
|
||||||
|
|
||||||
|
ser._writeHostObject = common.mustCall((object) => {
|
||||||
|
writeHostObjectCalled = true;
|
||||||
|
ser.writeUint32(buf.byteLength);
|
||||||
|
ser.writeRawBytes(buf);
|
||||||
|
});
|
||||||
|
|
||||||
|
ser.writeHeader();
|
||||||
|
ser.writeValue({ val: hostObject });
|
||||||
|
|
||||||
|
const des = new v8.DefaultDeserializer(ser.releaseBuffer());
|
||||||
|
des._readHostObject = common.mustCall(() => {
|
||||||
|
assert.strictEqual(writeHostObjectCalled, true);
|
||||||
|
const length = des.readUint32();
|
||||||
|
const buf = des.readRawBytes(length);
|
||||||
|
assert.strictEqual(buf.toString(), text);
|
||||||
|
|
||||||
|
return hostObject;
|
||||||
|
});
|
||||||
|
|
||||||
|
des.readHeader();
|
||||||
|
|
||||||
|
assert.strictEqual(des.readValue().val, hostObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayBufferViews.forEach((buf) => {
|
||||||
|
testWriteRawBytes(buf);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const ser = new v8.DefaultSerializer();
|
const ser = new v8.DefaultSerializer();
|
||||||
ser._writeHostObject = common.mustCall((object) => {
|
ser._writeHostObject = common.mustCall((object) => {
|
||||||
@ -146,3 +187,46 @@ const deserializerTypeError =
|
|||||||
assert.throws(v8.Serializer, serializerTypeError);
|
assert.throws(v8.Serializer, serializerTypeError);
|
||||||
assert.throws(v8.Deserializer, deserializerTypeError);
|
assert.throws(v8.Deserializer, deserializerTypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// `v8.deserialize()` and `new v8.Deserializer()` should support both
|
||||||
|
// `TypedArray` and `DataView`.
|
||||||
|
{
|
||||||
|
for (const obj of objects) {
|
||||||
|
const buf = v8.serialize(obj);
|
||||||
|
|
||||||
|
for (const arrayBufferView of common.getArrayBufferViews(buf)) {
|
||||||
|
assert.deepStrictEqual(v8.deserialize(arrayBufferView), obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const arrayBufferView of common.getArrayBufferViews(buf)) {
|
||||||
|
const deserializer = new v8.DefaultDeserializer(arrayBufferView);
|
||||||
|
deserializer.readHeader();
|
||||||
|
const value = deserializer.readValue();
|
||||||
|
assert.deepStrictEqual(value, obj);
|
||||||
|
|
||||||
|
const serializer = new v8.DefaultSerializer();
|
||||||
|
serializer.writeHeader();
|
||||||
|
serializer.writeValue(value);
|
||||||
|
assert.deepStrictEqual(buf, serializer.releaseBuffer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const INVALID_SOURCE = 'INVALID_SOURCE_TYPE';
|
||||||
|
const serializer = new v8.Serializer();
|
||||||
|
serializer.writeHeader();
|
||||||
|
assert.throws(
|
||||||
|
() => serializer.writeRawBytes(INVALID_SOURCE),
|
||||||
|
/^TypeError: source must be a TypedArray or a DataView$/,
|
||||||
|
);
|
||||||
|
assert.throws(
|
||||||
|
() => v8.deserialize(INVALID_SOURCE),
|
||||||
|
/^TypeError: buffer must be a TypedArray or a DataView$/,
|
||||||
|
);
|
||||||
|
assert.throws(
|
||||||
|
() => new v8.Deserializer(INVALID_SOURCE),
|
||||||
|
/^TypeError: buffer must be a TypedArray or a DataView$/,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user