diff --git a/README.md b/README.md index c53147e..428fd7c 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,25 @@ let data = encode(obj) let decoded = decode(data) decoded.y[0] // 2 CID.asCID(decoded.z.a) // cid instance + +// encode/decode options are exported for use with cborg's encodedLength and decodeFirst +import { encodeOptions, decodeOptions } from '@ipld/dag-cbor' +import { encodedLength } from 'cborg/length' +import { decodeFirst } from 'cborg' + +// dag-cbor encoded length of obj in bytes +const byteLength = encodedLength(obj, encodeOptions) +byteLength // 104 + +// concatenate two dag-cbor encoded obj +const concatenatedData = new Uint8Array(data.length * 2) +concatenatedData.set(data) +concatenatedData.set(data, data.length) + +// returns dag-cbor decoded obj at the beginning of the buffer as well as the remaining bytes +const [first, remainder] = decodeFirst(concatenatedData, decodeOptions) +assert.deepStrictEqual(first, obj) +assert.deepStrictEqual(remainder, data) ``` ## Spec diff --git a/src/index.js b/src/index.js index cdc058f..d555222 100644 --- a/src/index.js +++ b/src/index.js @@ -64,7 +64,7 @@ function numberEncoder (num) { return null } -const encodeOptions = { +const _encodeOptions = { float64: true, typeEncoders: { Object: cidEncoder, @@ -73,6 +73,13 @@ const encodeOptions = { } } +export const encodeOptions = { + ..._encodeOptions, + typeEncoders: { + ..._encodeOptions.typeEncoders + } +} + /** * @param {Uint8Array} bytes * @returns {CID} @@ -84,7 +91,7 @@ function cidDecoder (bytes) { return CID.decode(bytes.subarray(1)) // ignore leading 0x00 } -const decodeOptions = { +const _decodeOptions = { allowIndefinite: false, coerceUndefinedToNull: true, allowNaN: false, @@ -97,7 +104,12 @@ const decodeOptions = { /** @type {import('cborg').TagDecoder[]} */ tags: [] } -decodeOptions.tags[CID_CBOR_TAG] = cidDecoder +_decodeOptions.tags[CID_CBOR_TAG] = cidDecoder + +export const decodeOptions = { + ..._decodeOptions, + tags: _decodeOptions.tags.slice() +} export const name = 'dag-cbor' export const code = 0x71 @@ -107,11 +119,11 @@ export const code = 0x71 * @param {T} node * @returns {ByteView} */ -export const encode = (node) => cborg.encode(node, encodeOptions) +export const encode = (node) => cborg.encode(node, _encodeOptions) /** * @template T * @param {ByteView} data * @returns {T} */ -export const decode = (data) => cborg.decode(data, decodeOptions) +export const decode = (data) => cborg.decode(data, _decodeOptions) diff --git a/test/test-basics.spec.js b/test/test-basics.spec.js index f2ee5f1..c0549c1 100644 --- a/test/test-basics.spec.js +++ b/test/test-basics.spec.js @@ -3,6 +3,8 @@ import { Buffer } from 'buffer' import { garbage } from '@ipld/garbage' import { assert } from 'aegir/chai' +import { decodeFirst } from 'cborg' +import { encodedLength } from 'cborg/length' import { bytes, CID } from 'multiformats' import * as dagcbor from '../src/index.js' @@ -181,4 +183,23 @@ describe('dag-cbor', () => { const encoded = bytes.fromHex('a3636261720363666f6f0163666f6f02') assert.throws(() => decode(encoded), /CBOR decode error: found repeat map key "foo"/) }) + + test('determine encoded length of obj', () => { + const { encodeOptions } = dagcbor + + const length = encodedLength(obj, encodeOptions) + same(length, serializedObj.length) + }) + + test('.deserialize the first of concatenated serialized objects', () => { + const { decodeOptions } = dagcbor + + const concatSerializedObjs = new Uint8Array(serializedObj.length * 2) + concatSerializedObjs.set(serializedObj) + concatSerializedObjs.set(serializedObj, serializedObj.length) + + const [deserializedObj, remainder] = decodeFirst(concatSerializedObjs, decodeOptions) + same(deserializedObj, obj) + same(remainder, serializedObj) + }) })