Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/utils/cborutil.py @ 39438:aeb551a3bb8a
cborutil: implement sans I/O decoder
The vendored CBOR package decodes by calling read(n) on an object.
There are a number of disadvantages to this:
* Uses blocking I/O. If sufficient data is not available, the decoder
will hang until it is.
* No support for partial reads. If the read(n) returns less data than
requested, the decoder raises an error.
* Requires the use of a file like object. If the original data is in
say a buffer, we need to "cast" it to e.g. a BytesIO to appease the
decoder.
In addition, the vendored CBOR decoder doesn't provide flexibility
that we desire. Specifically:
* It buffers indefinite length bytestrings instead of streaming them.
* It doesn't allow limiting the set of types that can be decoded. This
property is useful when implementing a "hardened" decoder that is
less susceptible to abusive input.
* It doesn't provide sufficient "hook points" and introspection to
institute checks around behavior. These are useful for implementing
a "hardened" decoder.
This all adds up to a reasonable set of justifications for writing our
own decoder.
So, this commit implements our own CBOR decoder.
At the heart of the decoder is a function that decodes a single "item"
from a buffer. This item can be a complete simple value or a special
value, such as "start of array." Using this function, we can build a
decoder that effectively iterates over the stream of decoded items and
builds up higher-level values, such as arrays, maps, sets, and indefinite
length bytestrings. And we can do this without performing I/O in the
decoder itself.
The core of the sans I/O decoder will probably not be used directly.
Instead, it is expected that we'll build utility functions for invoking
the decoder given specific input types. This will allow extreme
flexibility in how data is delivered to the decoder.
I'm pretty happy with the state of the decoder modulo the TODO items
to track wanted features to help with a "hardened" decoder. The one
thing I could be convinced to change is the handling of semantic tags.
Since we only support a single semantic tag (sets), I thought it would
be easier to handle them inline in decodeitem(). This is simpler now.
But if we add support for other semantic tags, it will likely be easier
to move semantic tag handling outside of decodeitem(). But, properly
supporting semantic tags opens up a whole can of worms, as many
semantic tags imply new types. I'm optimistic we won't need these in
Mercurial. But who knows.
I'm also pretty happy with the test coverage. Writing comprehensive
tests for partial decoding did flush out a handful of bugs. One
general improvement to testing would be fuzz testing for partial
decoding. I may implement that later. I also anticipate switching the
wire protocol code to this new decoder will flush out any lingering
bugs.
Differential Revision: https://phab.mercurial-scm.org/D4414
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 28 Aug 2018 15:02:48 -0700 |
parents | 2ae6a3134362 |
children | a40d3da89b7d |
rev | line source |
---|---|
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 # cborutil.py - CBOR extensions |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 # |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 # |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 from __future__ import absolute_import |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
10 import struct |
39438
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
11 import sys |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 from ..thirdparty.cbor.cbor2 import ( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 decoder as decodermod, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 ) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
16 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 # Very short very of RFC 7049... |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 # |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 # Each item begins with a byte. The 3 high bits of that byte denote the |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 # "major type." The lower 5 bits denote the "subtype." Each major type |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 # has its own encoding mechanism. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 # |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 # Most types have lengths. However, bytestring, string, array, and map |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
24 # can be indefinite length. These are denotes by a subtype with value 31. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
25 # Sub-components of those types then come afterwards and are terminated |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 # by a "break" byte. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
27 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 MAJOR_TYPE_UINT = 0 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
29 MAJOR_TYPE_NEGINT = 1 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 MAJOR_TYPE_BYTESTRING = 2 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 MAJOR_TYPE_STRING = 3 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 MAJOR_TYPE_ARRAY = 4 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 MAJOR_TYPE_MAP = 5 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 MAJOR_TYPE_SEMANTIC = 6 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 MAJOR_TYPE_SPECIAL = 7 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
36 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
37 SUBTYPE_MASK = 0b00011111 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 |
39438
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
39 SUBTYPE_FALSE = 20 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
40 SUBTYPE_TRUE = 21 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
41 SUBTYPE_NULL = 22 |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 SUBTYPE_HALF_FLOAT = 25 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 SUBTYPE_SINGLE_FLOAT = 26 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
44 SUBTYPE_DOUBLE_FLOAT = 27 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
45 SUBTYPE_INDEFINITE = 31 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
46 |
39438
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
47 SEMANTIC_TAG_FINITE_SET = 258 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
48 |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 # Indefinite types begin with their major type ORd with information value 31. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
50 BEGIN_INDEFINITE_BYTESTRING = struct.pack( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
51 r'>B', MAJOR_TYPE_BYTESTRING << 5 | SUBTYPE_INDEFINITE) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
52 BEGIN_INDEFINITE_ARRAY = struct.pack( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 r'>B', MAJOR_TYPE_ARRAY << 5 | SUBTYPE_INDEFINITE) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 BEGIN_INDEFINITE_MAP = struct.pack( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
55 r'>B', MAJOR_TYPE_MAP << 5 | SUBTYPE_INDEFINITE) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
56 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 ENCODED_LENGTH_1 = struct.Struct(r'>B') |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 ENCODED_LENGTH_2 = struct.Struct(r'>BB') |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 ENCODED_LENGTH_3 = struct.Struct(r'>BH') |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 ENCODED_LENGTH_4 = struct.Struct(r'>BL') |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
61 ENCODED_LENGTH_5 = struct.Struct(r'>BQ') |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
62 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 # The break ends an indefinite length item. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 BREAK = b'\xff' |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 BREAK_INT = 255 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 def encodelength(majortype, length): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 """Obtain a value encoding the major type and its length.""" |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 if length < 24: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 return ENCODED_LENGTH_1.pack(majortype << 5 | length) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 elif length < 256: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 return ENCODED_LENGTH_2.pack(majortype << 5 | 24, length) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 elif length < 65536: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 return ENCODED_LENGTH_3.pack(majortype << 5 | 25, length) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
75 elif length < 4294967296: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
76 return ENCODED_LENGTH_4.pack(majortype << 5 | 26, length) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
77 else: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
78 return ENCODED_LENGTH_5.pack(majortype << 5 | 27, length) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
79 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
80 def streamencodebytestring(v): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 yield encodelength(MAJOR_TYPE_BYTESTRING, len(v)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 yield v |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 def streamencodebytestringfromiter(it): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 """Convert an iterator of chunks to an indefinite bytestring. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
87 Given an input that is iterable and each element in the iterator is |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 representable as bytes, emit an indefinite length bytestring. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 """ |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 yield BEGIN_INDEFINITE_BYTESTRING |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 for chunk in it: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 yield encodelength(MAJOR_TYPE_BYTESTRING, len(chunk)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 yield BREAK |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 def streamencodeindefinitebytestring(source, chunksize=65536): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
99 """Given a large source buffer, emit as an indefinite length bytestring. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
100 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
101 This is a generator of chunks constituting the encoded CBOR data. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 """ |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 yield BEGIN_INDEFINITE_BYTESTRING |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
105 i = 0 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
106 l = len(source) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
107 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
108 while True: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
109 chunk = source[i:i + chunksize] |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
110 i += len(chunk) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
111 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
112 yield encodelength(MAJOR_TYPE_BYTESTRING, len(chunk)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
113 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
114 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
115 if i >= l: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 break |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
117 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
118 yield BREAK |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
119 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
120 def streamencodeint(v): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
121 if v >= 18446744073709551616 or v < -18446744073709551616: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
122 raise ValueError('big integers not supported') |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
123 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
124 if v >= 0: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
125 yield encodelength(MAJOR_TYPE_UINT, v) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
126 else: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
127 yield encodelength(MAJOR_TYPE_NEGINT, abs(v) - 1) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
128 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
129 def streamencodearray(l): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
130 """Encode a known size iterable to an array.""" |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
131 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
132 yield encodelength(MAJOR_TYPE_ARRAY, len(l)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
133 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
134 for i in l: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
135 for chunk in streamencode(i): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
136 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
137 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
138 def streamencodearrayfromiter(it): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
139 """Encode an iterator of items to an indefinite length array.""" |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
140 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
141 yield BEGIN_INDEFINITE_ARRAY |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
142 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
143 for i in it: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
144 for chunk in streamencode(i): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
145 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
146 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
147 yield BREAK |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
148 |
37942
2ae6a3134362
cborutil: port to Python 3
Augie Fackler <augie@google.com>
parents:
37711
diff
changeset
|
149 def _mixedtypesortkey(v): |
2ae6a3134362
cborutil: port to Python 3
Augie Fackler <augie@google.com>
parents:
37711
diff
changeset
|
150 return type(v).__name__, v |
2ae6a3134362
cborutil: port to Python 3
Augie Fackler <augie@google.com>
parents:
37711
diff
changeset
|
151 |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
152 def streamencodeset(s): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
153 # https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml defines |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
154 # semantic tag 258 for finite sets. |
39438
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
155 yield encodelength(MAJOR_TYPE_SEMANTIC, SEMANTIC_TAG_FINITE_SET) |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
156 |
37942
2ae6a3134362
cborutil: port to Python 3
Augie Fackler <augie@google.com>
parents:
37711
diff
changeset
|
157 for chunk in streamencodearray(sorted(s, key=_mixedtypesortkey)): |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
158 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
159 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
160 def streamencodemap(d): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
161 """Encode dictionary to a generator. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
162 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
163 Does not supporting indefinite length dictionaries. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
164 """ |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
165 yield encodelength(MAJOR_TYPE_MAP, len(d)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
166 |
37942
2ae6a3134362
cborutil: port to Python 3
Augie Fackler <augie@google.com>
parents:
37711
diff
changeset
|
167 for key, value in sorted(d.iteritems(), |
2ae6a3134362
cborutil: port to Python 3
Augie Fackler <augie@google.com>
parents:
37711
diff
changeset
|
168 key=lambda x: _mixedtypesortkey(x[0])): |
37711
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
169 for chunk in streamencode(key): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
170 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
171 for chunk in streamencode(value): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
172 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
173 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
174 def streamencodemapfromiter(it): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
175 """Given an iterable of (key, value), encode to an indefinite length map.""" |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
176 yield BEGIN_INDEFINITE_MAP |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
177 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
178 for key, value in it: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
179 for chunk in streamencode(key): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
180 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
181 for chunk in streamencode(value): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
182 yield chunk |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
183 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
184 yield BREAK |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
185 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
186 def streamencodebool(b): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
187 # major type 7, simple value 20 and 21. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
188 yield b'\xf5' if b else b'\xf4' |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
189 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
190 def streamencodenone(v): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
191 # major type 7, simple value 22. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
192 yield b'\xf6' |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
193 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
194 STREAM_ENCODERS = { |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
195 bytes: streamencodebytestring, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
196 int: streamencodeint, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
197 list: streamencodearray, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
198 tuple: streamencodearray, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
199 dict: streamencodemap, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
200 set: streamencodeset, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
201 bool: streamencodebool, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
202 type(None): streamencodenone, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
203 } |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
204 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
205 def streamencode(v): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
206 """Encode a value in a streaming manner. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
207 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
208 Given an input object, encode it to CBOR recursively. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
209 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
210 Returns a generator of CBOR encoded bytes. There is no guarantee |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
211 that each emitted chunk fully decodes to a value or sub-value. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
212 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
213 Encoding is deterministic - unordered collections are sorted. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
214 """ |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
215 fn = STREAM_ENCODERS.get(v.__class__) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
216 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
217 if not fn: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
218 raise ValueError('do not know how to encode %s' % type(v)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
219 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
220 return fn(v) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
221 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
222 def readindefinitebytestringtoiter(fh, expectheader=True): |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
223 """Read an indefinite bytestring to a generator. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
224 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
225 Receives an object with a ``read(X)`` method to read N bytes. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
226 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
227 If ``expectheader`` is True, it is expected that the first byte read |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
228 will represent an indefinite length bytestring. Otherwise, we |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
229 expect the first byte to be part of the first bytestring chunk. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
230 """ |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
231 read = fh.read |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
232 decodeuint = decodermod.decode_uint |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
233 byteasinteger = decodermod.byte_as_integer |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
234 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
235 if expectheader: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
236 initial = decodermod.byte_as_integer(read(1)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
237 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
238 majortype = initial >> 5 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
239 subtype = initial & SUBTYPE_MASK |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
240 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
241 if majortype != MAJOR_TYPE_BYTESTRING: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
242 raise decodermod.CBORDecodeError( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
243 'expected major type %d; got %d' % (MAJOR_TYPE_BYTESTRING, |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
244 majortype)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
245 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
246 if subtype != SUBTYPE_INDEFINITE: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
247 raise decodermod.CBORDecodeError( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
248 'expected indefinite subtype; got %d' % subtype) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
250 # The indefinite bytestring is composed of chunks of normal bytestrings. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
251 # Read chunks until we hit a BREAK byte. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
252 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
253 while True: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
254 # We need to sniff for the BREAK byte. |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
255 initial = byteasinteger(read(1)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
256 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
257 if initial == BREAK_INT: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
258 break |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
259 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
260 length = decodeuint(fh, initial & SUBTYPE_MASK) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
261 chunk = read(length) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
262 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
263 if len(chunk) != length: |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
264 raise decodermod.CBORDecodeError( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
265 'failed to read bytestring chunk: got %d bytes; expected %d' % ( |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
266 len(chunk), length)) |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
267 |
65a23cc8e75b
cborutil: implement support for streaming encoding, bytestring decoding
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
268 yield chunk |
39438
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
269 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
270 class CBORDecodeError(Exception): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
271 """Represents an error decoding CBOR.""" |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
272 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
273 if sys.version_info.major >= 3: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
274 def _elementtointeger(b, i): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
275 return b[i] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
276 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
277 def _elementtointeger(b, i): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
278 return ord(b[i]) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
279 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
280 STRUCT_BIG_UBYTE = struct.Struct(r'>B') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
281 STRUCT_BIG_USHORT = struct.Struct('>H') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
282 STRUCT_BIG_ULONG = struct.Struct('>L') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
283 STRUCT_BIG_ULONGLONG = struct.Struct('>Q') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
284 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
285 SPECIAL_NONE = 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
286 SPECIAL_START_INDEFINITE_BYTESTRING = 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
287 SPECIAL_START_ARRAY = 2 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
288 SPECIAL_START_MAP = 3 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
289 SPECIAL_START_SET = 4 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
290 SPECIAL_INDEFINITE_BREAK = 5 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
291 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
292 def decodeitem(b, offset=0): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
293 """Decode a new CBOR value from a buffer at offset. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
294 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
295 This function attempts to decode up to one complete CBOR value |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
296 from ``b`` starting at offset ``offset``. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
297 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
298 The beginning of a collection (such as an array, map, set, or |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
299 indefinite length bytestring) counts as a single value. For these |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
300 special cases, a state flag will indicate that a special value was seen. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
301 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
302 When called, the function either returns a decoded value or gives |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
303 a hint as to how many more bytes are needed to do so. By calling |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
304 the function repeatedly given a stream of bytes, the caller can |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
305 build up the original values. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
306 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
307 Returns a tuple with the following elements: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
308 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
309 * Bool indicating whether a complete value was decoded. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
310 * A decoded value if first value is True otherwise None |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
311 * Integer number of bytes. If positive, the number of bytes |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
312 read. If negative, the number of bytes we need to read to |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
313 decode this value or the next chunk in this value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
314 * One of the ``SPECIAL_*`` constants indicating special treatment |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
315 for this value. ``SPECIAL_NONE`` means this is a fully decoded |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
316 simple value (such as an integer or bool). |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
317 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
318 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
319 initial = _elementtointeger(b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
320 offset += 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
321 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
322 majortype = initial >> 5 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
323 subtype = initial & SUBTYPE_MASK |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
324 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
325 if majortype == MAJOR_TYPE_UINT: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
326 complete, value, readcount = decodeuint(subtype, b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
327 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
328 if complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
329 return True, value, readcount + 1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
330 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
331 return False, None, readcount, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
332 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
333 elif majortype == MAJOR_TYPE_NEGINT: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
334 # Negative integers are the same as UINT except inverted minus 1. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
335 complete, value, readcount = decodeuint(subtype, b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
336 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
337 if complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
338 return True, -value - 1, readcount + 1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
339 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
340 return False, None, readcount, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
341 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
342 elif majortype == MAJOR_TYPE_BYTESTRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
343 # Beginning of bytestrings are treated as uints in order to |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
344 # decode their length, which may be indefinite. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
345 complete, size, readcount = decodeuint(subtype, b, offset, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
346 allowindefinite=True) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
347 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
348 # We don't know the size of the bytestring. It must be a definitive |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
349 # length since the indefinite subtype would be encoded in the initial |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
350 # byte. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
351 if not complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
352 return False, None, readcount, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
353 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
354 # We know the length of the bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
355 if size is not None: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
356 # And the data is available in the buffer. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
357 if offset + readcount + size <= len(b): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
358 value = b[offset + readcount:offset + readcount + size] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
359 return True, value, readcount + size + 1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
360 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
361 # And we need more data in order to return the bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
362 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
363 wanted = len(b) - offset - readcount - size |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
364 return False, None, wanted, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
365 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
366 # It is an indefinite length bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
367 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
368 return True, None, 1, SPECIAL_START_INDEFINITE_BYTESTRING |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
369 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
370 elif majortype == MAJOR_TYPE_STRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
371 raise CBORDecodeError('string major type not supported') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
372 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
373 elif majortype == MAJOR_TYPE_ARRAY: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
374 # Beginning of arrays are treated as uints in order to decode their |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
375 # length. We don't allow indefinite length arrays. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
376 complete, size, readcount = decodeuint(subtype, b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
377 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
378 if complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
379 return True, size, readcount + 1, SPECIAL_START_ARRAY |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
380 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
381 return False, None, readcount, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
382 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
383 elif majortype == MAJOR_TYPE_MAP: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
384 # Beginning of maps are treated as uints in order to decode their |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
385 # number of elements. We don't allow indefinite length arrays. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
386 complete, size, readcount = decodeuint(subtype, b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
387 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
388 if complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
389 return True, size, readcount + 1, SPECIAL_START_MAP |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
390 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
391 return False, None, readcount, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
392 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
393 elif majortype == MAJOR_TYPE_SEMANTIC: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
394 # Semantic tag value is read the same as a uint. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
395 complete, tagvalue, readcount = decodeuint(subtype, b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
396 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
397 if not complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
398 return False, None, readcount, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
399 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
400 # This behavior here is a little wonky. The main type being "decorated" |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
401 # by this semantic tag follows. A more robust parser would probably emit |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
402 # a special flag indicating this as a semantic tag and let the caller |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
403 # deal with the types that follow. But since we don't support many |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
404 # semantic tags, it is easier to deal with the special cases here and |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
405 # hide complexity from the caller. If we add support for more semantic |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
406 # tags, we should probably move semantic tag handling into the caller. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
407 if tagvalue == SEMANTIC_TAG_FINITE_SET: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
408 if offset + readcount >= len(b): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
409 return False, None, -1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
410 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
411 complete, size, readcount2, special = decodeitem(b, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
412 offset + readcount) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
413 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
414 if not complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
415 return False, None, readcount2, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
416 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
417 if special != SPECIAL_START_ARRAY: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
418 raise CBORDecodeError('expected array after finite set ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
419 'semantic tag') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
420 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
421 return True, size, readcount + readcount2 + 1, SPECIAL_START_SET |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
422 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
423 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
424 raise CBORDecodeError('semantic tag %d not allowed' % tagvalue) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
425 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
426 elif majortype == MAJOR_TYPE_SPECIAL: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
427 # Only specific values for the information field are allowed. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
428 if subtype == SUBTYPE_FALSE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
429 return True, False, 1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
430 elif subtype == SUBTYPE_TRUE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
431 return True, True, 1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
432 elif subtype == SUBTYPE_NULL: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
433 return True, None, 1, SPECIAL_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
434 elif subtype == SUBTYPE_INDEFINITE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
435 return True, None, 1, SPECIAL_INDEFINITE_BREAK |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
436 # If value is 24, subtype is in next byte. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
437 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
438 raise CBORDecodeError('special type %d not allowed' % subtype) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
439 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
440 assert False |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
441 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
442 def decodeuint(subtype, b, offset=0, allowindefinite=False): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
443 """Decode an unsigned integer. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
444 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
445 ``subtype`` is the lower 5 bits from the initial byte CBOR item |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
446 "header." ``b`` is a buffer containing bytes. ``offset`` points to |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
447 the index of the first byte after the byte that ``subtype`` was |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
448 derived from. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
449 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
450 ``allowindefinite`` allows the special indefinite length value |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
451 indicator. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
452 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
453 Returns a 3-tuple of (successful, value, count). |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
454 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
455 The first element is a bool indicating if decoding completed. The 2nd |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
456 is the decoded integer value or None if not fully decoded or the subtype |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
457 is 31 and ``allowindefinite`` is True. The 3rd value is the count of bytes. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
458 If positive, it is the number of additional bytes decoded. If negative, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
459 it is the number of additional bytes needed to decode this value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
460 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
461 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
462 # Small values are inline. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
463 if subtype < 24: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
464 return True, subtype, 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
465 # Indefinite length specifier. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
466 elif subtype == 31: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
467 if allowindefinite: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
468 return True, None, 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
469 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
470 raise CBORDecodeError('indefinite length uint not allowed here') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
471 elif subtype >= 28: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
472 raise CBORDecodeError('unsupported subtype on integer type: %d' % |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
473 subtype) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
474 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
475 if subtype == 24: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
476 s = STRUCT_BIG_UBYTE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
477 elif subtype == 25: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
478 s = STRUCT_BIG_USHORT |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
479 elif subtype == 26: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
480 s = STRUCT_BIG_ULONG |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
481 elif subtype == 27: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
482 s = STRUCT_BIG_ULONGLONG |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
483 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
484 raise CBORDecodeError('bounds condition checking violation') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
485 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
486 if len(b) - offset >= s.size: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
487 return True, s.unpack_from(b, offset)[0], s.size |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
488 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
489 return False, None, len(b) - offset - s.size |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
490 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
491 class bytestringchunk(bytes): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
492 """Represents a chunk/segment in an indefinite length bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
493 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
494 This behaves like a ``bytes`` but in addition has the ``isfirst`` |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
495 and ``islast`` attributes indicating whether this chunk is the first |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
496 or last in an indefinite length bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
497 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
498 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
499 def __new__(cls, v, first=False, last=False): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
500 self = bytes.__new__(cls, v) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
501 self.isfirst = first |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
502 self.islast = last |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
503 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
504 return self |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
505 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
506 class sansiodecoder(object): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
507 """A CBOR decoder that doesn't perform its own I/O. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
508 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
509 To use, construct an instance and feed it segments containing |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
510 CBOR-encoded bytes via ``decode()``. The return value from ``decode()`` |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
511 indicates whether a fully-decoded value is available, how many bytes |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
512 were consumed, and offers a hint as to how many bytes should be fed |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
513 in next time to decode the next value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
514 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
515 The decoder assumes it will decode N discrete CBOR values, not just |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
516 a single value. i.e. if the bytestream contains uints packed one after |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
517 the other, the decoder will decode them all, rather than just the initial |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
518 one. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
519 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
520 When ``decode()`` indicates a value is available, call ``getavailable()`` |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
521 to return all fully decoded values. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
522 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
523 ``decode()`` can partially decode input. It is up to the caller to keep |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
524 track of what data was consumed and to pass unconsumed data in on the |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
525 next invocation. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
526 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
527 The decoder decodes atomically at the *item* level. See ``decodeitem()``. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
528 If an *item* cannot be fully decoded, the decoder won't record it as |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
529 partially consumed. Instead, the caller will be instructed to pass in |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
530 the initial bytes of this item on the next invocation. This does result |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
531 in some redundant parsing. But the overhead should be minimal. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
532 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
533 This decoder only supports a subset of CBOR as required by Mercurial. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
534 It lacks support for: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
535 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
536 * Indefinite length arrays |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
537 * Indefinite length maps |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
538 * Use of indefinite length bytestrings as keys or values within |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
539 arrays, maps, or sets. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
540 * Nested arrays, maps, or sets within sets |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
541 * Any semantic tag that isn't a mathematical finite set |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
542 * Floating point numbers |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
543 * Undefined special value |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
544 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
545 CBOR types are decoded to Python types as follows: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
546 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
547 uint -> int |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
548 negint -> int |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
549 bytestring -> bytes |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
550 map -> dict |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
551 array -> list |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
552 True -> bool |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
553 False -> bool |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
554 null -> None |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
555 indefinite length bytestring chunk -> [bytestringchunk] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
556 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
557 The only non-obvious mapping here is an indefinite length bytestring |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
558 to the ``bytestringchunk`` type. This is to facilitate streaming |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
559 indefinite length bytestrings out of the decoder and to differentiate |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
560 a regular bytestring from an indefinite length bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
561 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
562 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
563 _STATE_NONE = 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
564 _STATE_WANT_MAP_KEY = 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
565 _STATE_WANT_MAP_VALUE = 2 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
566 _STATE_WANT_ARRAY_VALUE = 3 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
567 _STATE_WANT_SET_VALUE = 4 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
568 _STATE_WANT_BYTESTRING_CHUNK_FIRST = 5 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
569 _STATE_WANT_BYTESTRING_CHUNK_SUBSEQUENT = 6 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
570 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
571 def __init__(self): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
572 # TODO add support for limiting size of bytestrings |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
573 # TODO add support for limiting number of keys / values in collections |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
574 # TODO add support for limiting size of buffered partial values |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
575 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
576 self.decodedbytecount = 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
577 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
578 self._state = self._STATE_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
579 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
580 # Stack of active nested collections. Each entry is a dict describing |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
581 # the collection. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
582 self._collectionstack = [] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
583 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
584 # Fully decoded key to use for the current map. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
585 self._currentmapkey = None |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
586 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
587 # Fully decoded values available for retrieval. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
588 self._decodedvalues = [] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
589 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
590 @property |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
591 def inprogress(self): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
592 """Whether the decoder has partially decoded a value.""" |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
593 return self._state != self._STATE_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
594 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
595 def decode(self, b, offset=0): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
596 """Attempt to decode bytes from an input buffer. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
597 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
598 ``b`` is a collection of bytes and ``offset`` is the byte |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
599 offset within that buffer from which to begin reading data. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
600 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
601 ``b`` must support ``len()`` and accessing bytes slices via |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
602 ``__slice__``. Typically ``bytes`` instances are used. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
603 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
604 Returns a tuple with the following fields: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
605 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
606 * Bool indicating whether values are available for retrieval. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
607 * Integer indicating the number of bytes that were fully consumed, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
608 starting from ``offset``. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
609 * Integer indicating the number of bytes that are desired for the |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
610 next call in order to decode an item. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
611 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
612 if not b: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
613 return bool(self._decodedvalues), 0, 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
614 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
615 initialoffset = offset |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
616 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
617 # We could easily split the body of this loop into a function. But |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
618 # Python performance is sensitive to function calls and collections |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
619 # are composed of many items. So leaving as a while loop could help |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
620 # with performance. One thing that may not help is the use of |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
621 # if..elif versus a lookup/dispatch table. There may be value |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
622 # in switching that. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
623 while offset < len(b): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
624 # Attempt to decode an item. This could be a whole value or a |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
625 # special value indicating an event, such as start or end of a |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
626 # collection or indefinite length type. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
627 complete, value, readcount, special = decodeitem(b, offset) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
628 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
629 if readcount > 0: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
630 self.decodedbytecount += readcount |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
631 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
632 if not complete: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
633 assert readcount < 0 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
634 return ( |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
635 bool(self._decodedvalues), |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
636 offset - initialoffset, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
637 -readcount, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
638 ) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
639 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
640 offset += readcount |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
641 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
642 # No nested state. We either have a full value or beginning of a |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
643 # complex value to deal with. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
644 if self._state == self._STATE_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
645 # A normal value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
646 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
647 self._decodedvalues.append(value) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
648 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
649 elif special == SPECIAL_START_ARRAY: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
650 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
651 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
652 'v': [], |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
653 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
654 self._state = self._STATE_WANT_ARRAY_VALUE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
655 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
656 elif special == SPECIAL_START_MAP: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
657 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
658 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
659 'v': {}, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
660 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
661 self._state = self._STATE_WANT_MAP_KEY |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
662 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
663 elif special == SPECIAL_START_SET: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
664 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
665 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
666 'v': set(), |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
667 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
668 self._state = self._STATE_WANT_SET_VALUE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
669 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
670 elif special == SPECIAL_START_INDEFINITE_BYTESTRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
671 self._state = self._STATE_WANT_BYTESTRING_CHUNK_FIRST |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
672 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
673 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
674 raise CBORDecodeError('unhandled special state: %d' % |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
675 special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
676 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
677 # This value becomes an element of the current array. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
678 elif self._state == self._STATE_WANT_ARRAY_VALUE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
679 # Simple values get appended. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
680 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
681 c = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
682 c['v'].append(value) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
683 c['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
684 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
685 # self._state doesn't need changed. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
686 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
687 # An array nested within an array. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
688 elif special == SPECIAL_START_ARRAY: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
689 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
690 newvalue = [] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
691 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
692 lastc['v'].append(newvalue) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
693 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
694 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
695 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
696 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
697 'v': newvalue, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
698 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
699 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
700 # self._state doesn't need changed. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
701 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
702 # A map nested within an array. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
703 elif special == SPECIAL_START_MAP: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
704 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
705 newvalue = {} |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
706 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
707 lastc['v'].append(newvalue) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
708 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
709 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
710 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
711 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
712 'v': newvalue |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
713 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
714 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
715 self._state = self._STATE_WANT_MAP_KEY |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
716 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
717 elif special == SPECIAL_START_SET: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
718 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
719 newvalue = set() |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
720 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
721 lastc['v'].append(newvalue) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
722 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
723 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
724 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
725 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
726 'v': newvalue, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
727 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
728 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
729 self._state = self._STATE_WANT_SET_VALUE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
730 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
731 elif special == SPECIAL_START_INDEFINITE_BYTESTRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
732 raise CBORDecodeError('indefinite length bytestrings ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
733 'not allowed as array values') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
734 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
735 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
736 raise CBORDecodeError('unhandled special item when ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
737 'expecting array value: %d' % special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
738 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
739 # This value becomes the key of the current map instance. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
740 elif self._state == self._STATE_WANT_MAP_KEY: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
741 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
742 self._currentmapkey = value |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
743 self._state = self._STATE_WANT_MAP_VALUE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
744 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
745 elif special == SPECIAL_START_INDEFINITE_BYTESTRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
746 raise CBORDecodeError('indefinite length bytestrings ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
747 'not allowed as map keys') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
748 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
749 elif special in (SPECIAL_START_ARRAY, SPECIAL_START_MAP, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
750 SPECIAL_START_SET): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
751 raise CBORDecodeError('collections not supported as map ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
752 'keys') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
753 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
754 # We do not allow special values to be used as map keys. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
755 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
756 raise CBORDecodeError('unhandled special item when ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
757 'expecting map key: %d' % special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
758 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
759 # This value becomes the value of the current map key. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
760 elif self._state == self._STATE_WANT_MAP_VALUE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
761 # Simple values simply get inserted into the map. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
762 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
763 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
764 lastc['v'][self._currentmapkey] = value |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
765 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
766 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
767 self._state = self._STATE_WANT_MAP_KEY |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
768 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
769 # A new array is used as the map value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
770 elif special == SPECIAL_START_ARRAY: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
771 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
772 newvalue = [] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
773 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
774 lastc['v'][self._currentmapkey] = newvalue |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
775 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
776 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
777 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
778 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
779 'v': newvalue, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
780 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
781 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
782 self._state = self._STATE_WANT_ARRAY_VALUE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
783 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
784 # A new map is used as the map value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
785 elif special == SPECIAL_START_MAP: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
786 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
787 newvalue = {} |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
788 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
789 lastc['v'][self._currentmapkey] = newvalue |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
790 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
791 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
792 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
793 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
794 'v': newvalue, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
795 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
796 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
797 self._state = self._STATE_WANT_MAP_KEY |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
798 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
799 # A new set is used as the map value. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
800 elif special == SPECIAL_START_SET: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
801 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
802 newvalue = set() |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
803 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
804 lastc['v'][self._currentmapkey] = newvalue |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
805 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
806 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
807 self._collectionstack.append({ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
808 'remaining': value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
809 'v': newvalue, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
810 }) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
811 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
812 self._state = self._STATE_WANT_SET_VALUE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
813 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
814 elif special == SPECIAL_START_INDEFINITE_BYTESTRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
815 raise CBORDecodeError('indefinite length bytestrings not ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
816 'allowed as map values') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
817 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
818 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
819 raise CBORDecodeError('unhandled special item when ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
820 'expecting map value: %d' % special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
821 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
822 self._currentmapkey = None |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
823 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
824 # This value is added to the current set. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
825 elif self._state == self._STATE_WANT_SET_VALUE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
826 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
827 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
828 lastc['v'].add(value) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
829 lastc['remaining'] -= 1 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
830 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
831 elif special == SPECIAL_START_INDEFINITE_BYTESTRING: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
832 raise CBORDecodeError('indefinite length bytestrings not ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
833 'allowed as set values') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
834 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
835 elif special in (SPECIAL_START_ARRAY, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
836 SPECIAL_START_MAP, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
837 SPECIAL_START_SET): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
838 raise CBORDecodeError('collections not allowed as set ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
839 'values') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
840 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
841 # We don't allow non-trivial types to exist as set values. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
842 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
843 raise CBORDecodeError('unhandled special item when ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
844 'expecting set value: %d' % special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
845 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
846 # This value represents the first chunk in an indefinite length |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
847 # bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
848 elif self._state == self._STATE_WANT_BYTESTRING_CHUNK_FIRST: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
849 # We received a full chunk. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
850 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
851 self._decodedvalues.append(bytestringchunk(value, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
852 first=True)) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
853 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
854 self._state = self._STATE_WANT_BYTESTRING_CHUNK_SUBSEQUENT |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
855 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
856 # The end of stream marker. This means it is an empty |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
857 # indefinite length bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
858 elif special == SPECIAL_INDEFINITE_BREAK: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
859 # We /could/ convert this to a b''. But we want to preserve |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
860 # the nature of the underlying data so consumers expecting |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
861 # an indefinite length bytestring get one. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
862 self._decodedvalues.append(bytestringchunk(b'', |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
863 first=True, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
864 last=True)) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
865 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
866 # Since indefinite length bytestrings can't be used in |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
867 # collections, we must be at the root level. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
868 assert not self._collectionstack |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
869 self._state = self._STATE_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
870 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
871 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
872 raise CBORDecodeError('unexpected special value when ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
873 'expecting bytestring chunk: %d' % |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
874 special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
875 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
876 # This value represents the non-initial chunk in an indefinite |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
877 # length bytestring. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
878 elif self._state == self._STATE_WANT_BYTESTRING_CHUNK_SUBSEQUENT: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
879 # We received a full chunk. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
880 if special == SPECIAL_NONE: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
881 self._decodedvalues.append(bytestringchunk(value)) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
882 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
883 # The end of stream marker. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
884 elif special == SPECIAL_INDEFINITE_BREAK: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
885 self._decodedvalues.append(bytestringchunk(b'', last=True)) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
886 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
887 # Since indefinite length bytestrings can't be used in |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
888 # collections, we must be at the root level. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
889 assert not self._collectionstack |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
890 self._state = self._STATE_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
891 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
892 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
893 raise CBORDecodeError('unexpected special value when ' |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
894 'expecting bytestring chunk: %d' % |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
895 special) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
896 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
897 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
898 raise CBORDecodeError('unhandled decoder state: %d' % |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
899 self._state) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
900 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
901 # We could have just added the final value in a collection. End |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
902 # all complete collections at the top of the stack. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
903 while True: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
904 # Bail if we're not waiting on a new collection item. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
905 if self._state not in (self._STATE_WANT_ARRAY_VALUE, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
906 self._STATE_WANT_MAP_KEY, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
907 self._STATE_WANT_SET_VALUE): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
908 break |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
909 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
910 # Or we are expecting more items for this collection. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
911 lastc = self._collectionstack[-1] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
912 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
913 if lastc['remaining']: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
914 break |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
915 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
916 # The collection at the top of the stack is complete. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
917 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
918 # Discard it, as it isn't needed for future items. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
919 self._collectionstack.pop() |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
920 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
921 # If this is a nested collection, we don't emit it, since it |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
922 # will be emitted by its parent collection. But we do need to |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
923 # update state to reflect what the new top-most collection |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
924 # on the stack is. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
925 if self._collectionstack: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
926 self._state = { |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
927 list: self._STATE_WANT_ARRAY_VALUE, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
928 dict: self._STATE_WANT_MAP_KEY, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
929 set: self._STATE_WANT_SET_VALUE, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
930 }[type(self._collectionstack[-1]['v'])] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
931 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
932 # If this is the root collection, emit it. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
933 else: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
934 self._decodedvalues.append(lastc['v']) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
935 self._state = self._STATE_NONE |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
936 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
937 return ( |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
938 bool(self._decodedvalues), |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
939 offset - initialoffset, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
940 0, |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
941 ) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
942 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
943 def getavailable(self): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
944 """Returns an iterator over fully decoded values. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
945 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
946 Once values are retrieved, they won't be available on the next call. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
947 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
948 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
949 l = list(self._decodedvalues) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
950 self._decodedvalues = [] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
951 return l |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
952 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
953 def decodeall(b): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
954 """Decode all CBOR items present in an iterable of bytes. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
955 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
956 In addition to regular decode errors, raises CBORDecodeError if the |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
957 entirety of the passed buffer does not fully decode to complete CBOR |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
958 values. This includes failure to decode any value, incomplete collection |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
959 types, incomplete indefinite length items, and extra data at the end of |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
960 the buffer. |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
961 """ |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
962 if not b: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
963 return [] |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
964 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
965 decoder = sansiodecoder() |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
966 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
967 havevalues, readcount, wantbytes = decoder.decode(b) |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
968 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
969 if readcount != len(b): |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
970 raise CBORDecodeError('input data not fully consumed') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
971 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
972 if decoder.inprogress: |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
973 raise CBORDecodeError('input data not complete') |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
974 |
aeb551a3bb8a
cborutil: implement sans I/O decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37942
diff
changeset
|
975 return decoder.getavailable() |