1 |
|
2 |
|
3 | exports.Decoder = Decoder;
|
4 |
|
5 | var BufferLite = require("./buffer-lite");
|
6 | var extdecoders = require("./ext").decoders;
|
7 |
|
8 | var IS_BUFFER_SHIM = ("TYPED_ARRAY_SUPPORT" in Buffer);
|
9 | var NO_ASSERT = true;
|
10 |
|
11 | function Decoder(opts) {
|
12 | if (!(this instanceof Decoder)) return new Decoder(opts);
|
13 | if (opts && opts.push) this.push = opts.push.bind(opts);
|
14 | }
|
15 |
|
16 | Decoder.prototype.decode = function(chunk, encoding, callback) {
|
17 | if (!this.buffer) {
|
18 |
|
19 | this.buffer = chunk;
|
20 | } else {
|
21 |
|
22 | var prev = this.offset ? this.buffer.slice(this.offset) : this.buffer;
|
23 | this.buffer = Buffer.concat([prev, chunk]);
|
24 | }
|
25 |
|
26 | this.bufferLength = this.buffer.length;
|
27 | this.offset = 0;
|
28 |
|
29 |
|
30 | this.flush();
|
31 |
|
32 |
|
33 | if (callback) callback();
|
34 | };
|
35 |
|
36 | Decoder.prototype.flush = function() {
|
37 | if (!this.bufferLength) return;
|
38 | var start = this.offset;
|
39 | var value = decode(this);
|
40 | if (value === BUFFER_SHORTAGE) {
|
41 | this.offset = start;
|
42 | return;
|
43 | }
|
44 | this.push(value);
|
45 | return this.flush();
|
46 | };
|
47 |
|
48 | var token = [];
|
49 | var uint8 = read(1, Buffer.prototype.readUInt8);
|
50 |
|
51 | init();
|
52 |
|
53 | function init() {
|
54 | var i;
|
55 |
|
56 | var uint16 = read(2, Buffer.prototype.readUInt16BE);
|
57 | var uint32 = read(4, Buffer.prototype.readUInt32BE);
|
58 | var uint64 = read(8, readUInt64BE);
|
59 | var int8 = read(1, Buffer.prototype.readInt8);
|
60 | var int16 = read(2, Buffer.prototype.readInt16BE);
|
61 | var int32 = read(4, Buffer.prototype.readInt32BE);
|
62 | var int64 = read(8, readInt64BE);
|
63 | var float32 = read(4, Buffer.prototype.readFloatBE);
|
64 | var float64 = read(8, Buffer.prototype.readDoubleBE);
|
65 |
|
66 |
|
67 | for (i = 0x00; i <= 0x7f; i++) {
|
68 | token[i] = constant(i);
|
69 | }
|
70 |
|
71 |
|
72 | for (i = 0x80; i <= 0x8f; i++) {
|
73 | token[i] = fix(i - 0x80, map);
|
74 | }
|
75 |
|
76 |
|
77 | for (i = 0x90; i <= 0x9f; i++) {
|
78 | token[i] = fix(i - 0x90, array);
|
79 | }
|
80 |
|
81 |
|
82 | for (i = 0xa0; i <= 0xbf; i++) {
|
83 | token[i] = fix(i - 0xa0, str);
|
84 | }
|
85 |
|
86 |
|
87 | token[0xc0] = constant(null);
|
88 |
|
89 |
|
90 | token[0xc1] = constant(new Error("Invalid MessagePack token: 0xC1"));
|
91 |
|
92 |
|
93 |
|
94 | token[0xc2] = constant(false);
|
95 | token[0xc3] = constant(true);
|
96 |
|
97 |
|
98 |
|
99 |
|
100 | token[0xc4] = flex(uint8, bin);
|
101 | token[0xc5] = flex(uint16, bin);
|
102 | token[0xc6] = flex(uint32, bin);
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | token[0xc7] = flex(uint8, ext);
|
108 | token[0xc8] = flex(uint16, ext);
|
109 | token[0xc9] = flex(uint32, ext);
|
110 |
|
111 |
|
112 |
|
113 | token[0xca] = float32;
|
114 | token[0xcb] = float64;
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | token[0xcc] = uint8;
|
121 | token[0xcd] = uint16;
|
122 | token[0xce] = uint32;
|
123 | token[0xcf] = uint64;
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | token[0xd0] = int8;
|
130 | token[0xd1] = int16;
|
131 | token[0xd2] = int32;
|
132 | token[0xd3] = int64;
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | token[0xd4] = fix(1, ext);
|
140 | token[0xd5] = fix(2, ext);
|
141 | token[0xd6] = fix(4, ext);
|
142 | token[0xd7] = fix(8, ext);
|
143 | token[0xd8] = fix(16, ext);
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | token[0xd9] = flex(uint8, str);
|
153 | token[0xda] = flex(uint16, str);
|
154 | token[0xdb] = flex(uint32, str);
|
155 | token[0xdc] = flex(uint16, array);
|
156 | token[0xdd] = flex(uint32, array);
|
157 | token[0xde] = flex(uint16, map);
|
158 | token[0xdf] = flex(uint32, map);
|
159 |
|
160 |
|
161 | for (i = 0xe0; i <= 0xff; i++) {
|
162 | token[i] = constant(i - 0x100);
|
163 | }
|
164 | }
|
165 |
|
166 | function decode(decoder) {
|
167 | var type = uint8(decoder);
|
168 | if (type === BUFFER_SHORTAGE) return type;
|
169 | var func = token[type];
|
170 | if (!func) throw new Error("Invalid MessagePack token: 0x" + (type.toString(16)));
|
171 | return func(decoder);
|
172 | }
|
173 |
|
174 | function constant(value) {
|
175 | return function(decoder) {
|
176 | return value;
|
177 | };
|
178 | }
|
179 |
|
180 | function flex(lenFunc, decodeFunc) {
|
181 | return function(decoder) {
|
182 | var len = lenFunc(decoder);
|
183 | return decodeFunc(decoder, len);
|
184 | };
|
185 | }
|
186 |
|
187 | function fix(len, method) {
|
188 | return function(decoder) {
|
189 | return method(decoder, len);
|
190 | };
|
191 | }
|
192 |
|
193 | function map(decoder, len) {
|
194 | var value = {};
|
195 | for (var i = 0; i < len; i++) {
|
196 | var key = decode(decoder);
|
197 | value[key] = decode(decoder);
|
198 | }
|
199 | return value;
|
200 | }
|
201 |
|
202 | function array(decoder, len) {
|
203 | var value = new Array(len);
|
204 | for (var i = 0; i < len; i++) {
|
205 | value[i] = decode(decoder);
|
206 | }
|
207 | return value;
|
208 | }
|
209 |
|
210 | function str(decoder, len) {
|
211 | var start = decoder.offset;
|
212 | var end = start + len;
|
213 | if (end > decoder.bufferLength) return BUFFER_SHORTAGE;
|
214 | decoder.offset = end;
|
215 |
|
216 | if (IS_BUFFER_SHIM) {
|
217 |
|
218 | return BufferLite.readString.call(decoder.buffer, start, end);
|
219 | } else {
|
220 |
|
221 | return decoder.buffer.toString("utf-8", start, end);
|
222 | }
|
223 | }
|
224 |
|
225 | function read(len, method) {
|
226 | return function(decoder) {
|
227 | var start = decoder.offset;
|
228 | var end = start + len;
|
229 | if (end > decoder.bufferLength) return BUFFER_SHORTAGE;
|
230 | var value = method.call(decoder.buffer, start, NO_ASSERT);
|
231 | decoder.offset = end;
|
232 | return value;
|
233 | };
|
234 | }
|
235 |
|
236 | function readUInt64BE(start, noAssert) {
|
237 | var upper = this.readUInt32BE(start, noAssert);
|
238 | var lower = this.readUInt32BE(start + 4, noAssert);
|
239 | return upper ? (upper * 4294967296 + lower) : lower;
|
240 | }
|
241 |
|
242 | function readInt64BE(start, noAssert) {
|
243 | var upper = this.readInt32BE(start, noAssert);
|
244 | var lower = this.readUInt32BE(start + 4, noAssert);
|
245 | return upper ? (upper * 4294967296 + lower) : lower;
|
246 | }
|
247 |
|
248 | function bin(decoder, len) {
|
249 | var start = decoder.offset;
|
250 | var end = start + len;
|
251 | if (end > decoder.bufferLength) return BUFFER_SHORTAGE;
|
252 | var buf = decoder.buffer.slice(start, end);
|
253 | decoder.offset = end;
|
254 | return buf;
|
255 | }
|
256 |
|
257 | function ext(decoder, len) {
|
258 | var start = decoder.offset;
|
259 | var end = start + len + 1;
|
260 | if (end > decoder.bufferLength) return BUFFER_SHORTAGE;
|
261 | var type = decoder.buffer[start];
|
262 | decoder.offset = end;
|
263 |
|
264 | var e = extdecoders[type];
|
265 | if (e) {
|
266 | var buf = decoder.buffer.slice(start + 1, end);
|
267 | return e.decode(buf);
|
268 | }
|
269 |
|
270 | return decoder.buffer.slice(start, end);
|
271 | }
|
272 |
|
273 | function BUFFER_SHORTAGE() {
|
274 | } |
\ | No newline at end of file |