in modules/serialize/src/decode_body_header.ts [64:121]
export function decodeFrameBodyHeader(
buffer: Uint8Array,
headerInfo: HeaderInfo,
readPos: number
): FrameBodyHeader | false {
/* Precondition: The contentType must be FRAMED_DATA. */
needs(
ContentType.FRAMED_DATA === headerInfo.messageHeader.contentType,
'Unknown contentType'
)
const { frameLength } = headerInfo.messageHeader
const { ivLength, tagLength } = headerInfo.algorithmSuite
/* Uint8Array is a view on top of the underlying ArrayBuffer.
* This means that raw underlying memory stored in the ArrayBuffer
* may be larger than the Uint8Array. This is especially true of
* the Node.js Buffer object. The offset and length *must* be
* passed to the DataView otherwise I will get unexpected results.
*/
const dataView = new DataView(
buffer.buffer,
buffer.byteOffset,
buffer.byteLength
)
/* Precondition: decodeFrameBodyHeader readPos must be within the byte length of the buffer given. */
needs(
dataView.byteLength >= readPos && readPos >= 0,
'readPos out of bounds.'
)
/* Check for early return (Postcondition): There must be enough data to decodeFrameBodyHeader.
* The format expressed here is
* SequenceIdentifier: Uint32
* IVLength: Uint8
* There is a special case where the SequenceIdentifier is the Final Frame.
*/
if (4 + ivLength + readPos > dataView.byteLength) return false
const sequenceNumber = dataView.getUint32(readPos)
/* Postcondition: decodeFrameBodyHeader sequenceNumber must be greater than 0. */
needs(sequenceNumber > 0, 'Malformed sequenceNumber.')
if (sequenceNumber === SequenceIdentifier.SEQUENCE_NUMBER_END) {
return decodeFinalFrameBodyHeader(buffer, headerInfo, readPos)
}
const iv = buffer.slice((readPos += 4), (readPos += ivLength))
return {
sequenceNumber,
iv,
contentLength: frameLength,
readPos,
tagLength,
isFinalFrame: false,
contentType: ContentType.FRAMED_DATA,
}
}