forked from rvagg/cborg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
taglib.js
57 lines (49 loc) · 1.66 KB
/
taglib.js
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
import { Token, Type } from './cborg.js'
/*
A collection of some standard CBOR tags.
There are no tags included by default in the cborg encoder or decoder, you have
to include them by passing options. `typeEncoders` for encode() and `tags` for
decode().
The encoders here can be included with these options (see the tests for how this
can be done), or as examples for writing additional tags. Additional standard
(and reasonable) tags may be added here by pull request.
*/
/* TAG(2) Bignums https://tools.ietf.org/html/rfc8949#section-3.4.3 */
const neg1b = BigInt(-1)
const pos1b = BigInt(1)
const zerob = BigInt(0)
const twob = BigInt(2)
const eightb = BigInt(8)
export function bigIntDecoder (bytes) {
// TODO: assert that `bytes` is a `Uint8Array`
let bi = zerob
for (let ii = 0; ii < bytes.length; ii++) {
bi = (bi << eightb) + BigInt(bytes[ii])
}
return bi
}
function fromBigInt (bi) {
const buf = []
while (bi > 0) {
buf.unshift(Number(bi) & 0xff)
bi >>= eightb
}
return Uint8Array.from(buf)
}
// assuming that we're receiving a BigInt here, it should be registered for
// type 'bigint' for this to work.
const maxSafeBigInt = (twob ** BigInt(64)) - pos1b
const minSafeBigInt = neg1b * (twob ** BigInt(64))
export function bigIntEncoder (obj) {
if (obj >= minSafeBigInt && obj <= maxSafeBigInt) {
return null // null = do it the standard way
}
return [
new Token(Type.tag, obj >= zerob ? 2 : 3),
new Token(Type.bytes, fromBigInt(obj >= zerob ? obj : obj * neg1b - pos1b))
]
}
/* TAG(3) Negative Bignums https://tools.ietf.org/html/rfc8949#section-3.4.3 */
export function bigNegIntDecoder (bytes) {
return neg1b - bigIntDecoder(bytes)
}