UNPKG

@microsoft/signalr-protocol-msgpack

Version:

MsgPack Protocol support for ASP.NET Core SignalR

72 lines (59 loc) 2.6 kB
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // Not exported from index. /** @private */ export class BinaryMessageFormat { // The length prefix of binary messages is encoded as VarInt. Read the comment in // the BinaryMessageParser.TryParseMessage for details. public static write(output: Uint8Array): ArrayBuffer { let size = output.byteLength || output.length; const lenBuffer = []; do { let sizePart = size & 0x7f; size = size >> 7; if (size > 0) { sizePart |= 0x80; } lenBuffer.push(sizePart); } while (size > 0); size = output.byteLength || output.length; const buffer = new Uint8Array(lenBuffer.length + size); buffer.set(lenBuffer, 0); buffer.set(output, lenBuffer.length); return buffer.buffer; } public static parse(input: ArrayBuffer): Uint8Array[] { const result: Uint8Array[] = []; const uint8Array = new Uint8Array(input); const maxLengthPrefixSize = 5; const numBitsToShift = [0, 7, 14, 21, 28 ]; for (let offset = 0; offset < input.byteLength;) { let numBytes = 0; let size = 0; let byteRead; do { byteRead = uint8Array[offset + numBytes]; size = size | ((byteRead & 0x7f) << (numBitsToShift[numBytes])); numBytes++; } while (numBytes < Math.min(maxLengthPrefixSize, input.byteLength - offset) && (byteRead & 0x80) !== 0); if ((byteRead & 0x80) !== 0 && numBytes < maxLengthPrefixSize) { throw new Error("Cannot read message size."); } if (numBytes === maxLengthPrefixSize && byteRead > 7) { throw new Error("Messages bigger than 2GB are not supported."); } if (uint8Array.byteLength >= (offset + numBytes + size)) { // IE does not support .slice() so use subarray result.push(uint8Array.slice ? uint8Array.slice(offset + numBytes, offset + numBytes + size) : uint8Array.subarray(offset + numBytes, offset + numBytes + size)); } else { throw new Error("Incomplete message."); } offset = offset + numBytes + size; } return result; } }