- Add GETTING_STARTED.md with quick start guide and development modes - Add INSTALL.sh automated installation script - Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md - Add QUICK_REFERENCE.md for common commands - Add SETUP_GUIDE.md with detailed setup instructions - Update README.md with improved project overview - Add did-wallet app dependencies and node_modules
210 lines
7.7 KiB
JavaScript
210 lines
7.7 KiB
JavaScript
import { Token, Type } from './token.js'
|
|
import * as uint from './0uint.js'
|
|
import * as negint from './1negint.js'
|
|
import * as bytes from './2bytes.js'
|
|
import * as string from './3string.js'
|
|
import * as array from './4array.js'
|
|
import * as map from './5map.js'
|
|
import * as tag from './6tag.js'
|
|
import * as float from './7float.js'
|
|
import { decodeErrPrefix } from './common.js'
|
|
import { fromArray } from './byte-utils.js'
|
|
|
|
/**
|
|
* @typedef {import('../interface').DecodeOptions} DecodeOptions
|
|
*/
|
|
|
|
/**
|
|
* @param {Uint8Array} data
|
|
* @param {number} pos
|
|
* @param {number} minor
|
|
*/
|
|
function invalidMinor (data, pos, minor) {
|
|
throw new Error(`${decodeErrPrefix} encountered invalid minor (${minor}) for major ${data[pos] >>> 5}`)
|
|
}
|
|
|
|
/**
|
|
* @param {string} msg
|
|
* @returns {()=>any}
|
|
*/
|
|
function errorer (msg) {
|
|
return () => { throw new Error(`${decodeErrPrefix} ${msg}`) }
|
|
}
|
|
|
|
/** @type {((data:Uint8Array, pos:number, minor:number, options?:DecodeOptions) => any)[]} */
|
|
export const jump = []
|
|
|
|
// unsigned integer, 0x00..0x17 (0..23)
|
|
for (let i = 0; i <= 0x17; i++) {
|
|
jump[i] = invalidMinor // uint.decodeUintCompact, handled by quick[]
|
|
}
|
|
jump[0x18] = uint.decodeUint8 // unsigned integer, one-byte uint8_t follows
|
|
jump[0x19] = uint.decodeUint16 // unsigned integer, two-byte uint16_t follows
|
|
jump[0x1a] = uint.decodeUint32 // unsigned integer, four-byte uint32_t follows
|
|
jump[0x1b] = uint.decodeUint64 // unsigned integer, eight-byte uint64_t follows
|
|
jump[0x1c] = invalidMinor
|
|
jump[0x1d] = invalidMinor
|
|
jump[0x1e] = invalidMinor
|
|
jump[0x1f] = invalidMinor
|
|
// negative integer, -1-0x00..-1-0x17 (-1..-24)
|
|
for (let i = 0x20; i <= 0x37; i++) {
|
|
jump[i] = invalidMinor // negintDecode, handled by quick[]
|
|
}
|
|
jump[0x38] = negint.decodeNegint8 // negative integer, -1-n one-byte uint8_t for n follows
|
|
jump[0x39] = negint.decodeNegint16 // negative integer, -1-n two-byte uint16_t for n follows
|
|
jump[0x3a] = negint.decodeNegint32 // negative integer, -1-n four-byte uint32_t for follows
|
|
jump[0x3b] = negint.decodeNegint64 // negative integer, -1-n eight-byte uint64_t for follows
|
|
jump[0x3c] = invalidMinor
|
|
jump[0x3d] = invalidMinor
|
|
jump[0x3e] = invalidMinor
|
|
jump[0x3f] = invalidMinor
|
|
// byte string, 0x00..0x17 bytes follow
|
|
for (let i = 0x40; i <= 0x57; i++) {
|
|
jump[i] = bytes.decodeBytesCompact
|
|
}
|
|
jump[0x58] = bytes.decodeBytes8 // byte string, one-byte uint8_t for n, and then n bytes follow
|
|
jump[0x59] = bytes.decodeBytes16 // byte string, two-byte uint16_t for n, and then n bytes follow
|
|
jump[0x5a] = bytes.decodeBytes32 // byte string, four-byte uint32_t for n, and then n bytes follow
|
|
jump[0x5b] = bytes.decodeBytes64 // byte string, eight-byte uint64_t for n, and then n bytes follow
|
|
jump[0x5c] = invalidMinor
|
|
jump[0x5d] = invalidMinor
|
|
jump[0x5e] = invalidMinor
|
|
jump[0x5f] = errorer('indefinite length bytes/strings are not supported') // byte string, byte strings follow, terminated by "break"
|
|
// UTF-8 string 0x00..0x17 bytes follow
|
|
for (let i = 0x60; i <= 0x77; i++) {
|
|
jump[i] = string.decodeStringCompact
|
|
}
|
|
jump[0x78] = string.decodeString8 // UTF-8 string, one-byte uint8_t for n, and then n bytes follow
|
|
jump[0x79] = string.decodeString16 // UTF-8 string, two-byte uint16_t for n, and then n bytes follow
|
|
jump[0x7a] = string.decodeString32 // UTF-8 string, four-byte uint32_t for n, and then n bytes follow
|
|
jump[0x7b] = string.decodeString64 // UTF-8 string, eight-byte uint64_t for n, and then n bytes follow
|
|
jump[0x7c] = invalidMinor
|
|
jump[0x7d] = invalidMinor
|
|
jump[0x7e] = invalidMinor
|
|
jump[0x7f] = errorer('indefinite length bytes/strings are not supported') // UTF-8 strings follow, terminated by "break"
|
|
// array, 0x00..0x17 data items follow
|
|
for (let i = 0x80; i <= 0x97; i++) {
|
|
jump[i] = array.decodeArrayCompact
|
|
}
|
|
jump[0x98] = array.decodeArray8 // array, one-byte uint8_t for n, and then n data items follow
|
|
jump[0x99] = array.decodeArray16 // array, two-byte uint16_t for n, and then n data items follow
|
|
jump[0x9a] = array.decodeArray32 // array, four-byte uint32_t for n, and then n data items follow
|
|
jump[0x9b] = array.decodeArray64 // array, eight-byte uint64_t for n, and then n data items follow
|
|
jump[0x9c] = invalidMinor
|
|
jump[0x9d] = invalidMinor
|
|
jump[0x9e] = invalidMinor
|
|
jump[0x9f] = array.decodeArrayIndefinite // array, data items follow, terminated by "break"
|
|
// map, 0x00..0x17 pairs of data items follow
|
|
for (let i = 0xa0; i <= 0xb7; i++) {
|
|
jump[i] = map.decodeMapCompact
|
|
}
|
|
jump[0xb8] = map.decodeMap8 // map, one-byte uint8_t for n, and then n pairs of data items follow
|
|
jump[0xb9] = map.decodeMap16 // map, two-byte uint16_t for n, and then n pairs of data items follow
|
|
jump[0xba] = map.decodeMap32 // map, four-byte uint32_t for n, and then n pairs of data items follow
|
|
jump[0xbb] = map.decodeMap64 // map, eight-byte uint64_t for n, and then n pairs of data items follow
|
|
jump[0xbc] = invalidMinor
|
|
jump[0xbd] = invalidMinor
|
|
jump[0xbe] = invalidMinor
|
|
jump[0xbf] = map.decodeMapIndefinite // map, pairs of data items follow, terminated by "break"
|
|
// tags
|
|
for (let i = 0xc0; i <= 0xd7; i++) {
|
|
jump[i] = tag.decodeTagCompact
|
|
}
|
|
jump[0xd8] = tag.decodeTag8
|
|
jump[0xd9] = tag.decodeTag16
|
|
jump[0xda] = tag.decodeTag32
|
|
jump[0xdb] = tag.decodeTag64
|
|
jump[0xdc] = invalidMinor
|
|
jump[0xdd] = invalidMinor
|
|
jump[0xde] = invalidMinor
|
|
jump[0xdf] = invalidMinor
|
|
// 0xe0..0xf3 simple values, unsupported
|
|
for (let i = 0xe0; i <= 0xf3; i++) {
|
|
jump[i] = errorer('simple values are not supported')
|
|
}
|
|
jump[0xf4] = invalidMinor // false, handled by quick[]
|
|
jump[0xf5] = invalidMinor // true, handled by quick[]
|
|
jump[0xf6] = invalidMinor // null, handled by quick[]
|
|
jump[0xf7] = float.decodeUndefined // undefined
|
|
jump[0xf8] = errorer('simple values are not supported') // simple value, one byte follows, unsupported
|
|
jump[0xf9] = float.decodeFloat16 // half-precision float (two-byte IEEE 754)
|
|
jump[0xfa] = float.decodeFloat32 // single-precision float (four-byte IEEE 754)
|
|
jump[0xfb] = float.decodeFloat64 // double-precision float (eight-byte IEEE 754)
|
|
jump[0xfc] = invalidMinor
|
|
jump[0xfd] = invalidMinor
|
|
jump[0xfe] = invalidMinor
|
|
jump[0xff] = float.decodeBreak // "break" stop code
|
|
|
|
/** @type {Token[]} */
|
|
export const quick = []
|
|
// ints <24
|
|
for (let i = 0; i < 24; i++) {
|
|
quick[i] = new Token(Type.uint, i, 1)
|
|
}
|
|
// negints >= -24
|
|
for (let i = -1; i >= -24; i--) {
|
|
quick[31 - i] = new Token(Type.negint, i, 1)
|
|
}
|
|
// empty bytes
|
|
quick[0x40] = new Token(Type.bytes, new Uint8Array(0), 1)
|
|
// empty string
|
|
quick[0x60] = new Token(Type.string, '', 1)
|
|
// empty list
|
|
quick[0x80] = new Token(Type.array, 0, 1)
|
|
// empty map
|
|
quick[0xa0] = new Token(Type.map, 0, 1)
|
|
// false
|
|
quick[0xf4] = new Token(Type.false, false, 1)
|
|
// true
|
|
quick[0xf5] = new Token(Type.true, true, 1)
|
|
// null
|
|
quick[0xf6] = new Token(Type.null, null, 1)
|
|
|
|
/**
|
|
* @param {Token} token
|
|
* @returns {Uint8Array|undefined}
|
|
*/
|
|
export function quickEncodeToken (token) {
|
|
switch (token.type) {
|
|
case Type.false:
|
|
return fromArray([0xf4])
|
|
case Type.true:
|
|
return fromArray([0xf5])
|
|
case Type.null:
|
|
return fromArray([0xf6])
|
|
case Type.bytes:
|
|
if (!token.value.length) {
|
|
return fromArray([0x40])
|
|
}
|
|
return
|
|
case Type.string:
|
|
if (token.value === '') {
|
|
return fromArray([0x60])
|
|
}
|
|
return
|
|
case Type.array:
|
|
if (token.value === 0) {
|
|
return fromArray([0x80])
|
|
}
|
|
/* c8 ignore next 2 */
|
|
// shouldn't be possible if this were called when there was only one token
|
|
return
|
|
case Type.map:
|
|
if (token.value === 0) {
|
|
return fromArray([0xa0])
|
|
}
|
|
/* c8 ignore next 2 */
|
|
// shouldn't be possible if this were called when there was only one token
|
|
return
|
|
case Type.uint:
|
|
if (token.value < 24) {
|
|
return fromArray([Number(token.value)])
|
|
}
|
|
return
|
|
case Type.negint:
|
|
if (token.value >= -24) {
|
|
return fromArray([31 - Number(token.value)])
|
|
}
|
|
}
|
|
}
|