-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
decode.js
124 lines (106 loc) · 2.3 KB
/
decode.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
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
'use strict'
const constants = require('./constants')
const ShortString = constants.ShortString
const ShortMap = constants.ShortMap
const Null = constants.Null
var pos = 0
function decode (buf, p) {
pos = p || 0
return _decode(buf)
}
function _decode (buf) {
var first = buf.readUInt8(pos++)
switch (first) {
case ShortString:
return decodeString(buf)
case ShortMap:
return decodeObject(buf)
case Null:
return null
default:
throw new Error('unable to decode')
}
}
// Code partially lifted and adapted from
// https://github.com/google/flatbuffers/blob/master/js/flatbuffers.js
function decodeString (buf) {
var len = buf[pos++]
var to = pos + len
var codePoint
var str = ''
var a = ''
var b = ''
var c = ''
var d = ''
while (pos < to) {
// Decode UTF-8
a = buf[pos++]
if (a < 0xC0) {
codePoint = a
} else {
b = buf[pos++]
if (a < 0xE0) {
codePoint =
((a & 0x1F) << 6) |
(b & 0x3F)
} else {
c = buf[pos++]
if (a < 0xF0) {
codePoint =
((a & 0x0F) << 12) |
((b & 0x3F) << 6) |
(c & 0x3F)
} else {
d = buf[pos++]
codePoint =
((a & 0x07) << 18) |
((b & 0x3F) << 12) |
((c & 0x3F) << 6) |
(d & 0x3F)
}
}
}
// Encode UTF-16
if (codePoint < 0x10000) {
str += String.fromCharCode(codePoint)
} else {
codePoint -= 0x10000
str += String.fromCharCode(
(codePoint >> 10) + 0xD800,
(codePoint & ((1 << 10) - 1)) + 0xDC00)
}
}
pos = to
return str
}
const Props = Symbol('props')
const Buf = Symbol('buf')
var proxyHolder = {
get: get
}
function decodeObject (buf) {
var target = {}
var obj = new Proxy(target, proxyHolder)
var numProps = buf[pos++]
var key = null
var pointer = 0
var props = {}
target[Props] = props
target[Buf] = buf
for (var i = 0; i < numProps; i++) {
pos++
key = decodeString(buf)
pointer = buf.readUInt32BE(pos)
pos += 4
props[key] = pointer
}
return obj
}
function get (target, name) {
var buf = target[Buf]
var props = target[Props]
var val = decode(buf, props[name])
target[name] = val
return val
}
module.exports = decode