diff options
Diffstat (limited to 'cython')
| -rw-r--r-- | cython/plist.pxd | 9 | ||||
| -rw-r--r-- | cython/plist.pyx | 106 |
2 files changed, 72 insertions, 43 deletions
diff --git a/cython/plist.pxd b/cython/plist.pxd index daafd78..6a96817 100644 --- a/cython/plist.pxd +++ b/cython/plist.pxd | |||
| @@ -1,25 +1,26 @@ | |||
| 1 | cdef extern from "plist/plist.h": | 1 | cdef extern from "plist/plist.h": |
| 2 | ctypedef void *plist_t | 2 | ctypedef void *plist_t |
| 3 | ctypedef void *plist_dict_iter | 3 | ctypedef void *plist_dict_iter |
| 4 | void plist_free(plist_t node) | ||
| 4 | 5 | ||
| 5 | cdef class Node: | 6 | cdef class Node: |
| 6 | cdef plist_t _c_node | 7 | cdef plist_t _c_node |
| 7 | cdef bool _c_managed | 8 | cdef bool _c_managed |
| 8 | cpdef object __deepcopy__(self, memo=*) | 9 | cpdef object __deepcopy__(self, memo=*) |
| 9 | cpdef bytes to_xml(self) | 10 | cpdef unicode to_xml(self) |
| 10 | cpdef bytes to_bin(self) | 11 | cpdef bytes to_bin(self) |
| 11 | cpdef object copy(self) | 12 | cpdef object copy(self) |
| 12 | 13 | ||
| 13 | cdef class Bool(Node): | 14 | cdef class Bool(Node): |
| 14 | cpdef set_value(self, value) | 15 | cpdef set_value(self, object value) |
| 15 | cpdef bool get_value(self) | 16 | cpdef bool get_value(self) |
| 16 | 17 | ||
| 17 | cdef class Integer(Node): | 18 | cdef class Integer(Node): |
| 18 | cpdef set_value(self, value) | 19 | cpdef set_value(self, object value) |
| 19 | cpdef int get_value(self) | 20 | cpdef int get_value(self) |
| 20 | 21 | ||
| 21 | cdef class Real(Node): | 22 | cdef class Real(Node): |
| 22 | cpdef set_value(self, value) | 23 | cpdef set_value(self, object value) |
| 23 | cpdef float get_value(self) | 24 | cpdef float get_value(self) |
| 24 | 25 | ||
| 25 | cdef class String(Node): | 26 | cdef class String(Node): |
diff --git a/cython/plist.pyx b/cython/plist.pyx index f4e7dbb..c636f7d 100644 --- a/cython/plist.pyx +++ b/cython/plist.pyx | |||
| @@ -10,6 +10,8 @@ ELSE: | |||
| 10 | ctypedef unsigned long long int uint64_t | 10 | ctypedef unsigned long long int uint64_t |
| 11 | 11 | ||
| 12 | cimport python_unicode | 12 | cimport python_unicode |
| 13 | cimport python_string | ||
| 14 | cimport stdlib | ||
| 13 | 15 | ||
| 14 | cdef extern from *: | 16 | cdef extern from *: |
| 15 | ctypedef enum plist_type: | 17 | ctypedef enum plist_type: |
| @@ -80,9 +82,6 @@ cdef extern from *: | |||
| 80 | void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist) | 82 | void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist) |
| 81 | void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist) | 83 | void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist) |
| 82 | 84 | ||
| 83 | cdef extern from *: | ||
| 84 | void free(void *ptr) | ||
| 85 | |||
| 86 | cdef class Node: | 85 | cdef class Node: |
| 87 | def __init__(self, *args, **kwargs): | 86 | def __init__(self, *args, **kwargs): |
| 88 | self._c_managed = True | 87 | self._c_managed = True |
| @@ -99,19 +98,27 @@ cdef class Node: | |||
| 99 | c_node = plist_copy(self._c_node) | 98 | c_node = plist_copy(self._c_node) |
| 100 | return plist_t_to_node(c_node) | 99 | return plist_t_to_node(c_node) |
| 101 | 100 | ||
| 102 | cpdef bytes to_xml(self): | 101 | cpdef unicode to_xml(self): |
| 103 | cdef char* out = NULL | 102 | cdef: |
| 104 | cdef uint32_t length | 103 | char* out = NULL |
| 104 | uint32_t length | ||
| 105 | plist_to_xml(self._c_node, &out, &length) | 105 | plist_to_xml(self._c_node, &out, &length) |
| 106 | 106 | ||
| 107 | return out[:length] | 107 | try: |
| 108 | return python_unicode.PyUnicode_DecodeUTF8(out, length, 'strict') | ||
| 109 | finally: | ||
| 110 | stdlib.free(out) | ||
| 108 | 111 | ||
| 109 | cpdef bytes to_bin(self): | 112 | cpdef bytes to_bin(self): |
| 110 | cdef char* out = NULL | 113 | cdef: |
| 111 | cdef uint32_t length | 114 | char* out = NULL |
| 115 | uint32_t length | ||
| 112 | plist_to_bin(self._c_node, &out, &length) | 116 | plist_to_bin(self._c_node, &out, &length) |
| 113 | 117 | ||
| 114 | return out[:length] | 118 | try: |
| 119 | return python_string.PyString_FromStringAndSize(out, length) | ||
| 120 | finally: | ||
| 121 | stdlib.free(out) | ||
| 115 | 122 | ||
| 116 | property parent: | 123 | property parent: |
| 117 | def __get__(self): | 124 | def __get__(self): |
| @@ -156,7 +163,7 @@ cdef class Bool(Node): | |||
| 156 | b = self.get_value() | 163 | b = self.get_value() |
| 157 | return '<Bool: %s>' % b | 164 | return '<Bool: %s>' % b |
| 158 | 165 | ||
| 159 | cpdef set_value(self, value): | 166 | cpdef set_value(self, object value): |
| 160 | plist_set_bool_val(self._c_node, bool(value)) | 167 | plist_set_bool_val(self._c_node, bool(value)) |
| 161 | 168 | ||
| 162 | cpdef bool get_value(self): | 169 | cpdef bool get_value(self): |
| @@ -178,7 +185,7 @@ cdef class Integer(Node): | |||
| 178 | self._c_node = plist_new_uint(int(value)) | 185 | self._c_node = plist_new_uint(int(value)) |
| 179 | 186 | ||
| 180 | def __repr__(self): | 187 | def __repr__(self): |
| 181 | i = self.get_value() | 188 | cdef int i = self.get_value() |
| 182 | return '<Integer: %s>' % i | 189 | return '<Integer: %s>' % i |
| 183 | 190 | ||
| 184 | def __int__(self): | 191 | def __int__(self): |
| @@ -202,7 +209,7 @@ cdef class Integer(Node): | |||
| 202 | if op == 5: | 209 | if op == 5: |
| 203 | return i >= other | 210 | return i >= other |
| 204 | 211 | ||
| 205 | cpdef set_value(self, value): | 212 | cpdef set_value(self, object value): |
| 206 | plist_set_uint_val(self._c_node, int(value)) | 213 | plist_set_uint_val(self._c_node, int(value)) |
| 207 | 214 | ||
| 208 | cpdef int get_value(self): | 215 | cpdef int get_value(self): |
| @@ -248,7 +255,7 @@ cdef class Real(Node): | |||
| 248 | if op == 5: | 255 | if op == 5: |
| 249 | return f >= other | 256 | return f >= other |
| 250 | 257 | ||
| 251 | cpdef set_value(self, value): | 258 | cpdef set_value(self, object value): |
| 252 | plist_set_real_val(self._c_node, float(value)) | 259 | plist_set_real_val(self._c_node, float(value)) |
| 253 | 260 | ||
| 254 | cpdef float get_value(self): | 261 | cpdef float get_value(self): |
| @@ -266,24 +273,28 @@ from python_version cimport PY_MAJOR_VERSION | |||
| 266 | 273 | ||
| 267 | cdef class String(Node): | 274 | cdef class String(Node): |
| 268 | def __cinit__(self, value=None, *args, **kwargs): | 275 | def __cinit__(self, value=None, *args, **kwargs): |
| 276 | cdef: | ||
| 277 | char* c_utf8_data = NULL | ||
| 278 | bytes utf8_data | ||
| 269 | if value is None: | 279 | if value is None: |
| 270 | self._c_node = plist_new_string("") | 280 | self._c_node = plist_new_string("") |
| 271 | else: | 281 | else: |
| 272 | if isinstance(value, unicode): | 282 | if isinstance(value, unicode): |
| 273 | utf8_data = value.encode('utf-8') | 283 | utf8_data = value.encode('utf-8') |
| 274 | elif (PY_MAJOR_VERSION < 3) and isinstance(value, str): | 284 | elif (PY_MAJOR_VERSION < 3) and isinstance(value, str): |
| 275 | value.decode('ascii') | 285 | value.decode('ascii') # trial decode |
| 276 | utf8_data = value | 286 | utf8_data = value.decode('ascii') |
| 277 | else: | 287 | else: |
| 278 | raise ValueError("requires text input, got %s" % type(value)) | 288 | raise ValueError("requires text input, got %s" % type(value)) |
| 279 | self._c_node = plist_new_string(utf8_data) | 289 | c_utf8_data = utf8_data |
| 290 | self._c_node = plist_new_string(c_utf8_data) | ||
| 280 | 291 | ||
| 281 | def __repr__(self): | 292 | def __repr__(self): |
| 282 | s = self.get_value() | 293 | s = self.get_value() |
| 283 | return '<String: %s>' % s | 294 | return '<String: %s>' % s.encode('utf-8') |
| 284 | 295 | ||
| 285 | def __richcmp__(self, other, op): | 296 | def __richcmp__(self, other, op): |
| 286 | cdef str s = self.get_value() | 297 | cdef unicode s = self.get_value() |
| 287 | if op == 0: | 298 | if op == 0: |
| 288 | return s < other | 299 | return s < other |
| 289 | if op == 1: | 300 | if op == 1: |
| @@ -298,22 +309,30 @@ cdef class String(Node): | |||
| 298 | return s >= other | 309 | return s >= other |
| 299 | 310 | ||
| 300 | cpdef set_value(self, unicode value): | 311 | cpdef set_value(self, unicode value): |
| 312 | cdef: | ||
| 313 | char* c_utf8_data = NULL | ||
| 314 | bytes utf8_data | ||
| 301 | if value is None: | 315 | if value is None: |
| 302 | self._c_node = plist_new_string("") | 316 | plist_set_string_val(self._c_node, c_utf8_data) |
| 303 | else: | 317 | else: |
| 304 | if isinstance(value, unicode): | 318 | if isinstance(value, unicode): |
| 305 | utf8_data = value.encode('utf-8') | 319 | utf8_data = value.encode('utf-8') |
| 306 | elif (PY_MAJOR_VERSION < 3) and isinstance(value, str): | 320 | elif (PY_MAJOR_VERSION < 3) and isinstance(value, str): |
| 307 | value.decode('ascii') | 321 | value.decode('ascii') # trial decode |
| 308 | utf8_data = value | 322 | utf8_data = value.decode('ascii') |
| 309 | else: | 323 | else: |
| 310 | raise ValueError("requires text input, got %s" % type(value)) | 324 | raise ValueError("requires text input, got %s" % type(value)) |
| 311 | self._c_node = plist_new_string(utf8_data) | 325 | c_utf8_data = utf8_data |
| 326 | plist_set_string_val(self._c_node, c_utf8_data) | ||
| 312 | 327 | ||
| 313 | cpdef unicode get_value(self): | 328 | cpdef unicode get_value(self): |
| 314 | cdef char* value = NULL | 329 | cdef: |
| 315 | plist_get_string_val(self._c_node, &value) | 330 | char* c_value = NULL |
| 316 | return python_unicode.PyUnicode_DecodeUTF8(value, len(value), 'strict') | 331 | plist_get_string_val(self._c_node, &c_value) |
| 332 | try: | ||
| 333 | return python_unicode.PyUnicode_DecodeUTF8(c_value, stdlib.strlen(c_value), 'strict') | ||
| 334 | finally: | ||
| 335 | stdlib.free(c_value) | ||
| 317 | 336 | ||
| 318 | cdef String String_factory(plist_t c_node, bool managed=True): | 337 | cdef String String_factory(plist_t c_node, bool managed=True): |
| 319 | cdef String instance = String.__new__(String) | 338 | cdef String instance = String.__new__(String) |
| @@ -393,7 +412,7 @@ cdef class Data(Node): | |||
| 393 | return '<Data: %s>' % d | 412 | return '<Data: %s>' % d |
| 394 | 413 | ||
| 395 | def __richcmp__(self, other, op): | 414 | def __richcmp__(self, other, op): |
| 396 | cdef str d = self.get_value() | 415 | cdef bytes d = self.get_value() |
| 397 | if op == 0: | 416 | if op == 0: |
| 398 | return d < other | 417 | return d < other |
| 399 | if op == 1: | 418 | if op == 1: |
| @@ -408,11 +427,15 @@ cdef class Data(Node): | |||
| 408 | return d >= other | 427 | return d >= other |
| 409 | 428 | ||
| 410 | cpdef bytes get_value(self): | 429 | cpdef bytes get_value(self): |
| 411 | cdef char* val = NULL | 430 | cdef: |
| 412 | cdef uint64_t length = 0 | 431 | char* val = NULL |
| 432 | uint64_t length = 0 | ||
| 413 | plist_get_data_val(self._c_node, &val, &length) | 433 | plist_get_data_val(self._c_node, &val, &length) |
| 414 | 434 | ||
| 415 | return val[:length] | 435 | try: |
| 436 | return python_string.PyString_FromStringAndSize(val, length) | ||
| 437 | finally: | ||
| 438 | stdlib.free(val) | ||
| 416 | 439 | ||
| 417 | cpdef set_value(self, bytes value): | 440 | cpdef set_value(self, bytes value): |
| 418 | plist_set_data_val(self._c_node, value, len(value)) | 441 | plist_set_data_val(self._c_node, value, len(value)) |
| @@ -434,6 +457,8 @@ cdef plist_t create_dict_plist(value=None): | |||
| 434 | c_node = NULL | 457 | c_node = NULL |
| 435 | return node | 458 | return node |
| 436 | 459 | ||
| 460 | cimport python_dict | ||
| 461 | |||
| 437 | cdef class Dict(Node): | 462 | cdef class Dict(Node): |
| 438 | def __cinit__(self, value=None, *args, **kwargs): | 463 | def __cinit__(self, value=None, *args, **kwargs): |
| 439 | self._c_node = create_dict_plist(value) | 464 | self._c_node = create_dict_plist(value) |
| @@ -446,18 +471,18 @@ cdef class Dict(Node): | |||
| 446 | cdef char* key = NULL | 471 | cdef char* key = NULL |
| 447 | cdef plist_t subnode = NULL | 472 | cdef plist_t subnode = NULL |
| 448 | 473 | ||
| 449 | self._map = {} | 474 | self._map = python_dict.PyDict_New() |
| 450 | 475 | ||
| 451 | plist_dict_new_iter(self._c_node, &it); | 476 | plist_dict_new_iter(self._c_node, &it); |
| 452 | plist_dict_next_item(self._c_node, it, &key, &subnode); | 477 | plist_dict_next_item(self._c_node, it, &key, &subnode); |
| 453 | 478 | ||
| 454 | while subnode is not NULL: | 479 | while subnode is not NULL: |
| 455 | self._map[key] = plist_t_to_node(subnode, False) | 480 | python_dict.PyDict_SetItem(self._map, key, plist_t_to_node(subnode, False)) |
| 456 | subnode = NULL | 481 | subnode = NULL |
| 457 | free(key) | 482 | stdlib.free(key) |
| 458 | key = NULL | 483 | key = NULL |
| 459 | plist_dict_next_item(self._c_node, it, &key, &subnode); | 484 | plist_dict_next_item(self._c_node, it, &key, &subnode); |
| 460 | free(it) | 485 | stdlib.free(it) |
| 461 | 486 | ||
| 462 | def __dealloc__(self): | 487 | def __dealloc__(self): |
| 463 | self._map = None | 488 | self._map = None |
| @@ -478,13 +503,15 @@ cdef class Dict(Node): | |||
| 478 | return d >= other | 503 | return d >= other |
| 479 | 504 | ||
| 480 | def __len__(self): | 505 | def __len__(self): |
| 481 | return len(self._map) | 506 | return python_dict.PyDict_Size(self._map) |
| 482 | 507 | ||
| 483 | def __repr__(self): | 508 | def __repr__(self): |
| 484 | return '<Dict: %s>' % self._map | 509 | return '<Dict: %s>' % self._map |
| 485 | 510 | ||
| 486 | cpdef dict get_value(self): | 511 | cpdef dict get_value(self): |
| 512 | cdef dict result = python_dict.PyDict_New() | ||
| 487 | return dict([(key, value.get_value()) for key, value in self.items()]) | 513 | return dict([(key, value.get_value()) for key, value in self.items()]) |
| 514 | return result | ||
| 488 | 515 | ||
| 489 | cpdef set_value(self, dict value): | 516 | cpdef set_value(self, dict value): |
| 490 | plist_free(self._c_node) | 517 | plist_free(self._c_node) |
| @@ -503,18 +530,19 @@ cdef class Dict(Node): | |||
| 503 | return self._map.get(key, default) | 530 | return self._map.get(key, default) |
| 504 | 531 | ||
| 505 | cpdef list keys(self): | 532 | cpdef list keys(self): |
| 506 | return self._map.keys() | 533 | return python_dict.PyDict_Keys(self._map) |
| 507 | 534 | ||
| 508 | cpdef object iterkeys(self): | 535 | cpdef object iterkeys(self): |
| 509 | return self._map.iterkeys() | 536 | return self._map.iterkeys() |
| 510 | 537 | ||
| 511 | cpdef list items(self): | 538 | cpdef list items(self): |
| 512 | return self._map.items() | 539 | return python_dict.PyDict_Items(self._map) |
| 513 | 540 | ||
| 514 | cpdef object iteritems(self): | 541 | cpdef object iteritems(self): |
| 515 | return self._map.iteritems() | 542 | return self._map.iteritems() |
| 516 | 543 | ||
| 517 | cpdef list values(self): | 544 | cpdef list values(self): |
| 545 | return python_dict.PyDict_Values(self._map) | ||
| 518 | return self._map.values() | 546 | return self._map.values() |
| 519 | 547 | ||
| 520 | cpdef object itervalues(self): | 548 | cpdef object itervalues(self): |
| @@ -534,7 +562,7 @@ cdef class Dict(Node): | |||
| 534 | self._map[key] = n | 562 | self._map[key] = n |
| 535 | 563 | ||
| 536 | def __delitem__(self, key): | 564 | def __delitem__(self, key): |
| 537 | del self._map[key] | 565 | python_dict.PyDict_DelItem(self._map, key) |
| 538 | plist_dict_remove_item(self._c_node, key) | 566 | plist_dict_remove_item(self._c_node, key) |
| 539 | 567 | ||
| 540 | cdef Dict Dict_factory(plist_t c_node, bool managed=True): | 568 | cdef Dict Dict_factory(plist_t c_node, bool managed=True): |
| @@ -667,7 +695,7 @@ cdef plist_t native_to_plist_t(object native): | |||
| 667 | if isinstance(native, basestring): | 695 | if isinstance(native, basestring): |
| 668 | return plist_new_string(native) | 696 | return plist_new_string(native) |
| 669 | if isinstance(native, bool): | 697 | if isinstance(native, bool): |
| 670 | return plist_new_bool(native) | 698 | return plist_new_bool(<bint>native) |
| 671 | if isinstance(native, int) or isinstance(native, long): | 699 | if isinstance(native, int) or isinstance(native, long): |
| 672 | return plist_new_uint(native) | 700 | return plist_new_uint(native) |
| 673 | if isinstance(native, float): | 701 | if isinstance(native, float): |
