Line data Source code
1 : /*
2 : * Package : Cbor
3 : * Author : S. Hamblett <steve.hamblett@linux.com>
4 : * Date : 12/12/2016
5 : * Copyright : S.Hamblett
6 : */
7 :
8 : part of cbor;
9 :
10 : /// Decoder states
11 : enum DecoderState {
12 : type,
13 : pint,
14 : nint,
15 : bytesSize,
16 : bytesData,
17 : stringSize,
18 : stringData,
19 : array,
20 : map,
21 : tag,
22 : special,
23 : error
24 : }
25 :
26 : /// Length constants
27 : const int oneByte = 1;
28 : const int twoByte = 2;
29 : const int fourByte = 4;
30 : const int eightByte = 8;
31 :
32 : /// The decoder class implements the CBOR decoder functionality as defined in
33 : /// RFC7049. Output from the decoding process is through the Listener class interface.
34 : /// Different listener classes can be supplied for different purposes, such as test,
35 : /// debug as well as the standard stack listener.
36 : class Decoder {
37 : Listener _listener;
38 : Input _input;
39 : DecoderState _state;
40 : int _currentLength;
41 :
42 0 : Decoder(Input input) {
43 0 : _input = input;
44 0 : _state = DecoderState.type;
45 : }
46 :
47 3 : Decoder.withListener(Input input, Listener listener) {
48 3 : _input = input;
49 3 : _state = DecoderState.type;
50 3 : _listener = listener;
51 : }
52 :
53 : /// Decoder entry point.
54 : void run() {
55 : int temp;
56 : final bool run = true;
57 : while (run) {
58 6 : if (_state == DecoderState.type) {
59 6 : if (_input.hasBytes(1)) {
60 6 : final int type = _input.getByte();
61 3 : final int majorType = type >> majorTypeShift;
62 3 : final int minorType = type & minorTypeMask;
63 :
64 : switch (majorType) {
65 3 : case majorTypePint: // positive integer
66 3 : if (minorType < ai24) {
67 6 : _listener.onInteger(minorType);
68 3 : } else if (minorType == ai24) {
69 : // 1 byte
70 3 : _currentLength = oneByte;
71 3 : _state = DecoderState.pint;
72 3 : } else if (minorType == ai25) {
73 : // 2 byte
74 3 : _currentLength = twoByte;
75 3 : _state = DecoderState.pint;
76 3 : } else if (minorType == ai26) {
77 : // 4 byte
78 3 : _currentLength = fourByte;
79 3 : _state = DecoderState.pint;
80 1 : } else if (minorType == ai27) {
81 : // 8 byte
82 1 : _currentLength = eightByte;
83 1 : _state = DecoderState.pint;
84 : } else {
85 0 : _state = DecoderState.error;
86 0 : _listener.onError("Decoder::invalid positive integer type");
87 : }
88 : break;
89 3 : case majorTypeNint: // negative integer
90 3 : if (minorType < ai24) {
91 9 : _listener.onInteger(-1 - minorType);
92 3 : } else if (minorType == ai24) {
93 : // 1 byte
94 2 : _currentLength = oneByte;
95 2 : _state = DecoderState.nint;
96 3 : } else if (minorType == ai25) {
97 : // 2 byte
98 3 : _currentLength = twoByte;
99 3 : _state = DecoderState.nint;
100 2 : } else if (minorType == ai26) {
101 : // 4 byte
102 1 : _currentLength = fourByte;
103 1 : _state = DecoderState.nint;
104 1 : } else if (minorType == ai27) {
105 : // 8 byte
106 1 : _currentLength = eightByte;
107 1 : _state = DecoderState.nint;
108 : } else {
109 0 : _state = DecoderState.error;
110 0 : _listener.onError("Decoder::invalid negative integer type");
111 : }
112 : break;
113 3 : case majorTypeBytes: // bytes
114 3 : if (minorType < ai24) {
115 3 : _state = DecoderState.bytesData;
116 3 : _currentLength = minorType;
117 2 : } else if (minorType == ai24) {
118 0 : _state = DecoderState.bytesSize;
119 0 : _currentLength = oneByte;
120 2 : } else if (minorType == ai25) {
121 : // 2 byte
122 0 : _currentLength = twoByte;
123 0 : _state = DecoderState.bytesSize;
124 2 : } else if (minorType == ai26) {
125 : // 4 byte
126 0 : _currentLength = fourByte;
127 0 : _state = DecoderState.bytesSize;
128 2 : } else if (minorType == ai27) {
129 : // 8 byte
130 0 : _currentLength = eightByte;
131 0 : _state = DecoderState.bytesSize;
132 2 : } else if (minorType == aiBreak) {
133 2 : _state = DecoderState.type;
134 4 : _listener.onIndefinite("bytes");
135 : } else {
136 0 : _state = DecoderState.error;
137 0 : _listener.onError("Decoder::invalid bytes type");
138 : }
139 : break;
140 3 : case majorTypeString: // string
141 3 : if (minorType < ai24) {
142 3 : _state = DecoderState.stringData;
143 3 : _currentLength = minorType;
144 2 : } else if (minorType == ai24) {
145 0 : _state = DecoderState.stringSize;
146 0 : _currentLength = oneByte;
147 2 : } else if (minorType == ai25) {
148 : // 2 byte
149 0 : _currentLength = twoByte;
150 0 : _state = DecoderState.stringSize;
151 2 : } else if (minorType == ai26) {
152 : // 4 byte
153 0 : _currentLength = fourByte;
154 0 : _state = DecoderState.stringSize;
155 2 : } else if (minorType == ai27) {
156 : // 8 byte
157 0 : _currentLength = eightByte;
158 0 : _state = DecoderState.stringSize;
159 2 : } else if (minorType == aiBreak) {
160 2 : _state = DecoderState.type;
161 4 : _listener.onIndefinite("string");
162 : } else {
163 0 : _state = DecoderState.error;
164 0 : _listener.onError("Decoder::invalid string type");
165 : }
166 : break;
167 3 : case majorTypeArray: // array
168 3 : if (minorType < ai24) {
169 6 : _listener.onArray(minorType);
170 2 : } else if (minorType == ai24) {
171 1 : _state = DecoderState.array;
172 1 : _currentLength = oneByte;
173 2 : } else if (minorType == ai25) {
174 : // 2 byte
175 0 : _currentLength = twoByte;
176 0 : _state = DecoderState.array;
177 2 : } else if (minorType == ai26) {
178 : // 4 byte
179 0 : _currentLength = fourByte;
180 0 : _state = DecoderState.array;
181 2 : } else if (minorType == ai27) {
182 : // 8 byte
183 0 : _currentLength = eightByte;
184 0 : _state = DecoderState.array;
185 2 : } else if (minorType == aiBreak) {
186 2 : _state = DecoderState.type;
187 4 : _listener.onIndefinite("array");
188 : } else {
189 0 : _state = DecoderState.error;
190 0 : _listener.onError("Decoder::invalid array type");
191 : }
192 : break;
193 3 : case majorTypeMap: // map
194 3 : if (minorType < ai24) {
195 6 : _listener.onMap(minorType);
196 2 : } else if (minorType == ai24) {
197 0 : _state = DecoderState.map;
198 0 : _currentLength = oneByte;
199 2 : } else if (minorType == ai25) {
200 : // 2 byte
201 0 : _currentLength = twoByte;
202 0 : _state = DecoderState.map;
203 2 : } else if (minorType == ai26) {
204 : // 4 byte
205 0 : _currentLength = fourByte;
206 0 : _state = DecoderState.map;
207 2 : } else if (minorType == ai27) {
208 : // 8 byte
209 0 : _currentLength = eightByte;
210 0 : _state = DecoderState.map;
211 2 : } else if (minorType == aiBreak) {
212 2 : _state = DecoderState.type;
213 4 : _listener.onIndefinite("map");
214 : } else {
215 0 : _state = DecoderState.error;
216 0 : _listener.onError("Decoder::invalid map type");
217 : }
218 : break;
219 3 : case majorTypeTag: // tag
220 3 : if (minorType < ai24) {
221 6 : _listener.onTag(minorType);
222 3 : } else if (minorType == ai24) {
223 3 : _state = DecoderState.tag;
224 3 : _currentLength = oneByte;
225 1 : } else if (minorType == ai25) {
226 : // 2 byte
227 1 : _currentLength = twoByte;
228 1 : _state = DecoderState.tag;
229 0 : } else if (minorType == ai26) {
230 : // 4 byte
231 0 : _currentLength = fourByte;
232 0 : _state = DecoderState.tag;
233 0 : } else if (minorType == ai27) {
234 : // 8 byte
235 0 : _currentLength = eightByte;
236 0 : _state = DecoderState.tag;
237 : } else {
238 0 : _state = DecoderState.error;
239 0 : _listener.onError("Decoder::invalid tag type");
240 : }
241 : break;
242 3 : case majorTypeSpecial: // special
243 3 : if (minorType < ai20) {
244 6 : _listener.onSpecial(minorType);
245 3 : } else if (minorType == ai20) {
246 6 : _listener.onBool(false);
247 3 : } else if (minorType == ai21) {
248 6 : _listener.onBool(true);
249 3 : } else if (minorType == ai22) {
250 6 : _listener.onNull();
251 3 : } else if (minorType == ai23) {
252 6 : _listener.onUndefined();
253 3 : } else if (minorType == ai24) {
254 1 : _state = DecoderState.special;
255 1 : _currentLength = oneByte;
256 3 : } else if (minorType == ai25) {
257 : // 2 byte
258 3 : _currentLength = twoByte;
259 3 : _state = DecoderState.special;
260 3 : } else if (minorType == ai26) {
261 : // 4 byte
262 3 : _currentLength = fourByte;
263 3 : _state = DecoderState.special;
264 3 : } else if (minorType == ai27) {
265 : // 8 byte
266 3 : _currentLength = eightByte;
267 3 : _state = DecoderState.special;
268 2 : } else if (minorType == aiBreak) {
269 2 : _state = DecoderState.type;
270 4 : _listener.onIndefinite("stop");
271 : } else {
272 1 : _state = DecoderState.error;
273 2 : _listener.onError("Decoder::invalid special type");
274 : }
275 : break;
276 : }
277 : } else
278 : break;
279 6 : } else if (_state == DecoderState.pint) {
280 9 : if (_input.hasBytes(_currentLength)) {
281 3 : switch (_currentLength) {
282 3 : case 1:
283 12 : _listener.onInteger(_input.getByte());
284 3 : _state = DecoderState.type;
285 : break;
286 3 : case 2:
287 12 : _listener.onInteger(_input.getShort());
288 3 : _state = DecoderState.type;
289 : break;
290 3 : case 4:
291 6 : temp = _input.getInt();
292 6 : if (temp <= two32) {
293 6 : _listener.onInteger(temp);
294 : } else {
295 0 : _listener.onExtraInteger(temp, 1);
296 : }
297 3 : _state = DecoderState.type;
298 : break;
299 1 : case 8:
300 4 : _listener.onExtraInteger(_input.getLong(), 1);
301 1 : _state = DecoderState.type;
302 : break;
303 : }
304 : } else
305 : break;
306 6 : } else if (_state == DecoderState.nint) {
307 9 : if (_input.hasBytes(_currentLength)) {
308 3 : switch (_currentLength) {
309 3 : case 1:
310 10 : _listener.onInteger(-1 - _input.getByte());
311 2 : _state = DecoderState.type;
312 : break;
313 3 : case 2:
314 15 : _listener.onInteger(-1 - _input.getShort());
315 3 : _state = DecoderState.type;
316 : break;
317 2 : case 4:
318 2 : temp = _input.getInt();
319 2 : if (temp <= two32) {
320 3 : _listener.onInteger(-1 - temp);
321 0 : } else if (temp == two32 + 1) {
322 0 : _listener.onInteger(-two32 - 1);
323 : } else {
324 0 : _listener.onExtraInteger((-1 - temp), -1);
325 : }
326 1 : _state = DecoderState.type;
327 : break;
328 1 : case 8:
329 5 : _listener.onExtraInteger((-1 - _input.getLong()), -1);
330 1 : _state = DecoderState.type;
331 : break;
332 : }
333 : } else
334 : break;
335 6 : } else if (_state == DecoderState.bytesSize) {
336 0 : if (_input.hasBytes(_currentLength)) {
337 0 : switch (_currentLength) {
338 0 : case 1:
339 0 : _currentLength = _input.getByte();
340 0 : _state = DecoderState.bytesData;
341 : break;
342 0 : case 2:
343 0 : _currentLength = _input.getShort();
344 0 : _state = DecoderState.bytesData;
345 : break;
346 0 : case 4:
347 0 : _currentLength = _input.getInt();
348 0 : _state = DecoderState.bytesData;
349 : break;
350 0 : case 8:
351 0 : _state = DecoderState.error;
352 0 : _listener.onError("Decoder::extra long bytes");
353 : break;
354 : }
355 : } else
356 : break;
357 6 : } else if (_state == DecoderState.bytesData) {
358 9 : if (_input.hasBytes(_currentLength)) {
359 : typed.Uint8Buffer data;
360 9 : data = _input.getBytes(_currentLength);
361 3 : _state = DecoderState.type;
362 9 : _listener.onBytes(data, _currentLength);
363 : } else
364 : break;
365 6 : } else if (_state == DecoderState.stringSize) {
366 0 : if (_input.hasBytes(_currentLength)) {
367 0 : switch (_currentLength) {
368 0 : case 1:
369 0 : _currentLength = _input.getByte();
370 0 : _state = DecoderState.stringData;
371 : break;
372 0 : case 2:
373 0 : _currentLength = _input.getShort();
374 0 : _state = DecoderState.stringData;
375 : break;
376 0 : case 4:
377 0 : _currentLength = _input.getInt();
378 0 : _state = DecoderState.stringData;
379 : break;
380 0 : case 8:
381 0 : _state = DecoderState.error;
382 0 : _listener.onError("Decoder::extra long array");
383 : break;
384 : }
385 : } else
386 : break;
387 6 : } else if (_state == DecoderState.stringData) {
388 9 : if (_input.hasBytes(_currentLength)) {
389 : typed.Uint8Buffer data;
390 9 : data = _input.getBytes(_currentLength);
391 3 : final convertor.Utf8Decoder decoder = new convertor.Utf8Decoder();
392 3 : final String tmp = decoder.convert(data);
393 6 : _listener.onString(tmp);
394 3 : _state = DecoderState.type;
395 : } else
396 : break;
397 6 : } else if (_state == DecoderState.array) {
398 3 : if (_input.hasBytes(_currentLength)) {
399 1 : switch (_currentLength) {
400 1 : case 1:
401 4 : _listener.onArray(_input.getByte());
402 1 : _state = DecoderState.type;
403 : break;
404 0 : case 2:
405 0 : _listener.onArray(_input.getShort());
406 0 : _state = DecoderState.type;
407 : break;
408 0 : case 4:
409 0 : _listener.onArray(_input.getInt());
410 0 : _state = DecoderState.type;
411 : break;
412 0 : case 8:
413 0 : _state = DecoderState.error;
414 0 : _listener.onError("Decoder::extra long array");
415 : break;
416 : }
417 : } else
418 : break;
419 6 : } else if (_state == DecoderState.map) {
420 0 : if (_input.hasBytes(_currentLength)) {
421 0 : switch (_currentLength) {
422 0 : case 1:
423 0 : _listener.onMap(_input.getByte());
424 0 : _state = DecoderState.type;
425 : break;
426 0 : case 2:
427 0 : _listener.onMap(_currentLength = _input.getShort());
428 0 : _state = DecoderState.type;
429 : break;
430 0 : case 4:
431 0 : _listener.onMap(_input.getInt());
432 0 : _state = DecoderState.type;
433 : break;
434 0 : case 8:
435 0 : _state = DecoderState.error;
436 0 : _listener.onError("Decoder::extra long map");
437 : break;
438 : }
439 : } else
440 : break;
441 6 : } else if (_state == DecoderState.tag) {
442 9 : if (_input.hasBytes(_currentLength)) {
443 3 : switch (_currentLength) {
444 3 : case 1:
445 12 : _listener.onTag(_input.getByte());
446 3 : _state = DecoderState.type;
447 : break;
448 1 : case 2:
449 4 : _listener.onTag(_input.getShort());
450 1 : _state = DecoderState.type;
451 : break;
452 0 : case 4:
453 0 : _listener.onTag(_input.getInt());
454 0 : _state = DecoderState.type;
455 : break;
456 0 : case 8:
457 0 : _listener.onExtraTag(_input.getLong());
458 0 : _state = DecoderState.type;
459 : break;
460 : }
461 : } else
462 : break;
463 6 : } else if (_state == DecoderState.special) {
464 9 : if (_input.hasBytes(_currentLength)) {
465 3 : switch (_currentLength) {
466 3 : case 1:
467 4 : _listener.onSpecial(_input.getByte());
468 1 : _state = DecoderState.type;
469 : break;
470 3 : case 2:
471 6 : final int val = _input.getShort();
472 6 : final double fval = _input.getHalfFloat(val);
473 6 : _listener.onSpecialFloat(fval);
474 3 : _state = DecoderState.type;
475 : break;
476 3 : case 4:
477 9 : final typed.Uint8Buffer buff = _input.getBytes(_currentLength);
478 6 : final double fval = _input.getSingleFloat(buff);
479 6 : _listener.onSpecialFloat(fval);
480 3 : _state = DecoderState.type;
481 : break;
482 3 : case 8:
483 9 : final typed.Uint8Buffer buff = _input.getBytes(_currentLength);
484 6 : final double fval = _input.getDoubleFloat(buff);
485 6 : _listener.onSpecialFloat(fval);
486 3 : _state = DecoderState.type;
487 : break;
488 : }
489 : } else
490 : break;
491 2 : } else if (_state == DecoderState.error) {
492 2 : _listener.onError("Decoder::general error");
493 : break;
494 : } else {
495 0 : _listener.onError("Decoder::unknown state");
496 : }
497 : }
498 : }
499 :
500 : /// Set a listener.
501 : void setListener(Listener listenerInstance) {
502 2 : _listener = listenerInstance;
503 : }
504 : }
|