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
|
||||
-->
|
||||
|
||||
* `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
|
||||
from a buffer.
|
||||
@ -252,7 +252,7 @@ For use inside of a custom [`serializer._writeHostObject()`][].
|
||||
|
||||
#### serializer.writeRawBytes(buffer)
|
||||
|
||||
* `buffer` {Buffer|Uint8Array}
|
||||
* `buffer` {Buffer|TypedArray|DataView}
|
||||
|
||||
Write raw bytes into the serializer’s internal buffer. The deserializer
|
||||
will require a way to compute the length of the buffer.
|
||||
@ -308,7 +308,7 @@ added: v8.0.0
|
||||
|
||||
#### new Deserializer(buffer)
|
||||
|
||||
* `buffer` {Buffer|Uint8Array} A buffer returned by
|
||||
* `buffer` {Buffer|TypedArray|DataView} A buffer returned by
|
||||
[`serializer.releaseBuffer()`][].
|
||||
|
||||
Creates a new `Deserializer` object.
|
||||
|
@ -266,9 +266,9 @@ void SerializerContext::WriteRawBytes(const FunctionCallbackInfo<Value>& args) {
|
||||
SerializerContext* ctx;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
|
||||
|
||||
if (!args[0]->IsUint8Array()) {
|
||||
if (!args[0]->IsArrayBufferView()) {
|
||||
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]),
|
||||
@ -317,9 +317,9 @@ MaybeLocal<Object> DeserializerContext::ReadHostObject(Isolate* isolate) {
|
||||
void DeserializerContext::New(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
if (!args[0]->IsUint8Array()) {
|
||||
if (!args[0]->IsArrayBufferView()) {
|
||||
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]);
|
||||
|
@ -98,6 +98,47 @@ const deserializerTypeError =
|
||||
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();
|
||||
ser._writeHostObject = common.mustCall((object) => {
|
||||
@ -146,3 +187,46 @@ const deserializerTypeError =
|
||||
assert.throws(v8.Serializer, serializerTypeError);
|
||||
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