UNPKG

2.94 kBJavaScriptView Raw
1/**
2 * Implementation of the multicodec specification.
3 *
4 * @module multicodec
5 * @example
6 * const multicodec = require('multicodec')
7 *
8 * const prefixedProtobuf = multicodec.addPrefix('protobuf', protobufBuffer)
9 * // prefixedProtobuf 0x50...
10 *
11 */
12'use strict'
13
14const varint = require('varint')
15const intTable = require('./int-table')
16const codecNameToCodeVarint = require('./varint-table')
17const util = require('./util')
18const uint8ArrayConcat = require('uint8arrays/concat')
19
20exports = module.exports
21
22/**
23 * Prefix a buffer with a multicodec-packed.
24 *
25 * @param {string|number} multicodecStrOrCode
26 * @param {Uint8Array} data
27 * @returns {Uint8Array}
28 */
29exports.addPrefix = (multicodecStrOrCode, data) => {
30 let prefix
31
32 if (multicodecStrOrCode instanceof Uint8Array) {
33 prefix = util.varintUint8ArrayEncode(multicodecStrOrCode)
34 } else {
35 if (codecNameToCodeVarint[multicodecStrOrCode]) {
36 prefix = codecNameToCodeVarint[multicodecStrOrCode]
37 } else {
38 throw new Error('multicodec not recognized')
39 }
40 }
41 return uint8ArrayConcat([prefix, data], prefix.length + data.length)
42}
43
44/**
45 * Decapsulate the multicodec-packed prefix from the data.
46 *
47 * @param {Uint8Array} data
48 * @returns {Uint8Array}
49 */
50exports.rmPrefix = (data) => {
51 varint.decode(data)
52 return data.slice(varint.decode.bytes)
53}
54
55/**
56 * Get the codec of the prefixed data.
57 * @param {Uint8Array} prefixedData
58 * @returns {string}
59 */
60exports.getCodec = (prefixedData) => {
61 const code = varint.decode(prefixedData)
62 const codecName = intTable.get(code)
63 if (codecName === undefined) {
64 throw new Error(`Code ${code} not found`)
65 }
66 return codecName
67}
68
69/**
70 * Get the name of the codec.
71 * @param {number} codec
72 * @returns {string}
73 */
74exports.getName = (codec) => {
75 return intTable.get(codec)
76}
77
78/**
79 * Get the code of the codec
80 * @param {string} name
81 * @returns {number}
82 */
83exports.getNumber = (name) => {
84 const code = codecNameToCodeVarint[name]
85 if (code === undefined) {
86 throw new Error('Codec `' + name + '` not found')
87 }
88 return varint.decode(code)
89}
90
91/**
92 * Get the code of the prefixed data.
93 * @param {Uint8Array} prefixedData
94 * @returns {number}
95 */
96exports.getCode = (prefixedData) => {
97 return varint.decode(prefixedData)
98}
99
100/**
101 * Get the code as varint of a codec name.
102 * @param {string} codecName
103 * @returns {Uint8Array}
104 */
105exports.getCodeVarint = (codecName) => {
106 const code = codecNameToCodeVarint[codecName]
107 if (code === undefined) {
108 throw new Error('Codec `' + codecName + '` not found')
109 }
110 return code
111}
112
113/**
114 * Get the varint of a code.
115 * @param {Number} code
116 * @returns {Array.<number>}
117 */
118exports.getVarint = (code) => {
119 return varint.encode(code)
120}
121
122// Make the constants top-level constants
123const constants = require('./constants')
124Object.assign(exports, constants)
125
126// Human friendly names for printing, e.g. in error messages
127exports.print = require('./print')