mirror of
https://github.com/pezkuwichain/pezkuwi-api.git
synced 2026-11-03 15:01:06 +00:00
The pezkuwi-dev build treats any package with a src/ directory as its own: it requires our license header on every file and builds it. These are upstream files that must stay byte-identical to the source embedded in dist/, so they live in upstream-src/ instead, which neither the build nor the root tsconfig picks up.
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { createDecoder, Hex, u16, u8, type HexString } from "../codecs"
|
|
import { type TrieNodeHeaderKey, TrieNodeHeaders, type TrieNode } from "./types"
|
|
|
|
const varHex = Hex().dec
|
|
const allHex = Hex(Infinity).dec
|
|
const hex32 = Hex(32).dec
|
|
const byte = u8.dec
|
|
|
|
const getHeader = (
|
|
bytes: Uint8Array,
|
|
): { type: TrieNodeHeaderKey; partialKey: string } => {
|
|
const firstByte = byte(bytes)
|
|
|
|
let bitsLeft = 6
|
|
const typeId = firstByte >> bitsLeft
|
|
const type: TrieNodeHeaderKey = typeId
|
|
? typeId === 1
|
|
? TrieNodeHeaders.Leaf
|
|
: typeId === 2
|
|
? TrieNodeHeaders.Branch
|
|
: TrieNodeHeaders.BranchWithVal
|
|
: firstByte >> --bitsLeft
|
|
? TrieNodeHeaders.LeafWithHash
|
|
: firstByte >> --bitsLeft
|
|
? TrieNodeHeaders.BranchWithHash
|
|
: firstByte
|
|
? TrieNodeHeaders.Reserved
|
|
: TrieNodeHeaders.Empty
|
|
|
|
let nNibles = firstByte & (0xff >> (8 - bitsLeft))
|
|
if (nNibles === 2 ** bitsLeft - 1) {
|
|
let current: number
|
|
do nNibles += current = byte(bytes)
|
|
while (current === 255)
|
|
}
|
|
|
|
return {
|
|
type,
|
|
partialKey: Hex(Math.ceil(nNibles / 2))
|
|
.dec(bytes)
|
|
.slice(nNibles % 2 ? 3 : 2),
|
|
}
|
|
}
|
|
|
|
export const trieNodeDec = createDecoder((bytes): TrieNode => {
|
|
const header = getHeader(bytes)
|
|
const { type } = header
|
|
|
|
if (type === "Empty" || type === "Reserved") return header as TrieNode
|
|
if (type === "Leaf" || type === "LeafWithHash")
|
|
return {
|
|
...header,
|
|
value: allHex(bytes),
|
|
} as TrieNode
|
|
|
|
const bitmap = u16.dec(bytes)
|
|
const keys: string[] = []
|
|
for (let i = 0; i < 16; i++) if ((bitmap >> i) & 1) keys.push(i.toString(16))
|
|
|
|
let value: null | HexString = null
|
|
if (type === "BranchWithVal") value = varHex(bytes)
|
|
if (type === "BranchWithHash") value = hex32(bytes)
|
|
|
|
const result: any = {
|
|
...header,
|
|
children: Object.fromEntries(keys.map((key) => [key, varHex(bytes)])),
|
|
}
|
|
if (value !== null) result.value = value
|
|
return result
|
|
})
|