msgpack-lite icon indicating copy to clipboard operation
msgpack-lite copied to clipboard

Codec option to encode Uint8Array like ArrayBuffer

Open dbrgn opened this issue 7 years ago • 3 comments

Currently, with the binarybuffer option, ArrayBuffer instances are converted to bin bytes.

>>> msgpack.encode(Uint8Array.of(1,2,3,4).buffer, { codec: msgpack.createCodec({ binarraybuffer: true }) })
Uint8Array [ 196, 4, 1, 2, 3, 4 ]

However, when passing an Uint8Array directly, it gets converted to a map (or to an extension type when turning on the preset):

>>> msgpack.encode(Uint8Array.of(1,2,3,4), { codec: msgpack.createCodec({ binarraybuffer: true }) })
Uint8Array [ 132, 161, 48, 1, 161, 49, 2, 161, 50, 3, … ]

Could you maybe add an option to treat an UInt8Array like an ArrayBuffer when encoding?

dbrgn avatar May 17 '18 10:05 dbrgn

Advanage of properly handling Uint8Array as bin type: When you have a Uint8Array which is a view into an ArrayBuffer, then you cannot simply pass u8a.buffer to msgpack, since then the byteOffset and byteLength will be lost. The only way to properly encode the data is to copy it into a new ArrayBuffer like so:

const start = decryptedBytes.byteOffset;
const end = start + decryptedBytes.byteLength;
return decryptedBytes.buffer.slice(start, end);

This copying is unnecessary. It would be better if a Uint8Array (which is a view into a buffer) could be serialized directly.

dbrgn avatar Jul 23 '18 13:07 dbrgn

In addition, the decoding function could hand out a view into the original buffer which will also be much more efficient.

lgrahl avatar Jul 23 '18 13:07 lgrahl

I'd be in favor of Uint8Array, ArrayBuffer and Buffer being encoded to 'bin', but bin decoded to Uint8Array by default. that would likely need a major version bump, but it would mean not needing Buffer in the browser. node's Buffer is an Uint8Array under the hood anyway I believe.

MeirionHughes avatar Jan 08 '19 16:01 MeirionHughes