function decodeEncryptionContext()

in modules/serialize/src/decode_encryption_context.ts [26:73]


  function decodeEncryptionContext(
    encodedEncryptionContext: Uint8Array
  ): Readonly<EncryptionContext> {
    const encryptionContext: EncryptionContext = Object.create(null)
    /* Check for early return (Postcondition): The case of 0 length is defined as an empty object. */
    if (!encodedEncryptionContext.byteLength) {
      return Object.freeze(encryptionContext)
    }
    /* 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(
      encodedEncryptionContext.buffer,
      encodedEncryptionContext.byteOffset,
      encodedEncryptionContext.byteLength
    )
    const pairsCount = dataView.getUint16(0, false) // big endian
    const elementInfo = readElements(pairsCount, 2, encodedEncryptionContext, 2)
    /* Postcondition: Since the encryption context has a length, it must have pairs.
     * Unlike the encrypted data key section, the encryption context has a length
     * element.  This means I should always pass the entire section.
     */
    if (!elementInfo) throw new Error('context parse error')
    const { elements, readPos } = elementInfo

    /* Postcondition: The byte length of the encodedEncryptionContext must match the readPos. */
    needs(
      encodedEncryptionContext.byteLength === readPos,
      'Overflow, too much data.'
    )

    for (let count = 0; count < pairsCount; count++) {
      const [key, value] = elements[count].map(toUtf8)
      /* Postcondition: The number of keys in the encryptionContext must match the pairsCount.
       * If the same Key value is serialized...
       */
      needs(
        encryptionContext[key] === undefined,
        'Duplicate encryption context key value.'
      )
      encryptionContext[key] = value
    }
    Object.freeze(encryptionContext)
    return encryptionContext
  }