Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1x 30x 30x 22x 22x 8x 8x 126x 116x 62x 62x 8x 8x 8x 8x 4x 4x 4x 4x 8x 8x 46x 46x 46x 46x 4x 24x 24x 24x 24x 24x 8x | export class Decoder {
private pos = 0
private data: DataView
private array: Uint8Array
constructor(data: Uint8Array | ArrayBuffer) {
if (data instanceof Uint8Array) {
this.data = new DataView(data.buffer, data.byteOffset, data.byteLength)
this.array = data
} else {
this.data = new DataView(data)
this.array = new Uint8Array(data)
}
}
canRead(bytes = 1): boolean {
return !(this.pos + bytes > this.array.byteLength)
}
private ensure(bytes: number) {
Iif (!this.canRead(bytes)) {
throw new Error('Read past end of buffer')
}
}
/** Read one byte. */
readByte(): number {
this.ensure(1)
return this.array[this.pos++]
}
/** Read integer as JavaScript number, up to 32 bits. */
readNum(byteWidth: number, littleEndian = false) {
this.ensure(byteWidth)
const d = this.data,
p = this.pos
let rv: number
switch (byteWidth) {
case 1:
rv = d.getUint8(p)
break
case 2:
rv = d.getUint16(p, littleEndian)
break
case 4:
rv = d.getUint32(p, littleEndian)
break
case -1:
rv = d.getInt8(p)
break
case -2:
rv = d.getInt16(p, littleEndian)
break
case -4:
rv = d.getInt32(p, littleEndian)
break
default:
throw new Error('Invalid integer width')
}
this.pos += byteWidth
return rv
}
readArray(length: number) {
this.ensure(length)
const rv = this.array.subarray(this.pos, this.pos + length)
this.pos += length
return rv
}
remainder() {
return this.array.subarray(this.pos)
}
readDer(tag: number) {
const t = this.readByte()
Iif (t !== tag) {
throw new Error(`Unexpected DER tag: ${t}`)
}
const len = this.readByte()
Iif (len < 0) {
throw new Error('Invalid DER length')
}
return this.readArray(len)
}
derDecoder(tag: number) {
return new Decoder(this.readDer(tag))
}
}
|