JohnWeisz/TypedJSON

Serializing odd-length ArrayBuffer fails

Opened this issue · 0 comments

Serializing objects containing ArrayBuffer properties works only if the ArrayBuffer is of even length.

In case of odd length, the following error is thrown:
RangeError: byte length of Uint16Array should be a multiple of 2

The cause is quite evident when looking at the serializer code, as it uses Uint16Arrays under the hood:

function convertAsArrayBuffer(buffer: ArrayBuffer) {
    // ArrayBuffer -> 16-bit character codes -> character array -> joined string.
    return Array.from(new Uint16Array(buffer))
        .map(charCode => String.fromCharCode(charCode)).join('');
}

I'm not sure what would be the best change to make this work for odd lengths as well; so far my ideas would be

  1. Serializing to bas64 instead of a sequence of UTF16 characters
  2. Padding the ArrayBuffer with a zero (creating a new Uint8Array and copying the old one over) and then serializing to { data: string, padded: boolean }
  3. Splitting off the last byte of an odd-length ArrayBuffer and treating it separately:
    • Treat the main portion using the current approach
    • Treat the last byte as number (0-255) or undefined (for even-length ArrayBuffer)
    • Serialize the whole ArrayBuffer to { data: string, lastByte: number | undefined }
  4. Any other creative ideas?

I'm happy to contribute if you'd like; in that case please let me know your preference on the approach. If you feel it's quicker for you to "just do it", that's also fine :-)