Skip to content
This repository was archived by the owner on Sep 29, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# js-multicodec
# js-multicodec <!-- omit in toc -->

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)
Expand All @@ -9,14 +9,16 @@

> JavaScript implementation of the multicodec specification

## Lead Maintainer
## Lead Maintainer <!-- omit in toc -->

[Henrique Dias](https://github.com/hacdias)

## Table of Contents
## Table of Contents <!-- omit in toc -->

- [Install](#install)
- [Usage](#usage)
- [Example](#example)
- [API](#api)
- [Updating the lookup table](#updating-the-lookup-table)
- [Contribute](#contribute)
- [License](#license)
Expand Down
2 changes: 1 addition & 1 deletion example.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const multicodec = require('multicodec')

const prefixedProtobuf = multicodec.addPrefix('protobuf', Buffer.from('some protobuf code'))
const prefixedProtobuf = multicodec.addPrefix('protobuf', new TextEncoder().encode('some protobuf code'))

// eslint-disable-next-line no-console
console.log(prefixedProtobuf)
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@
},
"homepage": "https://github.com/multiformats/js-multicodec#readme",
"dependencies": {
"buffer": "^5.6.0",
"uint8arrays": "0.0.2",
"varint": "^5.0.0"
},
"devDependencies": {
"aegir": "^23.0.0",
"bent": "^7.3.4",
"chai": "^4.2.0",
"dirty-chai": "^2.0.1",
"pre-push": "~0.1.1"
},
"contributors": [
Expand Down
24 changes: 12 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,41 @@
*/
'use strict'

const { Buffer } = require('buffer')
const varint = require('varint')
const intTable = require('./int-table')
const codecNameToCodeVarint = require('./varint-table')
const util = require('./util')
const uint8ArrayConcat = require('uint8arrays/concat')

exports = module.exports

/**
* Prefix a buffer with a multicodec-packed.
*
* @param {string|number} multicodecStrOrCode
* @param {Buffer} data
* @returns {Buffer}
* @param {Uint8Array} data
* @returns {Uint8Array}
*/
exports.addPrefix = (multicodecStrOrCode, data) => {
let prefix

if (Buffer.isBuffer(multicodecStrOrCode)) {
prefix = util.varintBufferEncode(multicodecStrOrCode)
if (multicodecStrOrCode instanceof Uint8Array) {
prefix = util.varintUint8ArrayEncode(multicodecStrOrCode)
} else {
if (codecNameToCodeVarint[multicodecStrOrCode]) {
prefix = codecNameToCodeVarint[multicodecStrOrCode]
} else {
throw new Error('multicodec not recognized')
}
}
return Buffer.concat([prefix, data])
return uint8ArrayConcat([prefix, data], prefix.length + data.length)
}

/**
* Decapsulate the multicodec-packed prefix from the data.
*
* @param {Buffer} data
* @returns {Buffer}
* @param {Uint8Array} data
* @returns {Uint8Array}
*/
exports.rmPrefix = (data) => {
varint.decode(data)
Expand All @@ -54,7 +54,7 @@ exports.rmPrefix = (data) => {

/**
* Get the codec of the prefixed data.
* @param {Buffer} prefixedData
* @param {Uint8Array} prefixedData
* @returns {string}
*/
exports.getCodec = (prefixedData) => {
Expand Down Expand Up @@ -85,12 +85,12 @@ exports.getNumber = (name) => {
if (code === undefined) {
throw new Error('Codec `' + name + '` not found')
}
return util.varintBufferDecode(code)[0]
return util.varintUint8ArrayDecode(code)[0]
}

/**
* Get the code of the prefixed data.
* @param {Buffer} prefixedData
* @param {Uint8Array} prefixedData
* @returns {number}
*/
exports.getCode = (prefixedData) => {
Expand All @@ -100,7 +100,7 @@ exports.getCode = (prefixedData) => {
/**
* Get the code as varint of a codec name.
* @param {string} codecName
* @returns {Buffer}
* @returns {Uint8Array}
*/
exports.getCodeVarint = (codecName) => {
const code = codecNameToCodeVarint[codecName]
Expand Down
30 changes: 16 additions & 14 deletions src/util.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
'use strict'

const varint = require('varint')
const { Buffer } = require('buffer')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayFromString = require('uint8arrays/from-string')

module.exports = {
numberToBuffer,
bufferToNumber,
varintBufferEncode,
varintBufferDecode,
numberToUint8Array,
uint8ArrayToNumber,
varintUint8ArrayEncode,
varintUint8ArrayDecode,
varintEncode
}

function bufferToNumber (buf) {
return parseInt(buf.toString('hex'), 16)
function uint8ArrayToNumber (buf) {
return parseInt(uint8ArrayToString(buf, 'base16'), 16)
}

function numberToBuffer (num) {
function numberToUint8Array (num) {
let hexString = num.toString(16)
if (hexString.length % 2 === 1) {
hexString = '0' + hexString
}
return Buffer.from(hexString, 'hex')
return uint8ArrayFromString(hexString, 'base16')
}

function varintBufferEncode (input) {
return Buffer.from(varint.encode(bufferToNumber(input)))
function varintUint8ArrayEncode (input) {
return Uint8Array.from(varint.encode(uint8ArrayToNumber(input)))
}

function varintBufferDecode (input) {
return numberToBuffer(varint.decode(input))
function varintUint8ArrayDecode (input) {
return numberToUint8Array(varint.decode(input))
}

function varintEncode (num) {
return Buffer.from(varint.encode(num))
return Uint8Array.from(varint.encode(num))
}
2 changes: 1 addition & 1 deletion src/varint-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const baseTable = require('./base-table.json')
const varintEncode = require('./util').varintEncode

// map for codecName -> codeVarintBuffer
// map for codecName -> codeVarintUint8Array
const varintTable = {}

for (const encodingName in baseTable) {
Expand Down
22 changes: 10 additions & 12 deletions test/multicodec.spec.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,39 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const { expect } = require('aegir/utils/chai')
const multicodec = require('../src')
const uint8ArrayFromString = require('uint8arrays/from-string')

describe('multicodec', () => {
it('add prefix through multicodec (string)', () => {
const buf = Buffer.from('hey')
const buf = uint8ArrayFromString('hey')
const prefixedBuf = multicodec.addPrefix('protobuf', buf)
expect(multicodec.getCodec(prefixedBuf)).to.equal('protobuf')
expect(buf).to.eql(multicodec.rmPrefix(prefixedBuf))
})

it('add prefix through code (code)', () => {
const buf = Buffer.from('hey')
const prefixedBuf = multicodec.addPrefix(Buffer.from('70', 'hex'), buf)
const buf = uint8ArrayFromString('hey')
const prefixedBuf = multicodec.addPrefix(uint8ArrayFromString('70', 'base16'), buf)
expect(multicodec.getCodec(prefixedBuf)).to.equal('dag-pb')
expect(buf).to.eql(multicodec.rmPrefix(prefixedBuf))
})

it('add multibyte varint prefix (eth-block) through multicodec (string)', () => {
const buf = Buffer.from('hey')
const buf = uint8ArrayFromString('hey')
const prefixedBuf = multicodec.addPrefix('eth-block', buf)
expect(multicodec.getCodec(prefixedBuf)).to.equal('eth-block')
expect(buf).to.eql(multicodec.rmPrefix(prefixedBuf))
})

it('returns code via codec name', () => {
const code = multicodec.getCodeVarint('keccak-256')
expect(code).to.eql(Buffer.from('1b', 'hex'))
expect(code).to.eql(uint8ArrayFromString('1b', 'base16'))
})

it('returns code from prefixed data', () => {
const buf = Buffer.from('hey')
const buf = uint8ArrayFromString('hey')
const prefixedBuf = multicodec.addPrefix('dag-cbor', buf)
const code = multicodec.getCode(prefixedBuf)
expect(code).to.eql(multicodec.DAG_CBOR)
Expand Down Expand Up @@ -92,9 +90,9 @@ describe('multicodec', () => {
})

it('throws error on unknown codec name when getting the codec', () => {
const code = Buffer.from('ffee', 'hex')
const code = uint8ArrayFromString('ffee', 'base16')

const buf = Buffer.from('hey')
const buf = uint8ArrayFromString('hey')
const prefixedBuf = multicodec.addPrefix(code, buf)
expect(() => {
multicodec.getCodec(prefixedBuf)
Expand Down