Codebase list python-cbor / 78ac43b
Merge tag 'upstream/0.1.24' Upstream version 0.1.24 Agustin Henze 8 years ago
9 changed file(s) with 149 addition(s) and 60 deletion(s). Raw diff Collapse all Expand all
00 Metadata-Version: 1.1
11 Name: cbor
2 Version: 0.1.21
2 Version: 0.1.24
33 Summary: RFC 7049 - Concise Binary Object Representation
44 Home-page: https://bitbucket.org/bodhisnarkva/cbor
55 Author: Brian Olson
2727 #define IS_PY3 1
2828
2929 #endif
30
31 typedef struct {
32 unsigned int sort_keys;
33 } EncodeOptions;
3034
3135 // Hey Look! It's a polymorphic object structure in C!
3236
994998 return;
995999 }
9961000
997 static int inner_dumps(PyObject* ob, uint8_t* out, uintptr_t* posp);
998
999 static int dumps_dict(PyObject* ob, uint8_t* out, uintptr_t* posp) {
1001 static int inner_dumps(EncodeOptions *optp, PyObject* ob, uint8_t* out, uintptr_t* posp);
1002
1003 static int dumps_dict(EncodeOptions *optp, PyObject* ob, uint8_t* out, uintptr_t* posp) {
10001004 uintptr_t pos = *posp;
1001 Py_ssize_t dictiter = 0;
1005 Py_ssize_t dictlen = PyDict_Size(ob);
10021006 PyObject* key;
10031007 PyObject* val;
1004 Py_ssize_t dictlen = PyDict_Size(ob);
10051008 int err;
1009
10061010 tag_aux_out(CBOR_MAP, dictlen, out, &pos);
1007 while (PyDict_Next(ob, &dictiter, &key, &val)) {
1008 err = inner_dumps(key, out, &pos);
1009 if (err != 0) { return err; }
1010 err = inner_dumps(val, out, &pos);
1011 if (err != 0) { return err; }
1012 }
1011
1012 if (optp->sort_keys) {
1013 Py_ssize_t index = 0;
1014 PyObject* keylist = PyDict_Keys(ob);
1015 PyList_Sort(keylist);
1016
1017 //fprintf(stderr, "sortking keys\n");
1018 for (index = 0; index < PyList_Size(keylist); index++) {
1019 key = PyList_GetItem(keylist, index); // Borrowed ref
1020 val = PyDict_GetItem(ob, key); // Borrowed ref
1021 err = inner_dumps(optp, key, out, &pos);
1022 if (err != 0) { return err; }
1023 err = inner_dumps(optp, val, out, &pos);
1024 if (err != 0) { return err; }
1025 }
1026 Py_DECREF(keylist);
1027 } else {
1028 Py_ssize_t dictiter = 0;
1029 //fprintf(stderr, "unsorted keys\n");
1030 while (PyDict_Next(ob, &dictiter, &key, &val)) {
1031 err = inner_dumps(optp, key, out, &pos);
1032 if (err != 0) { return err; }
1033 err = inner_dumps(optp, val, out, &pos);
1034 if (err != 0) { return err; }
1035 }
1036 }
1037
10131038 *posp = pos;
10141039 return 0;
10151040 }
10161041
10171042
1018 static void dumps_bignum(uint8_t tag, PyObject* val, uint8_t* out, uintptr_t* posp) {
1043 static void dumps_bignum(EncodeOptions *optp, uint8_t tag, PyObject* val, uint8_t* out, uintptr_t* posp) {
10191044 uintptr_t pos = (posp != NULL) ? *posp : 0;
10201045 PyObject* eight = PyLong_FromLong(8);
10211046 PyObject* bytemask = NULL;
10651090 *posp = pos;
10661091 }
10671092
1068 static int dumps_tag(PyObject* ob, uint8_t* out, uintptr_t* posp) {
1093 static int dumps_tag(EncodeOptions *optp, PyObject* ob, uint8_t* out, uintptr_t* posp) {
10691094 uintptr_t pos = (posp != NULL) ? *posp : 0;
10701095 int err = 0;
10711096
10831108 long val = PyInt_AsLong(tag_num);
10841109 if (val > 0) {
10851110 tag_aux_out(CBOR_TAG, val, out, &pos);
1086 err = inner_dumps(tag_value, out, &pos);
1111 err = inner_dumps(optp, tag_value, out, &pos);
10871112 } else {
10881113 PyErr_Format(PyExc_ValueError, "tag cannot be a negative int: %ld", val);
10891114 err = -1;
10961121 if (overflow == 0) {
10971122 if (val >= 0) {
10981123 tag_aux_out(CBOR_TAG, val, out, &pos);
1099 err = inner_dumps(tag_value, out, &pos);
1124 err = inner_dumps(optp, tag_value, out, &pos);
11001125 } else {
11011126 PyErr_Format(PyExc_ValueError, "tag cannot be a negative long: %lld", val);
11021127 err = -1;
11251150
11261151 // With out=NULL it just counts the length.
11271152 // return err, 0=OK
1128 static int inner_dumps(PyObject* ob, uint8_t* out, uintptr_t* posp) {
1153 static int inner_dumps(EncodeOptions *optp, PyObject* ob, uint8_t* out, uintptr_t* posp) {
11291154 uintptr_t pos = (posp != NULL) ? *posp : 0;
11301155
1131 if (PyBool_Check(ob)) {
1156 if (ob == Py_None) {
1157 if (out != NULL) {
1158 out[pos] = CBOR_NULL;
1159 }
1160 pos += 1;
1161 } else if (PyBool_Check(ob)) {
11321162 if (out != NULL) {
11331163 if (PyObject_IsTrue(ob)) {
11341164 out[pos] = CBOR_TRUE;
11371167 }
11381168 }
11391169 pos += 1;
1140 } else if (ob == Py_None) {
1141 if (out != NULL) {
1142 out[pos] = CBOR_NULL;
1143 }
1144 pos += 1;
11451170 } else if (PyDict_Check(ob)) {
1146 int err = dumps_dict(ob, out, &pos);
1171 int err = dumps_dict(optp, ob, out, &pos);
11471172 if (err != 0) { return err; }
11481173 } else if (PyList_Check(ob)) {
11491174 Py_ssize_t i;
11501175 Py_ssize_t listlen = PyList_Size(ob);
11511176 tag_aux_out(CBOR_ARRAY, listlen, out, &pos);
11521177 for (i = 0; i < listlen; i++) {
1153 int err = inner_dumps(PyList_GetItem(ob, i), out, &pos);
1178 int err = inner_dumps(optp, PyList_GetItem(ob, i), out, &pos);
11541179 if (err != 0) { return err; }
11551180 }
11561181 } else if (PyTuple_Check(ob)) {
11581183 Py_ssize_t listlen = PyTuple_Size(ob);
11591184 tag_aux_out(CBOR_ARRAY, listlen, out, &pos);
11601185 for (i = 0; i < listlen; i++) {
1161 int err = inner_dumps(PyTuple_GetItem(ob, i), out, &pos);
1186 int err = inner_dumps(optp, PyTuple_GetItem(ob, i), out, &pos);
11621187 if (err != 0) { return err; }
11631188 }
11641189 // TODO: accept other enumerables and emit a variable length array
11871212 PyObject* minusone = PyLong_FromLongLong(-1L);
11881213 PyObject* val = PyNumber_Subtract(minusone, ob);
11891214 Py_DECREF(minusone);
1190 dumps_bignum(CBOR_TAG_NEGBIGNUM, val, out, &pos);
1215 dumps_bignum(optp, CBOR_TAG_NEGBIGNUM, val, out, &pos);
11911216 Py_DECREF(val);
11921217 } else {
11931218 // BIG INT
1194 dumps_bignum(CBOR_TAG_BIGNUM, ob, out, &pos);
1219 dumps_bignum(optp, CBOR_TAG_BIGNUM, ob, out, &pos);
11951220 }
11961221 }
11971222 } else if (PyFloat_Check(ob)) {
12181243 {
12191244 PyObject* tag_class = getCborTagClass();
12201245 if (PyObject_IsInstance(ob, tag_class)) {
1221 int err = dumps_tag(ob, out, &pos);
1246 int err = dumps_tag(optp, ob, out, &pos);
12221247 if (err != 0) { return err; }
12231248 handled = 1;
12241249 }
12461271 return 0;
12471272 }
12481273
1274 static int _dumps_kwargs(EncodeOptions *optp, PyObject* kwargs) {
1275 if (kwargs == NULL) {
1276 } else if (!PyDict_Check(kwargs)) {
1277 PyErr_Format(PyExc_ValueError, "kwargs not dict: %R\n", kwargs);
1278 return 0;
1279 } else {
1280 PyObject* sort_keys = PyDict_GetItemString(kwargs, "sort_keys"); // Borrowed ref
1281 if (sort_keys != NULL) {
1282 optp->sort_keys = PyObject_IsTrue(sort_keys);
1283 //fprintf(stderr, "sort_keys=%d\n", optp->sort_keys);
1284 }
1285 }
1286 return 1;
1287 }
1288
12491289 static PyObject*
1250 cbor_dumps(PyObject* noself, PyObject* args) {
1290 cbor_dumps(PyObject* noself, PyObject* args, PyObject* kwargs) {
1291
12511292 PyObject* ob;
1293 EncodeOptions opts = {0};
1294 EncodeOptions *optp = &opts;
12521295 is_big_endian();
12531296 if (PyType_IsSubtype(Py_TYPE(args), &PyList_Type)) {
12541297 ob = PyList_GetItem(args, 0);
12571300 } else {
12581301 PyErr_Format(PyExc_ValueError, "args not list or tuple: %R\n", args);
12591302 return NULL;
1303 }
1304 if (ob == NULL) {
1305 return NULL;
1306 }
1307
1308 if (!_dumps_kwargs(optp, kwargs)) {
1309 return NULL;
12601310 }
12611311
12621312 {
12671317 int err;
12681318
12691319 // first pass just to count length
1270 err = inner_dumps(ob, NULL, &pos);
1320 err = inner_dumps(optp, ob, NULL, &pos);
12711321 if (err != 0) {
12721322 return NULL;
12731323 }
12801330 return NULL;
12811331 }
12821332
1283 err = inner_dumps(ob, out, NULL);
1333 err = inner_dumps(optp, ob, out, NULL);
12841334 if (err != 0) {
12851335 PyMem_Free(out);
12861336 return NULL;
12941344 }
12951345
12961346 static PyObject*
1297 cbor_dump(PyObject* noself, PyObject* args) {
1347 cbor_dump(PyObject* noself, PyObject* args, PyObject *kwargs) {
12981348 // args should be (obj, fp)
12991349 PyObject* ob;
13001350 PyObject* fp;
1351 EncodeOptions opts = {0};
1352 EncodeOptions *optp = &opts;
13011353
13021354 is_big_endian();
13031355 if (PyType_IsSubtype(Py_TYPE(args), &PyList_Type)) {
13101362 PyErr_Format(PyExc_ValueError, "args not list or tuple: %R\n", args);
13111363 return NULL;
13121364 }
1365 if ((ob == NULL) || (fp == NULL)) {
1366 return NULL;
1367 }
1368
1369 if (!_dumps_kwargs(optp, kwargs)) {
1370 return NULL;
1371 }
13131372
13141373 {
13151374 // TODO: make this smarter, right now it is justt fp.write(dumps(ob))
13191378 int err;
13201379
13211380 // first pass just to count length
1322 err = inner_dumps(ob, NULL, &pos);
1381 err = inner_dumps(optp, ob, NULL, &pos);
13231382 if (err != 0) {
13241383 return NULL;
13251384 }
13321391 return NULL;
13331392 }
13341393
1335 err = inner_dumps(ob, out, NULL);
1394 err = inner_dumps(optp, ob, out, NULL);
13361395 if (err != 0) {
13371396 PyMem_Free(out);
13381397 return NULL;
13761435 static PyMethodDef CborMethods[] = {
13771436 {"loads", cbor_loads, METH_VARARGS,
13781437 "parse cbor from data buffer to objects"},
1379 {"dumps", cbor_dumps, METH_VARARGS,
1438 {"dumps", (PyCFunction)cbor_dumps, METH_VARARGS|METH_KEYWORDS,
13801439 "serialize python object to bytes"},
13811440 {"load", cbor_load, METH_VARARGS,
13821441 "Parse cbor from data buffer to objects.\n"
13831442 "Takes a file-like object capable of .read(N)\n"},
1384 {"dump", cbor_dump, METH_VARARGS,
1443 {"dump", (PyCFunction)cbor_dump, METH_VARARGS|METH_KEYWORDS,
13851444 "Serialize python object to bytes.\n"
13861445 "dump(obj, fp)\n"
13871446 "obj: object to output; fp: file-like object to .write() to\n"},
0 '0.1.24'
88
99 from .cbor import Tag
1010 from .tagmap import TagMapper, ClassTag, UnknownTagException
11 from .VERSION import __doc__ as __version__
1112
1213 __all__ = [
1314 'loads', 'dumps', 'load', 'dump',
1415 'Tag',
1516 'TagMapper', 'ClassTag', 'UnknownTagException',
17 '__version__',
1618 ]
148148 return _encode_type_num(CBOR_TEXT, len(val)) + val
149149
150150
151 def dumps_array(arr):
151 def dumps_array(arr, sort_keys=False):
152152 head = _encode_type_num(CBOR_ARRAY, len(arr))
153 parts = [dumps(x) for x in arr]
153 parts = [dumps(x, sort_keys=sort_keys) for x in arr]
154154 return head + b''.join(parts)
155155
156156
157157 if _IS_PY3:
158 def dumps_dict(d):
158 def dumps_dict(d, sort_keys=False):
159159 head = _encode_type_num(CBOR_MAP, len(d))
160160 parts = [head]
161 for k,v in d.items():
162 parts.append(dumps(k))
163 parts.append(dumps(v))
161 if sort_keys:
162 for k in sorted(d.keys()):
163 v = d[k]
164 parts.append(dumps(k, sort_keys=sort_keys))
165 parts.append(dumps(v, sort_keys=sort_keys))
166 else:
167 for k,v in d.items():
168 parts.append(dumps(k, sort_keys=sort_keys))
169 parts.append(dumps(v, sort_keys=sort_keys))
164170 return b''.join(parts)
165171 else:
166 def dumps_dict(d):
172 def dumps_dict(d, sort_keys=False):
167173 head = _encode_type_num(CBOR_MAP, len(d))
168174 parts = [head]
169 for k,v in d.iteritems():
170 parts.append(dumps(k))
171 parts.append(dumps(v))
175 if sort_keys:
176 for k in sorted(d.iterkeys()):
177 v = d[k]
178 parts.append(dumps(k, sort_keys=sort_keys))
179 parts.append(dumps(v, sort_keys=sort_keys))
180 else:
181 for k,v in d.iteritems():
182 parts.append(dumps(k, sort_keys=sort_keys))
183 parts.append(dumps(v, sort_keys=sort_keys))
172184 return b''.join(parts)
173185
174186
178190 return struct.pack('B', CBOR_FALSE)
179191
180192
181 def dumps_tag(t):
182 return _encode_type_num(CBOR_TAG, t.tag) + dumps(t.value)
193 def dumps_tag(t, sort_keys=False):
194 return _encode_type_num(CBOR_TAG, t.tag) + dumps(t.value, sort_keys=sort_keys)
183195
184196
185197 if _IS_PY3:
194206 return isinstance(x, (int, long))
195207
196208
197 def dumps(ob):
209 def dumps(ob, sort_keys=False):
198210 if ob is None:
199211 return struct.pack('B', CBOR_NULL)
200212 if isinstance(ob, bool):
202214 if _is_stringish(ob):
203215 return dumps_string(ob)
204216 if isinstance(ob, (list, tuple)):
205 return dumps_array(ob)
217 return dumps_array(ob, sort_keys=sort_keys)
206218 # TODO: accept other enumerables and emit a variable length array
207219 if isinstance(ob, dict):
208 return dumps_dict(ob)
220 return dumps_dict(ob, sort_keys=sort_keys)
209221 if isinstance(ob, float):
210222 return dumps_float(ob)
211223 if _is_intish(ob):
212224 return dumps_int(ob)
213225 if isinstance(ob, Tag):
214 return dumps_tag(ob)
226 return dumps_tag(ob, sort_keys=sort_keys)
215227 raise Exception("don't know how to cbor serialize object of type %s", type(ob))
216228
217229
218230 # same basic signature as json.dump, but with no options (yet)
219 def dump(obj, fp):
231 def dump(obj, fp, sort_keys=False):
220232 """
221233 obj: Python object to serialize
222234 fp: file-like object capable of .write(bytes)
223235 """
224236 # this is kinda lame, but probably not inefficient for non-huge objects
225237 # TODO: .write() to fp as we go as each inner object is serialized
226 blob = dumps(obj)
238 blob = dumps(obj, sort_keys=sort_keys)
227239 fp.write(blob)
228240
229241
44 # fall back to 100% python implementation
55 from .cbor import loads, dumps, load, dump
66
7 from .cbor import Tag, CBOR_TAG_CBOR
7 from .cbor import Tag, CBOR_TAG_CBOR, _IS_PY3
88
99
1010 class ClassTag(object):
5353 # can't do this in Python 2.6:
5454 #return {k:self.encode(v) for k,v in obj.iteritems()}
5555 out = {}
56 for k,v in obj.iteritems():
56 if _IS_PY3:
57 items = obj.items()
58 else:
59 items = obj.iteritems()
60 for k,v in items:
5761 out[k] = self.encode(v)
5862 return out
5963 # fall through, let underlying cbor.dump decide if it can encode object
7680 return obj
7781 if isinstance(obj, dict):
7882 # update in place
79 for k,v in obj.iteritems():
83 if _IS_PY3:
84 items = obj.items()
85 else:
86 items = obj.iteritems()
87 for k,v in items:
8088 # assume key is a primitive
8189 obj[k] = self.decode(v)
8290 return obj
00 Metadata-Version: 1.1
11 Name: cbor
2 Version: 0.1.21
2 Version: 0.1.24
33 Summary: RFC 7049 - Concise Binary Object Representation
44 Home-page: https://bitbucket.org/bodhisnarkva/cbor
55 Author: Brian Olson
00 setup.py
11 c/cbor.h
22 c/cbormodule.c
3 cbor/VERSION.py
34 cbor/__init__.py
45 cbor/cbor.py
56 cbor/cbor_rpc_client.py
1111 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212 # See the License for the specific language governing permissions and
1313 # limitations under the License.
14
15 # Thanks!
16 # to Mic Bowman for a bunch of work and impetus on dumps(,sort_keys=)
1417
1518 from distutils.command.build_ext import build_ext
1619 from distutils.errors import (CCompilerError, DistutilsExecError,
5255 raise
5356
5457
58 VERSION = eval(open('cbor/VERSION.py','rb').read())
59
60
5561 setup_options = dict(
5662 name='cbor',
57 version='0.1.21',
63 version=VERSION,
5864 description='RFC 7049 - Concise Binary Object Representation',
5965 long_description="""
6066 An implementation of RFC 7049 - Concise Binary Object Representation (CBOR).