diff options
| author | 2023-01-16 04:25:52 +0100 | |
|---|---|---|
| committer | 2023-01-16 04:25:52 +0100 | |
| commit | d886885b0ec2506fa2caf0986a3d0e496fea91c2 (patch) | |
| tree | 58bc4bcd1963ea885abd60a65bf87a2685526714 | |
| parent | 47a7fbe438ee7350a2b151e007f07043ef596775 (diff) | |
| download | libplist-d886885b0ec2506fa2caf0986a3d0e496fea91c2.tar.gz libplist-d886885b0ec2506fa2caf0986a3d0e496fea91c2.tar.bz2 | |
Rename PLIST_UINT to PLIST_INT and add plist_new_int() and plist_get_int_val()
This properly supports getting and setting signed or unsigned integer values.
Also, a new helper function plist_int_val_is_negative() was added to determine if
a given #PLIST_INT node has a negative value or not.
The old type PLIST_UINT is defined as a macro with the value of PLIST_INT for
backwards compatibility.
This commit also adds int vs. uint support to the C++ interface, and the python
bindings in a hopefully useful way.
| -rw-r--r-- | cython/plist.pxd | 3 | ||||
| -rw-r--r-- | cython/plist.pyx | 55 | ||||
| -rw-r--r-- | include/plist/Integer.h | 8 | ||||
| -rw-r--r-- | include/plist/plist.h | 79 | ||||
| -rw-r--r-- | src/Integer.cpp | 35 | ||||
| -rw-r--r-- | src/Key.cpp | 2 | ||||
| -rw-r--r-- | src/Node.cpp | 4 | ||||
| -rw-r--r-- | src/Real.cpp | 2 | ||||
| -rw-r--r-- | src/String.cpp | 2 | ||||
| -rw-r--r-- | src/bplist.c | 24 | ||||
| -rw-r--r-- | src/jplist.c | 12 | ||||
| -rw-r--r-- | src/oplist.c | 4 | ||||
| -rw-r--r-- | src/plist.c | 68 | ||||
| -rw-r--r-- | src/xplist.c | 6 | ||||
| -rw-r--r-- | test/Makefile.am | 5 | ||||
| -rw-r--r-- | test/integer_set.c | 130 | ||||
| -rwxr-xr-x | test/integer_set.test | 5 |
17 files changed, 382 insertions, 62 deletions
diff --git a/cython/plist.pxd b/cython/plist.pxd index b11d80d..5a41bf8 100644 --- a/cython/plist.pxd +++ b/cython/plist.pxd | |||
| @@ -19,7 +19,8 @@ cdef class Bool(Node): | |||
| 19 | 19 | ||
| 20 | cdef class Integer(Node): | 20 | cdef class Integer(Node): |
| 21 | cpdef set_value(self, object value) | 21 | cpdef set_value(self, object value) |
| 22 | cpdef uint64_t get_value(self) | 22 | cpdef get_value(self) |
| 23 | cpdef bint is_negative(self) | ||
| 23 | 24 | ||
| 24 | cdef class Uid(Node): | 25 | cdef class Uid(Node): |
| 25 | cpdef set_value(self, object value) | 26 | cpdef set_value(self, object value) |
diff --git a/cython/plist.pyx b/cython/plist.pyx index 38415f9..5481308 100644 --- a/cython/plist.pyx +++ b/cython/plist.pyx | |||
| @@ -5,7 +5,7 @@ from libc.stdint cimport * | |||
| 5 | cdef extern from *: | 5 | cdef extern from *: |
| 6 | ctypedef enum plist_type: | 6 | ctypedef enum plist_type: |
| 7 | PLIST_BOOLEAN, | 7 | PLIST_BOOLEAN, |
| 8 | PLIST_UINT, | 8 | PLIST_INT, |
| 9 | PLIST_REAL, | 9 | PLIST_REAL, |
| 10 | PLIST_STRING, | 10 | PLIST_STRING, |
| 11 | PLIST_ARRAY, | 11 | PLIST_ARRAY, |
| @@ -14,6 +14,7 @@ cdef extern from *: | |||
| 14 | PLIST_DATA, | 14 | PLIST_DATA, |
| 15 | PLIST_KEY, | 15 | PLIST_KEY, |
| 16 | PLIST_UID, | 16 | PLIST_UID, |
| 17 | PLIST_NULL, | ||
| 17 | PLIST_NONE | 18 | PLIST_NONE |
| 18 | 19 | ||
| 19 | plist_t plist_new_bool(uint8_t val) | 20 | plist_t plist_new_bool(uint8_t val) |
| @@ -24,6 +25,10 @@ cdef extern from *: | |||
| 24 | void plist_get_uint_val(plist_t node, uint64_t *val) | 25 | void plist_get_uint_val(plist_t node, uint64_t *val) |
| 25 | void plist_set_uint_val(plist_t node, uint64_t val) | 26 | void plist_set_uint_val(plist_t node, uint64_t val) |
| 26 | 27 | ||
| 28 | plist_t plist_new_int(int64_t val) | ||
| 29 | void plist_get_int_val(plist_t node, int64_t *val) | ||
| 30 | void plist_set_int_val(plist_t node, int64_t val) | ||
| 31 | |||
| 27 | plist_t plist_new_real(double val) | 32 | plist_t plist_new_real(double val) |
| 28 | void plist_get_real_val(plist_t node, double *val) | 33 | void plist_get_real_val(plist_t node, double *val) |
| 29 | void plist_set_real_val(plist_t node, double val) | 34 | void plist_set_real_val(plist_t node, double val) |
| @@ -47,6 +52,8 @@ cdef extern from *: | |||
| 47 | void plist_get_data_val(plist_t node, char **val, uint64_t * length) | 52 | void plist_get_data_val(plist_t node, char **val, uint64_t * length) |
| 48 | void plist_set_data_val(plist_t node, char *val, uint64_t length) | 53 | void plist_set_data_val(plist_t node, char *val, uint64_t length) |
| 49 | 54 | ||
| 55 | plist_t plist_new_null(); | ||
| 56 | |||
| 50 | plist_t plist_new_dict() | 57 | plist_t plist_new_dict() |
| 51 | int plist_dict_get_size(plist_t node) | 58 | int plist_dict_get_size(plist_t node) |
| 52 | plist_t plist_dict_get_item(plist_t node, char* key) | 59 | plist_t plist_dict_get_item(plist_t node, char* key) |
| @@ -77,6 +84,8 @@ cdef extern from *: | |||
| 77 | void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist) | 84 | void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist) |
| 78 | void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist) | 85 | void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist) |
| 79 | 86 | ||
| 87 | int plist_int_val_is_negative(plist_t node); | ||
| 88 | |||
| 80 | cdef class Node: | 89 | cdef class Node: |
| 81 | def __init__(self, *args, **kwargs): | 90 | def __init__(self, *args, **kwargs): |
| 82 | self._c_managed = True | 91 | self._c_managed = True |
| @@ -177,13 +186,15 @@ cdef Bool Bool_factory(plist_t c_node, bint managed=True): | |||
| 177 | cdef class Integer(Node): | 186 | cdef class Integer(Node): |
| 178 | def __cinit__(self, object value=None, *args, **kwargs): | 187 | def __cinit__(self, object value=None, *args, **kwargs): |
| 179 | if value is None: | 188 | if value is None: |
| 180 | self._c_node = plist_new_uint(0) | 189 | self._c_node = plist_new_int(0) |
| 181 | else: | 190 | else: |
| 182 | self._c_node = plist_new_uint(int(value)) | 191 | if value < 0 or value <= INT64_MAX: |
| 192 | self._c_node = plist_new_int(int(value)) | ||
| 193 | else: | ||
| 194 | self._c_node = plist_new_uint(int(value)) | ||
| 183 | 195 | ||
| 184 | def __repr__(self): | 196 | def __repr__(self): |
| 185 | cdef uint64_t i = self.get_value() | 197 | return '<Integer: %s>' % self.get_value() |
| 186 | return '<Integer: %s>' % i | ||
| 187 | 198 | ||
| 188 | def __int__(self): | 199 | def __int__(self): |
| 189 | return self.get_value() | 200 | return self.get_value() |
| @@ -210,10 +221,18 @@ cdef class Integer(Node): | |||
| 210 | cpdef set_value(self, object value): | 221 | cpdef set_value(self, object value): |
| 211 | plist_set_uint_val(self._c_node, int(value)) | 222 | plist_set_uint_val(self._c_node, int(value)) |
| 212 | 223 | ||
| 213 | cpdef uint64_t get_value(self): | 224 | cpdef get_value(self): |
| 214 | cdef uint64_t value | 225 | cdef int64_t ivalue |
| 215 | plist_get_uint_val(self._c_node, &value) | 226 | cdef uint64_t uvalue |
| 216 | return value | 227 | if self.is_negative(): |
| 228 | plist_get_int_val(self._c_node, &ivalue) | ||
| 229 | return int(ivalue) | ||
| 230 | else: | ||
| 231 | plist_get_uint_val(self._c_node, &uvalue) | ||
| 232 | return int(uvalue) | ||
| 233 | |||
| 234 | cpdef bint is_negative(self): | ||
| 235 | return plist_int_val_is_negative(self._c_node); | ||
| 217 | 236 | ||
| 218 | cdef Integer Integer_factory(plist_t c_node, bint managed=True): | 237 | cdef Integer Integer_factory(plist_t c_node, bint managed=True): |
| 219 | cdef Integer instance = Integer.__new__(Integer) | 238 | cdef Integer instance = Integer.__new__(Integer) |
| @@ -314,6 +333,20 @@ cdef Uid Uid_factory(plist_t c_node, bint managed=True): | |||
| 314 | instance._c_node = c_node | 333 | instance._c_node = c_node |
| 315 | return instance | 334 | return instance |
| 316 | 335 | ||
| 336 | cdef class Null(Node): | ||
| 337 | def __cinit__(self, object value=None, *args, **kwargs): | ||
| 338 | self._c_node = plist_new_null() | ||
| 339 | |||
| 340 | def __repr__(self): | ||
| 341 | cdef uint64_t i = self.get_value() | ||
| 342 | return '<Null>' | ||
| 343 | |||
| 344 | cdef Null Null_factory(plist_t c_node, bint managed=True): | ||
| 345 | cdef Null instance = Null.__new__(Null) | ||
| 346 | instance._c_managed = managed | ||
| 347 | instance._c_node = c_node | ||
| 348 | return instance | ||
| 349 | |||
| 317 | from cpython cimport PY_MAJOR_VERSION | 350 | from cpython cimport PY_MAJOR_VERSION |
| 318 | 351 | ||
| 319 | cdef class Key(Node): | 352 | cdef class Key(Node): |
| @@ -833,7 +866,7 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True): | |||
| 833 | cdef plist_type t = plist_get_node_type(c_plist) | 866 | cdef plist_type t = plist_get_node_type(c_plist) |
| 834 | if t == PLIST_BOOLEAN: | 867 | if t == PLIST_BOOLEAN: |
| 835 | return Bool_factory(c_plist, managed) | 868 | return Bool_factory(c_plist, managed) |
| 836 | if t == PLIST_UINT: | 869 | if t == PLIST_INT: |
| 837 | return Integer_factory(c_plist, managed) | 870 | return Integer_factory(c_plist, managed) |
| 838 | if t == PLIST_KEY: | 871 | if t == PLIST_KEY: |
| 839 | return Key_factory(c_plist, managed) | 872 | return Key_factory(c_plist, managed) |
| @@ -851,6 +884,8 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True): | |||
| 851 | return Data_factory(c_plist, managed) | 884 | return Data_factory(c_plist, managed) |
| 852 | if t == PLIST_UID: | 885 | if t == PLIST_UID: |
| 853 | return Uid_factory(c_plist, managed) | 886 | return Uid_factory(c_plist, managed) |
| 887 | if t == PLIST_NULL: | ||
| 888 | return Null_factory(c_plist, managed) | ||
| 854 | if t == PLIST_NONE: | 889 | if t == PLIST_NONE: |
| 855 | return None | 890 | return None |
| 856 | 891 | ||
diff --git a/include/plist/Integer.h b/include/plist/Integer.h index bdabc6f..1a4d980 100644 --- a/include/plist/Integer.h +++ b/include/plist/Integer.h | |||
| @@ -35,12 +35,18 @@ public : | |||
| 35 | Integer(const Integer& i); | 35 | Integer(const Integer& i); |
| 36 | Integer& operator=(const Integer& i); | 36 | Integer& operator=(const Integer& i); |
| 37 | Integer(uint64_t i); | 37 | Integer(uint64_t i); |
| 38 | Integer(int64_t i); | ||
| 38 | virtual ~Integer(); | 39 | virtual ~Integer(); |
| 39 | 40 | ||
| 40 | Node* Clone() const; | 41 | Node* Clone() const; |
| 41 | 42 | ||
| 43 | void SetValue(int64_t i); | ||
| 42 | void SetValue(uint64_t i); | 44 | void SetValue(uint64_t i); |
| 43 | uint64_t GetValue() const; | 45 | void SetUnsignedValue(uint64_t i); |
| 46 | int64_t GetValue() const; | ||
| 47 | uint64_t GetUnsignedValue() const; | ||
| 48 | |||
| 49 | bool isNegative() const; | ||
| 44 | }; | 50 | }; |
| 45 | 51 | ||
| 46 | }; | 52 | }; |
diff --git a/include/plist/plist.h b/include/plist/plist.h index 0ae8889..2bb947f 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * @brief Main include of libplist | 3 | * @brief Main include of libplist |
| 4 | * \internal | 4 | * \internal |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved. | 6 | * Copyright (c) 2012-2023 Nikias Bassen, All Rights Reserved. |
| 7 | * Copyright (c) 2008-2009 Jonathan Beck, All Rights Reserved. | 7 | * Copyright (c) 2008-2009 Jonathan Beck, All Rights Reserved. |
| 8 | * | 8 | * |
| 9 | * This library is free software; you can redistribute it and/or | 9 | * This library is free software; you can redistribute it and/or |
| @@ -104,7 +104,7 @@ extern "C" | |||
| 104 | typedef enum | 104 | typedef enum |
| 105 | { | 105 | { |
| 106 | PLIST_BOOLEAN, /**< Boolean, scalar type */ | 106 | PLIST_BOOLEAN, /**< Boolean, scalar type */ |
| 107 | PLIST_UINT, /**< Unsigned integer, scalar type */ | 107 | PLIST_INT, /**< Integer, scalar type */ |
| 108 | PLIST_REAL, /**< Real, scalar type */ | 108 | PLIST_REAL, /**< Real, scalar type */ |
| 109 | PLIST_STRING, /**< ASCII string, scalar type */ | 109 | PLIST_STRING, /**< ASCII string, scalar type */ |
| 110 | PLIST_ARRAY, /**< Ordered array, structured type */ | 110 | PLIST_ARRAY, /**< Ordered array, structured type */ |
| @@ -117,6 +117,9 @@ extern "C" | |||
| 117 | PLIST_NONE /**< No type */ | 117 | PLIST_NONE /**< No type */ |
| 118 | } plist_type; | 118 | } plist_type; |
| 119 | 119 | ||
| 120 | /* for backwards compatibility */ | ||
| 121 | #define PLIST_UINT PLIST_INT | ||
| 122 | |||
| 120 | /** | 123 | /** |
| 121 | * libplist error values | 124 | * libplist error values |
| 122 | */ | 125 | */ |
| @@ -171,15 +174,28 @@ extern "C" | |||
| 171 | plist_t plist_new_bool(uint8_t val); | 174 | plist_t plist_new_bool(uint8_t val); |
| 172 | 175 | ||
| 173 | /** | 176 | /** |
| 174 | * Create a new plist_t type #PLIST_UINT | 177 | * Create a new plist_t type #PLIST_INT with an unsigned integer value |
| 175 | * | 178 | * |
| 176 | * @param val the unsigned integer value | 179 | * @param val the unsigned integer value |
| 177 | * @return the created item | 180 | * @return the created item |
| 178 | * @sa #plist_type | 181 | * @sa #plist_type |
| 182 | * @note The value is always stored as uint64_t internally. | ||
| 183 | * Use #plist_get_uint_val or #plist_get_int_val to get the unsigned or signed value. | ||
| 179 | */ | 184 | */ |
| 180 | plist_t plist_new_uint(uint64_t val); | 185 | plist_t plist_new_uint(uint64_t val); |
| 181 | 186 | ||
| 182 | /** | 187 | /** |
| 188 | * Create a new plist_t type #PLIST_INT with a signed integer value | ||
| 189 | * | ||
| 190 | * @param val the signed integer value | ||
| 191 | * @return the created item | ||
| 192 | * @sa #plist_type | ||
| 193 | * @note The value is always stored as uint64_t internally. | ||
| 194 | * Use #plist_get_uint_val or #plist_get_int_val to get the unsigned or signed value. | ||
| 195 | */ | ||
| 196 | plist_t plist_new_int(int64_t val); | ||
| 197 | |||
| 198 | /** | ||
| 183 | * Create a new plist_t type #PLIST_REAL | 199 | * Create a new plist_t type #PLIST_REAL |
| 184 | * | 200 | * |
| 185 | * @param val the real value | 201 | * @param val the real value |
| @@ -509,8 +525,8 @@ extern "C" | |||
| 509 | void plist_get_bool_val(plist_t node, uint8_t * val); | 525 | void plist_get_bool_val(plist_t node, uint8_t * val); |
| 510 | 526 | ||
| 511 | /** | 527 | /** |
| 512 | * Get the value of a #PLIST_UINT node. | 528 | * Get the unsigned integer value of a #PLIST_INT node. |
| 513 | * This function does nothing if node is not of type #PLIST_UINT | 529 | * This function does nothing if node is not of type #PLIST_INT |
| 514 | * | 530 | * |
| 515 | * @param node the node | 531 | * @param node the node |
| 516 | * @param val a pointer to a uint64_t variable. | 532 | * @param val a pointer to a uint64_t variable. |
| @@ -518,6 +534,15 @@ extern "C" | |||
| 518 | void plist_get_uint_val(plist_t node, uint64_t * val); | 534 | void plist_get_uint_val(plist_t node, uint64_t * val); |
| 519 | 535 | ||
| 520 | /** | 536 | /** |
| 537 | * Get the signed integer value of a #PLIST_INT node. | ||
| 538 | * This function does nothing if node is not of type #PLIST_INT | ||
| 539 | * | ||
| 540 | * @param node the node | ||
| 541 | * @param val a pointer to a int64_t variable. | ||
| 542 | */ | ||
| 543 | void plist_get_int_val(plist_t node, int64_t * val); | ||
| 544 | |||
| 545 | /** | ||
| 521 | * Get the value of a #PLIST_REAL node. | 546 | * Get the value of a #PLIST_REAL node. |
| 522 | * This function does nothing if node is not of type #PLIST_REAL | 547 | * This function does nothing if node is not of type #PLIST_REAL |
| 523 | * | 548 | * |
| @@ -607,7 +632,7 @@ extern "C" | |||
| 607 | 632 | ||
| 608 | /** | 633 | /** |
| 609 | * Set the value of a node. | 634 | * Set the value of a node. |
| 610 | * Forces type of node to #PLIST_UINT | 635 | * Forces type of node to #PLIST_INT |
| 611 | * | 636 | * |
| 612 | * @param node the node | 637 | * @param node the node |
| 613 | * @param val the unsigned integer value | 638 | * @param val the unsigned integer value |
| @@ -616,6 +641,15 @@ extern "C" | |||
| 616 | 641 | ||
| 617 | /** | 642 | /** |
| 618 | * Set the value of a node. | 643 | * Set the value of a node. |
| 644 | * Forces type of node to #PLIST_INT | ||
| 645 | * | ||
| 646 | * @param node the node | ||
| 647 | * @param val the signed integer value | ||
| 648 | */ | ||
| 649 | void plist_set_int_val(plist_t node, int64_t val); | ||
| 650 | |||
| 651 | /** | ||
| 652 | * Set the value of a node. | ||
| 619 | * Forces type of node to #PLIST_REAL | 653 | * Forces type of node to #PLIST_REAL |
| 620 | * | 654 | * |
| 621 | * @param node the node | 655 | * @param node the node |
| @@ -823,7 +857,7 @@ extern "C" | |||
| 823 | 857 | ||
| 824 | /* Helper macros for the different plist types */ | 858 | /* Helper macros for the different plist types */ |
| 825 | #define PLIST_IS_BOOLEAN(__plist) _PLIST_IS_TYPE(__plist, BOOLEAN) | 859 | #define PLIST_IS_BOOLEAN(__plist) _PLIST_IS_TYPE(__plist, BOOLEAN) |
| 826 | #define PLIST_IS_UINT(__plist) _PLIST_IS_TYPE(__plist, UINT) | 860 | #define PLIST_IS_INT(__plist) _PLIST_IS_TYPE(__plist, INT) |
| 827 | #define PLIST_IS_REAL(__plist) _PLIST_IS_TYPE(__plist, REAL) | 861 | #define PLIST_IS_REAL(__plist) _PLIST_IS_TYPE(__plist, REAL) |
| 828 | #define PLIST_IS_STRING(__plist) _PLIST_IS_TYPE(__plist, STRING) | 862 | #define PLIST_IS_STRING(__plist) _PLIST_IS_TYPE(__plist, STRING) |
| 829 | #define PLIST_IS_ARRAY(__plist) _PLIST_IS_TYPE(__plist, ARRAY) | 863 | #define PLIST_IS_ARRAY(__plist) _PLIST_IS_TYPE(__plist, ARRAY) |
| @@ -832,21 +866,42 @@ extern "C" | |||
| 832 | #define PLIST_IS_DATA(__plist) _PLIST_IS_TYPE(__plist, DATA) | 866 | #define PLIST_IS_DATA(__plist) _PLIST_IS_TYPE(__plist, DATA) |
| 833 | #define PLIST_IS_KEY(__plist) _PLIST_IS_TYPE(__plist, KEY) | 867 | #define PLIST_IS_KEY(__plist) _PLIST_IS_TYPE(__plist, KEY) |
| 834 | #define PLIST_IS_UID(__plist) _PLIST_IS_TYPE(__plist, UID) | 868 | #define PLIST_IS_UID(__plist) _PLIST_IS_TYPE(__plist, UID) |
| 869 | /* for backwards compatibility */ | ||
| 870 | #define PLIST_IS_UINT PLIST_IS_INT | ||
| 835 | 871 | ||
| 836 | /** | 872 | /** |
| 837 | * Helper function to check the value of a PLIST_BOOL node. | 873 | * Helper function to check the value of a PLIST_BOOL node. |
| 838 | * | 874 | * |
| 839 | * @param boolnode node of type PLIST_BOOL | 875 | * @param boolnode node of type PLIST_BOOL |
| 840 | * @return 1 if the boolean node has a value of TRUE, 0 if FALSE, | 876 | * @return 1 if the boolean node has a value of TRUE or 0 if FALSE. |
| 841 | * or -1 if the node is not of type PLIST_BOOL | ||
| 842 | */ | 877 | */ |
| 843 | int plist_bool_val_is_true(plist_t boolnode); | 878 | int plist_bool_val_is_true(plist_t boolnode); |
| 844 | 879 | ||
| 845 | /** | 880 | /** |
| 846 | * Helper function to compare the value of a PLIST_UINT node against | 881 | * Helper function to test if a given #PLIST_INT node's value is negative |
| 847 | * a given value. | 882 | * |
| 883 | * @param intnode node of type PLIST_INT | ||
| 884 | * @return 1 if the node's value is negative, or 0 if positive. | ||
| 885 | */ | ||
| 886 | int plist_int_val_is_negative(plist_t intnode); | ||
| 887 | |||
| 888 | /** | ||
| 889 | * Helper function to compare the value of a PLIST_INT node against | ||
| 890 | * a given signed integer value. | ||
| 891 | * | ||
| 892 | * @param uintnode node of type PLIST_INT | ||
| 893 | * @param cmpval value to compare against | ||
| 894 | * @return 0 if the node's value and cmpval are equal, | ||
| 895 | * 1 if the node's value is greater than cmpval, | ||
| 896 | * or -1 if the node's value is less than cmpval. | ||
| 897 | */ | ||
| 898 | int plist_int_val_compare(plist_t uintnode, int64_t cmpval); | ||
| 899 | |||
| 900 | /** | ||
| 901 | * Helper function to compare the value of a PLIST_INT node against | ||
| 902 | * a given unsigned integer value. | ||
| 848 | * | 903 | * |
| 849 | * @param uintnode node of type PLIST_UINT | 904 | * @param uintnode node of type PLIST_INT |
| 850 | * @param cmpval value to compare against | 905 | * @param cmpval value to compare against |
| 851 | * @return 0 if the node's value and cmpval are equal, | 906 | * @return 0 if the node's value and cmpval are equal, |
| 852 | * 1 if the node's value is greater than cmpval, | 907 | * 1 if the node's value is greater than cmpval, |
diff --git a/src/Integer.cpp b/src/Integer.cpp index a40d026..7fa0f93 100644 --- a/src/Integer.cpp +++ b/src/Integer.cpp | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | namespace PList | 24 | namespace PList |
| 25 | { | 25 | { |
| 26 | 26 | ||
| 27 | Integer::Integer(Node* parent) : Node(PLIST_UINT, parent) | 27 | Integer::Integer(Node* parent) : Node(PLIST_INT, parent) |
| 28 | { | 28 | { |
| 29 | } | 29 | } |
| 30 | 30 | ||
| @@ -32,7 +32,7 @@ Integer::Integer(plist_t node, Node* parent) : Node(node, parent) | |||
| 32 | { | 32 | { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | Integer::Integer(const PList::Integer& i) : Node(PLIST_UINT) | 35 | Integer::Integer(const PList::Integer& i) : Node(PLIST_INT) |
| 36 | { | 36 | { |
| 37 | plist_set_uint_val(_node, i.GetValue()); | 37 | plist_set_uint_val(_node, i.GetValue()); |
| 38 | } | 38 | } |
| @@ -44,11 +44,16 @@ Integer& Integer::operator=(const PList::Integer& i) | |||
| 44 | return *this; | 44 | return *this; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | Integer::Integer(uint64_t i) : Node(PLIST_UINT) | 47 | Integer::Integer(uint64_t i) : Node(PLIST_INT) |
| 48 | { | 48 | { |
| 49 | plist_set_uint_val(_node, i); | 49 | plist_set_uint_val(_node, i); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | Integer::Integer(int64_t i) : Node(PLIST_INT) | ||
| 53 | { | ||
| 54 | plist_set_int_val(_node, i); | ||
| 55 | } | ||
| 56 | |||
| 52 | Integer::~Integer() | 57 | Integer::~Integer() |
| 53 | { | 58 | { |
| 54 | } | 59 | } |
| @@ -58,16 +63,38 @@ Node* Integer::Clone() const | |||
| 58 | return new Integer(*this); | 63 | return new Integer(*this); |
| 59 | } | 64 | } |
| 60 | 65 | ||
| 66 | void Integer::SetValue(int64_t i) | ||
| 67 | { | ||
| 68 | plist_set_int_val(_node, i); | ||
| 69 | } | ||
| 70 | |||
| 61 | void Integer::SetValue(uint64_t i) | 71 | void Integer::SetValue(uint64_t i) |
| 62 | { | 72 | { |
| 63 | plist_set_uint_val(_node, i); | 73 | plist_set_uint_val(_node, i); |
| 64 | } | 74 | } |
| 65 | 75 | ||
| 66 | uint64_t Integer::GetValue() const | 76 | void Integer::SetUnsignedValue(uint64_t i) |
| 77 | { | ||
| 78 | plist_set_uint_val(_node, i); | ||
| 79 | } | ||
| 80 | |||
| 81 | int64_t Integer::GetValue() const | ||
| 82 | { | ||
| 83 | int64_t i = 0; | ||
| 84 | plist_get_int_val(_node, &i); | ||
| 85 | return i; | ||
| 86 | } | ||
| 87 | |||
| 88 | uint64_t Integer::GetUnsignedValue() const | ||
| 67 | { | 89 | { |
| 68 | uint64_t i = 0; | 90 | uint64_t i = 0; |
| 69 | plist_get_uint_val(_node, &i); | 91 | plist_get_uint_val(_node, &i); |
| 70 | return i; | 92 | return i; |
| 71 | } | 93 | } |
| 72 | 94 | ||
| 95 | bool Integer::isNegative() const | ||
| 96 | { | ||
| 97 | return plist_int_val_is_negative(_node); | ||
| 98 | } | ||
| 99 | |||
| 73 | } // namespace PList | 100 | } // namespace PList |
diff --git a/src/Key.cpp b/src/Key.cpp index 5d7d372..5f8d205 100644 --- a/src/Key.cpp +++ b/src/Key.cpp | |||
| @@ -32,7 +32,7 @@ Key::Key(plist_t node, Node* parent) : Node(node, parent) | |||
| 32 | { | 32 | { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | Key::Key(const PList::Key& k) : Node(PLIST_UINT) | 35 | Key::Key(const PList::Key& k) : Node(PLIST_INT) |
| 36 | { | 36 | { |
| 37 | plist_set_key_val(_node, k.GetValue().c_str()); | 37 | plist_set_key_val(_node, k.GetValue().c_str()); |
| 38 | } | 38 | } |
diff --git a/src/Node.cpp b/src/Node.cpp index fb79911..08a91b0 100644 --- a/src/Node.cpp +++ b/src/Node.cpp | |||
| @@ -52,7 +52,7 @@ Node::Node(plist_type type, Node* parent) : _parent(parent) | |||
| 52 | case PLIST_BOOLEAN: | 52 | case PLIST_BOOLEAN: |
| 53 | _node = plist_new_bool(0); | 53 | _node = plist_new_bool(0); |
| 54 | break; | 54 | break; |
| 55 | case PLIST_UINT: | 55 | case PLIST_INT: |
| 56 | _node = plist_new_uint(0); | 56 | _node = plist_new_uint(0); |
| 57 | break; | 57 | break; |
| 58 | case PLIST_REAL: | 58 | case PLIST_REAL: |
| @@ -134,7 +134,7 @@ Node* Node::FromPlist(plist_t node, Node* parent) | |||
| 134 | case PLIST_BOOLEAN: | 134 | case PLIST_BOOLEAN: |
| 135 | ret = new Boolean(node, parent); | 135 | ret = new Boolean(node, parent); |
| 136 | break; | 136 | break; |
| 137 | case PLIST_UINT: | 137 | case PLIST_INT: |
| 138 | ret = new Integer(node, parent); | 138 | ret = new Integer(node, parent); |
| 139 | break; | 139 | break; |
| 140 | case PLIST_REAL: | 140 | case PLIST_REAL: |
diff --git a/src/Real.cpp b/src/Real.cpp index 6bdb920..02d1d9b 100644 --- a/src/Real.cpp +++ b/src/Real.cpp | |||
| @@ -32,7 +32,7 @@ Real::Real(plist_t node, Node* parent) : Node(node, parent) | |||
| 32 | { | 32 | { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | Real::Real(const PList::Real& d) : Node(PLIST_UINT) | 35 | Real::Real(const PList::Real& d) : Node(PLIST_INT) |
| 36 | { | 36 | { |
| 37 | plist_set_real_val(_node, d.GetValue()); | 37 | plist_set_real_val(_node, d.GetValue()); |
| 38 | } | 38 | } |
diff --git a/src/String.cpp b/src/String.cpp index 06b61ba..aee2358 100644 --- a/src/String.cpp +++ b/src/String.cpp | |||
| @@ -32,7 +32,7 @@ String::String(plist_t node, Node* parent) : Node(node, parent) | |||
| 32 | { | 32 | { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | String::String(const PList::String& s) : Node(PLIST_UINT) | 35 | String::String(const PList::String& s) : Node(PLIST_INT) |
| 36 | { | 36 | { |
| 37 | plist_set_string_val(_node, s.GetValue().c_str()); | 37 | plist_set_string_val(_node, s.GetValue().c_str()); |
| 38 | } | 38 | } |
diff --git a/src/bplist.c b/src/bplist.c index 851ecd6..8927de6 100644 --- a/src/bplist.c +++ b/src/bplist.c | |||
| @@ -62,7 +62,7 @@ enum | |||
| 62 | BPLIST_FALSE = 0x08, | 62 | BPLIST_FALSE = 0x08, |
| 63 | BPLIST_TRUE = 0x09, | 63 | BPLIST_TRUE = 0x09, |
| 64 | BPLIST_FILL = 0x0F, /* will be used for length grabbing */ | 64 | BPLIST_FILL = 0x0F, /* will be used for length grabbing */ |
| 65 | BPLIST_UINT = 0x10, | 65 | BPLIST_INT = 0x10, |
| 66 | BPLIST_REAL = 0x20, | 66 | BPLIST_REAL = 0x20, |
| 67 | BPLIST_DATE = 0x30, | 67 | BPLIST_DATE = 0x30, |
| 68 | BPLIST_DATA = 0x40, | 68 | BPLIST_DATA = 0x40, |
| @@ -229,7 +229,7 @@ void plist_bin_deinit(void) | |||
| 229 | 229 | ||
| 230 | static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node_index); | 230 | static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node_index); |
| 231 | 231 | ||
| 232 | static plist_t parse_uint_node(const char **bnode, uint8_t size) | 232 | static plist_t parse_int_node(const char **bnode, uint8_t size) |
| 233 | { | 233 | { |
| 234 | plist_data_t data = plist_new_plist_data(); | 234 | plist_data_t data = plist_new_plist_data(); |
| 235 | 235 | ||
| @@ -254,7 +254,7 @@ static plist_t parse_uint_node(const char **bnode, uint8_t size) | |||
| 254 | data->intval = UINT_TO_HOST(*bnode, size); | 254 | data->intval = UINT_TO_HOST(*bnode, size); |
| 255 | 255 | ||
| 256 | (*bnode) += size; | 256 | (*bnode) += size; |
| 257 | data->type = PLIST_UINT; | 257 | data->type = PLIST_INT; |
| 258 | 258 | ||
| 259 | return node_create(NULL, data); | 259 | return node_create(NULL, data); |
| 260 | } | 260 | } |
| @@ -583,8 +583,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 583 | case BPLIST_DICT: | 583 | case BPLIST_DICT: |
| 584 | { | 584 | { |
| 585 | uint16_t next_size = **object & BPLIST_FILL; | 585 | uint16_t next_size = **object & BPLIST_FILL; |
| 586 | if ((**object & BPLIST_MASK) != BPLIST_UINT) { | 586 | if ((**object & BPLIST_MASK) != BPLIST_INT) { |
| 587 | PLIST_BIN_ERR("%s: invalid size node type for node type 0x%02x: found 0x%02x, expected 0x%02x\n", __func__, type, **object & BPLIST_MASK, BPLIST_UINT); | 587 | PLIST_BIN_ERR("%s: invalid size node type for node type 0x%02x: found 0x%02x, expected 0x%02x\n", __func__, type, **object & BPLIST_MASK, BPLIST_INT); |
| 588 | return NULL; | 588 | return NULL; |
| 589 | } | 589 | } |
| 590 | (*object)++; | 590 | (*object)++; |
| @@ -641,12 +641,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 641 | return NULL; | 641 | return NULL; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | case BPLIST_UINT: | 644 | case BPLIST_INT: |
| 645 | if (pobject + (uint64_t)(1 << size) > poffset_table) { | 645 | if (pobject + (uint64_t)(1 << size) > poffset_table) { |
| 646 | PLIST_BIN_ERR("%s: BPLIST_UINT data bytes point outside of valid range\n", __func__); | 646 | PLIST_BIN_ERR("%s: BPLIST_INT data bytes point outside of valid range\n", __func__); |
| 647 | return NULL; | 647 | return NULL; |
| 648 | } | 648 | } |
| 649 | return parse_uint_node(object, size); | 649 | return parse_int_node(object, size); |
| 650 | 650 | ||
| 651 | case BPLIST_REAL: | 651 | case BPLIST_REAL: |
| 652 | if (pobject + (uint64_t)(1 << size) > poffset_table) { | 652 | if (pobject + (uint64_t)(1 << size) > poffset_table) { |
| @@ -896,7 +896,7 @@ static unsigned int plist_data_hash(const void* key) | |||
| 896 | switch (data->type) | 896 | switch (data->type) |
| 897 | { | 897 | { |
| 898 | case PLIST_BOOLEAN: | 898 | case PLIST_BOOLEAN: |
| 899 | case PLIST_UINT: | 899 | case PLIST_INT: |
| 900 | case PLIST_REAL: | 900 | case PLIST_REAL: |
| 901 | case PLIST_DATE: | 901 | case PLIST_DATE: |
| 902 | case PLIST_UID: | 902 | case PLIST_UID: |
| @@ -973,7 +973,7 @@ static void write_int(bytearray_t * bplist, uint64_t val) | |||
| 973 | //do not write 3bytes int node | 973 | //do not write 3bytes int node |
| 974 | if (size == 3) | 974 | if (size == 3) |
| 975 | size++; | 975 | size++; |
| 976 | sz = BPLIST_UINT | Log2(size); | 976 | sz = BPLIST_INT | Log2(size); |
| 977 | 977 | ||
| 978 | val = be64toh(val); | 978 | val = be64toh(val); |
| 979 | byte_array_append(bplist, &sz, 1); | 979 | byte_array_append(bplist, &sz, 1); |
| @@ -982,7 +982,7 @@ static void write_int(bytearray_t * bplist, uint64_t val) | |||
| 982 | 982 | ||
| 983 | static void write_uint(bytearray_t * bplist, uint64_t val) | 983 | static void write_uint(bytearray_t * bplist, uint64_t val) |
| 984 | { | 984 | { |
| 985 | uint8_t sz = BPLIST_UINT | 4; | 985 | uint8_t sz = BPLIST_INT | 4; |
| 986 | uint64_t zero = 0; | 986 | uint64_t zero = 0; |
| 987 | 987 | ||
| 988 | val = be64toh(val); | 988 | val = be64toh(val); |
| @@ -1346,7 +1346,7 @@ PLIST_API plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * l | |||
| 1346 | byte_array_append(bplist_buff, &b, 1); | 1346 | byte_array_append(bplist_buff, &b, 1); |
| 1347 | break; | 1347 | break; |
| 1348 | } | 1348 | } |
| 1349 | case PLIST_UINT: | 1349 | case PLIST_INT: |
| 1350 | if (data->length == 16) { | 1350 | if (data->length == 16) { |
| 1351 | write_uint(bplist_buff, data->intval); | 1351 | write_uint(bplist_buff, data->intval); |
| 1352 | } else { | 1352 | } else { |
diff --git a/src/jplist.c b/src/jplist.c index f4adf2f..7817b1c 100644 --- a/src/jplist.c +++ b/src/jplist.c | |||
| @@ -131,7 +131,7 @@ static int node_to_json(node_t* node, bytearray_t **outbuf, uint32_t depth, int | |||
| 131 | str_buf_append(*outbuf, "null", 4); | 131 | str_buf_append(*outbuf, "null", 4); |
| 132 | break; | 132 | break; |
| 133 | 133 | ||
| 134 | case PLIST_UINT: | 134 | case PLIST_INT: |
| 135 | val = (char*)malloc(64); | 135 | val = (char*)malloc(64); |
| 136 | if (node_data->length == 16) { | 136 | if (node_data->length == 16) { |
| 137 | val_len = snprintf(val, 64, "%"PRIu64, node_data->intval); | 137 | val_len = snprintf(val, 64, "%"PRIu64, node_data->intval); |
| @@ -349,7 +349,7 @@ static int node_estimate_size(node_t *node, uint64_t *size, uint32_t depth, int | |||
| 349 | *size += data->length; | 349 | *size += data->length; |
| 350 | *size += 2; | 350 | *size += 2; |
| 351 | break; | 351 | break; |
| 352 | case PLIST_UINT: | 352 | case PLIST_INT: |
| 353 | if (data->length == 16) { | 353 | if (data->length == 16) { |
| 354 | *size += num_digits_u(data->intval); | 354 | *size += num_digits_u(data->intval); |
| 355 | } else { | 355 | } else { |
| @@ -501,10 +501,15 @@ static plist_t parse_primitive(const char* js, jsmntok_info_t* ti, int* index) | |||
| 501 | val = plist_new_node(data); | 501 | val = plist_new_node(data); |
| 502 | } else if (isdigit(str_val[0]) || (str_val[0] == '-' && str_val+1 < str_end && isdigit(str_val[1]))) { | 502 | } else if (isdigit(str_val[0]) || (str_val[0] == '-' && str_val+1 < str_end && isdigit(str_val[1]))) { |
| 503 | char* endp = (char*)str_val; | 503 | char* endp = (char*)str_val; |
| 504 | int is_neg = (str_val[0] == '-'); | ||
| 504 | int64_t intpart = parse_decimal(str_val, str_end, &endp); | 505 | int64_t intpart = parse_decimal(str_val, str_end, &endp); |
| 505 | if (endp >= str_end) { | 506 | if (endp >= str_end) { |
| 506 | /* integer */ | 507 | /* integer */ |
| 507 | val = plist_new_uint((uint64_t)intpart); | 508 | if (is_neg || intpart <= INT64_MAX) { |
| 509 | val = plist_new_int(intpart); | ||
| 510 | } else { | ||
| 511 | val = plist_new_uint((uint64_t)intpart); | ||
| 512 | } | ||
| 508 | } else if ((*endp == '.' && endp+1 < str_end && isdigit(*(endp+1))) || ((*endp == 'e' || *endp == 'E') && endp+1 < str_end && (isdigit(*(endp+1)) || ((*(endp+1) == '-') && endp+2 < str_end && isdigit(*(endp+2)))))) { | 513 | } else if ((*endp == '.' && endp+1 < str_end && isdigit(*(endp+1))) || ((*endp == 'e' || *endp == 'E') && endp+1 < str_end && (isdigit(*(endp+1)) || ((*(endp+1) == '-') && endp+2 < str_end && isdigit(*(endp+2)))))) { |
| 509 | /* floating point */ | 514 | /* floating point */ |
| 510 | double dval = (double)intpart; | 515 | double dval = (double)intpart; |
| @@ -513,7 +518,6 @@ static plist_t parse_primitive(const char* js, jsmntok_info_t* ti, int* index) | |||
| 513 | do { | 518 | do { |
| 514 | if (*endp == '.') { | 519 | if (*endp == '.') { |
| 515 | fendp++; | 520 | fendp++; |
| 516 | int is_neg = (str_val[0] == '-'); | ||
| 517 | double frac = 0; | 521 | double frac = 0; |
| 518 | double p = 0.1; | 522 | double p = 0.1; |
| 519 | while (fendp < str_end && isdigit(*fendp)) { | 523 | while (fendp < str_end && isdigit(*fendp)) { |
diff --git a/src/oplist.c b/src/oplist.c index 122440f..8936cce 100644 --- a/src/oplist.c +++ b/src/oplist.c | |||
| @@ -146,7 +146,7 @@ static int node_to_openstep(node_t* node, bytearray_t **outbuf, uint32_t depth, | |||
| 146 | 146 | ||
| 147 | switch (node_data->type) | 147 | switch (node_data->type) |
| 148 | { | 148 | { |
| 149 | case PLIST_UINT: | 149 | case PLIST_INT: |
| 150 | val = (char*)malloc(64); | 150 | val = (char*)malloc(64); |
| 151 | if (node_data->length == 16) { | 151 | if (node_data->length == 16) { |
| 152 | val_len = snprintf(val, 64, "%"PRIu64, node_data->intval); | 152 | val_len = snprintf(val, 64, "%"PRIu64, node_data->intval); |
| @@ -393,7 +393,7 @@ static int node_estimate_size(node_t *node, uint64_t *size, uint32_t depth, int | |||
| 393 | *size += data->length; | 393 | *size += data->length; |
| 394 | *size += 2; | 394 | *size += 2; |
| 395 | break; | 395 | break; |
| 396 | case PLIST_UINT: | 396 | case PLIST_INT: |
| 397 | if (data->length == 16) { | 397 | if (data->length == 16) { |
| 398 | *size += num_digits_u(data->intval); | 398 | *size += num_digits_u(data->intval); |
| 399 | } else { | 399 | } else { |
diff --git a/src/plist.c b/src/plist.c index e696f70..5d06311 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * plist.c | 2 | * plist.c |
| 3 | * Builds plist XML structures | 3 | * Builds plist XML structures |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2009-2019 Nikias Bassen, All Rights Reserved. | 5 | * Copyright (c) 2009-2023 Nikias Bassen, All Rights Reserved. |
| 6 | * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved. | 6 | * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved. |
| 7 | * Copyright (c) 2008 Zach C., All Rights Reserved. | 7 | * Copyright (c) 2008 Zach C., All Rights Reserved. |
| 8 | * | 8 | * |
| @@ -390,7 +390,16 @@ PLIST_API plist_t plist_new_bool(uint8_t val) | |||
| 390 | PLIST_API plist_t plist_new_uint(uint64_t val) | 390 | PLIST_API plist_t plist_new_uint(uint64_t val) |
| 391 | { | 391 | { |
| 392 | plist_data_t data = plist_new_plist_data(); | 392 | plist_data_t data = plist_new_plist_data(); |
| 393 | data->type = PLIST_UINT; | 393 | data->type = PLIST_INT; |
| 394 | data->intval = val; | ||
| 395 | data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t); | ||
| 396 | return plist_new_node(data); | ||
| 397 | } | ||
| 398 | |||
| 399 | PLIST_API plist_t plist_new_int(int64_t val) | ||
| 400 | { | ||
| 401 | plist_data_t data = plist_new_plist_data(); | ||
| 402 | data->type = PLIST_INT; | ||
| 394 | data->intval = val; | 403 | data->intval = val; |
| 395 | data->length = sizeof(uint64_t); | 404 | data->length = sizeof(uint64_t); |
| 396 | return plist_new_node(data); | 405 | return plist_new_node(data); |
| @@ -926,7 +935,7 @@ static void plist_get_type_and_value(plist_t node, plist_type * type, void *valu | |||
| 926 | case PLIST_BOOLEAN: | 935 | case PLIST_BOOLEAN: |
| 927 | *((char *) value) = data->boolval; | 936 | *((char *) value) = data->boolval; |
| 928 | break; | 937 | break; |
| 929 | case PLIST_UINT: | 938 | case PLIST_INT: |
| 930 | case PLIST_UID: | 939 | case PLIST_UID: |
| 931 | *((uint64_t *) value) = data->intval; | 940 | *((uint64_t *) value) = data->intval; |
| 932 | break; | 941 | break; |
| @@ -1024,12 +1033,17 @@ PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val) | |||
| 1024 | return; | 1033 | return; |
| 1025 | plist_type type = plist_get_node_type(node); | 1034 | plist_type type = plist_get_node_type(node); |
| 1026 | uint64_t length = 0; | 1035 | uint64_t length = 0; |
| 1027 | if (PLIST_UINT != type) | 1036 | if (PLIST_INT != type) |
| 1028 | return; | 1037 | return; |
| 1029 | plist_get_type_and_value(node, &type, (void *) val, &length); | 1038 | plist_get_type_and_value(node, &type, (void *) val, &length); |
| 1030 | assert(length == sizeof(uint64_t) || length == 16); | 1039 | assert(length == sizeof(uint64_t) || length == 16); |
| 1031 | } | 1040 | } |
| 1032 | 1041 | ||
| 1042 | PLIST_API void plist_get_int_val(plist_t node, int64_t * val) | ||
| 1043 | { | ||
| 1044 | plist_get_uint_val(node, (uint64_t*)val); | ||
| 1045 | } | ||
| 1046 | |||
| 1033 | PLIST_API void plist_get_uid_val(plist_t node, uint64_t * val) | 1047 | PLIST_API void plist_get_uid_val(plist_t node, uint64_t * val) |
| 1034 | { | 1048 | { |
| 1035 | if (!node || !val) | 1049 | if (!node || !val) |
| @@ -1116,7 +1130,7 @@ int plist_data_compare(const void *a, const void *b) | |||
| 1116 | switch (val_a->type) | 1130 | switch (val_a->type) |
| 1117 | { | 1131 | { |
| 1118 | case PLIST_BOOLEAN: | 1132 | case PLIST_BOOLEAN: |
| 1119 | case PLIST_UINT: | 1133 | case PLIST_INT: |
| 1120 | case PLIST_REAL: | 1134 | case PLIST_REAL: |
| 1121 | case PLIST_DATE: | 1135 | case PLIST_DATE: |
| 1122 | case PLIST_UID: | 1136 | case PLIST_UID: |
| @@ -1180,7 +1194,7 @@ static void plist_set_element_val(plist_t node, plist_type type, const void *val | |||
| 1180 | case PLIST_BOOLEAN: | 1194 | case PLIST_BOOLEAN: |
| 1181 | data->boolval = *((char *) value); | 1195 | data->boolval = *((char *) value); |
| 1182 | break; | 1196 | break; |
| 1183 | case PLIST_UINT: | 1197 | case PLIST_INT: |
| 1184 | case PLIST_UID: | 1198 | case PLIST_UID: |
| 1185 | data->intval = *((uint64_t *) value); | 1199 | data->intval = *((uint64_t *) value); |
| 1186 | break; | 1200 | break; |
| @@ -1225,7 +1239,12 @@ PLIST_API void plist_set_bool_val(plist_t node, uint8_t val) | |||
| 1225 | 1239 | ||
| 1226 | PLIST_API void plist_set_uint_val(plist_t node, uint64_t val) | 1240 | PLIST_API void plist_set_uint_val(plist_t node, uint64_t val) |
| 1227 | { | 1241 | { |
| 1228 | plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t)); | 1242 | plist_set_element_val(node, PLIST_INT, &val, (val > INT64_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t)); |
| 1243 | } | ||
| 1244 | |||
| 1245 | PLIST_API void plist_set_int_val(plist_t node, int64_t val) | ||
| 1246 | { | ||
| 1247 | plist_set_element_val(node, PLIST_INT, &val, sizeof(uint64_t)); | ||
| 1229 | } | 1248 | } |
| 1230 | 1249 | ||
| 1231 | PLIST_API void plist_set_uid_val(plist_t node, uint64_t val) | 1250 | PLIST_API void plist_set_uid_val(plist_t node, uint64_t val) |
| @@ -1259,9 +1278,42 @@ PLIST_API int plist_bool_val_is_true(plist_t boolnode) | |||
| 1259 | return (bv == 1); | 1278 | return (bv == 1); |
| 1260 | } | 1279 | } |
| 1261 | 1280 | ||
| 1281 | PLIST_API int plist_int_val_is_negative(plist_t intnode) | ||
| 1282 | { | ||
| 1283 | if (!PLIST_IS_INT(intnode)) { | ||
| 1284 | return 0; | ||
| 1285 | } | ||
| 1286 | plist_data_t data = plist_get_data(intnode); | ||
| 1287 | if (data->length == 16) { | ||
| 1288 | return 0; | ||
| 1289 | } | ||
| 1290 | if ((int64_t)data->intval < 0) { | ||
| 1291 | return 1; | ||
| 1292 | } | ||
| 1293 | return 0; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | PLIST_API int plist_int_val_compare(plist_t uintnode, int64_t cmpval) | ||
| 1297 | { | ||
| 1298 | if (!PLIST_IS_INT(uintnode)) { | ||
| 1299 | return -1; | ||
| 1300 | } | ||
| 1301 | int64_t uintval = 0; | ||
| 1302 | plist_get_int_val(uintnode, &uintval); | ||
| 1303 | if (uintval == cmpval) { | ||
| 1304 | return 0; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | if (uintval < cmpval) { | ||
| 1308 | return -1; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | return 1; | ||
| 1312 | } | ||
| 1313 | |||
| 1262 | PLIST_API int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval) | 1314 | PLIST_API int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval) |
| 1263 | { | 1315 | { |
| 1264 | if (!PLIST_IS_UINT(uintnode)) { | 1316 | if (!PLIST_IS_INT(uintnode)) { |
| 1265 | return -1; | 1317 | return -1; |
| 1266 | } | 1318 | } |
| 1267 | uint64_t uintval = 0; | 1319 | uint64_t uintval = 0; |
diff --git a/src/xplist.c b/src/xplist.c index d8f6458..cf5d818 100644 --- a/src/xplist.c +++ b/src/xplist.c | |||
| @@ -162,7 +162,7 @@ static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) | |||
| 162 | } | 162 | } |
| 163 | break; | 163 | break; |
| 164 | 164 | ||
| 165 | case PLIST_UINT: | 165 | case PLIST_INT: |
| 166 | tag = XPLIST_INT; | 166 | tag = XPLIST_INT; |
| 167 | tag_len = XPLIST_INT_LEN; | 167 | tag_len = XPLIST_INT_LEN; |
| 168 | val = (char*)malloc(64); | 168 | val = (char*)malloc(64); |
| @@ -479,7 +479,7 @@ static int node_estimate_size(node_t *node, uint64_t *size, uint32_t depth) | |||
| 479 | *size += data->length; | 479 | *size += data->length; |
| 480 | *size += (XPLIST_KEY_LEN << 1) + 6; | 480 | *size += (XPLIST_KEY_LEN << 1) + 6; |
| 481 | break; | 481 | break; |
| 482 | case PLIST_UINT: | 482 | case PLIST_INT: |
| 483 | if (data->length == 16) { | 483 | if (data->length == 16) { |
| 484 | *size += num_digits_u(data->intval); | 484 | *size += num_digits_u(data->intval); |
| 485 | } else { | 485 | } else { |
| @@ -1194,7 +1194,7 @@ static int node_from_xml(parse_ctx ctx, plist_t *plist) | |||
| 1194 | data->intval = 0; | 1194 | data->intval = 0; |
| 1195 | data->length = 8; | 1195 | data->length = 8; |
| 1196 | } | 1196 | } |
| 1197 | data->type = PLIST_UINT; | 1197 | data->type = PLIST_INT; |
| 1198 | } else if (!strcmp(tag, XPLIST_REAL)) { | 1198 | } else if (!strcmp(tag, XPLIST_REAL)) { |
| 1199 | if (!is_empty) { | 1199 | if (!is_empty) { |
| 1200 | text_part_t first_part = { NULL, 0, 0, NULL }; | 1200 | text_part_t first_part = { NULL, 0, 0, NULL }; |
diff --git a/test/Makefile.am b/test/Makefile.am index 66543ea..5326317 100644 --- a/test/Makefile.am +++ b/test/Makefile.am | |||
| @@ -8,6 +8,7 @@ AM_LDFLAGS = | |||
| 8 | noinst_PROGRAMS = \ | 8 | noinst_PROGRAMS = \ |
| 9 | plist_cmp \ | 9 | plist_cmp \ |
| 10 | plist_test \ | 10 | plist_test \ |
| 11 | integer_set_test \ | ||
| 11 | plist_btest \ | 12 | plist_btest \ |
| 12 | plist_jtest \ | 13 | plist_jtest \ |
| 13 | plist_otest | 14 | plist_otest |
| @@ -20,6 +21,9 @@ plist_cmp_LDADD = \ | |||
| 20 | plist_test_SOURCES = plist_test.c | 21 | plist_test_SOURCES = plist_test.c |
| 21 | plist_test_LDADD = $(top_builddir)/src/libplist-2.0.la | 22 | plist_test_LDADD = $(top_builddir)/src/libplist-2.0.la |
| 22 | 23 | ||
| 24 | integer_set_test_SOURCES = integer_set.c | ||
| 25 | integer_set_test_LDADD = $(top_builddir)/src/libplist-2.0.la | ||
| 26 | |||
| 23 | plist_btest_SOURCES = plist_btest.c | 27 | plist_btest_SOURCES = plist_btest.c |
| 24 | plist_btest_LDADD = $(top_builddir)/src/libplist-2.0.la | 28 | plist_btest_LDADD = $(top_builddir)/src/libplist-2.0.la |
| 25 | 29 | ||
| @@ -54,6 +58,7 @@ TESTS = \ | |||
| 54 | refsize.test \ | 58 | refsize.test \ |
| 55 | malformed_dict.test \ | 59 | malformed_dict.test \ |
| 56 | uid.test \ | 60 | uid.test \ |
| 61 | integer_set.test \ | ||
| 57 | json1.test \ | 62 | json1.test \ |
| 58 | json2.test \ | 63 | json2.test \ |
| 59 | json3.test \ | 64 | json3.test \ |
diff --git a/test/integer_set.c b/test/integer_set.c new file mode 100644 index 0000000..e25648f --- /dev/null +++ b/test/integer_set.c | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdint.h> | ||
| 3 | #include <inttypes.h> | ||
| 4 | #include <stdlib.h> | ||
| 5 | |||
| 6 | #include <string.h> | ||
| 7 | #include <plist/plist.h> | ||
| 8 | |||
| 9 | void print_plist(plist_t pl) | ||
| 10 | { | ||
| 11 | char *xml = NULL; | ||
| 12 | uint32_t xlen = 0; | ||
| 13 | plist_to_xml(pl, &xml, &xlen); | ||
| 14 | if (xml) { | ||
| 15 | printf("%s\n", xml); | ||
| 16 | } | ||
| 17 | free(xml); | ||
| 18 | } | ||
| 19 | |||
| 20 | int main(int argc, char** argv) | ||
| 21 | { | ||
| 22 | int err = 0; | ||
| 23 | char *xml = NULL; | ||
| 24 | uint32_t xlen = 0; | ||
| 25 | plist_t iii = plist_new_int(0); | ||
| 26 | |||
| 27 | /* test 1 */ | ||
| 28 | plist_set_uint_val(iii, 0x8000000000000000LL); | ||
| 29 | plist_to_xml(iii, &xml, &xlen); | ||
| 30 | const char* match1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
| 31 | "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" | ||
| 32 | "<plist version=\"1.0\">\n" | ||
| 33 | "<integer>9223372036854775808</integer>\n" | ||
| 34 | "</plist>\n"; | ||
| 35 | if (strcmp(xml, match1) != 0) { | ||
| 36 | printf("ERROR: plist_set_uint_val with 0x8000000000000000LL failed\n"); | ||
| 37 | err++; | ||
| 38 | } else { | ||
| 39 | printf("SUCCESS: plist_set_uint_val with 0x8000000000000000LL\n"); | ||
| 40 | } | ||
| 41 | free(xml); | ||
| 42 | xml = NULL; | ||
| 43 | |||
| 44 | /* test 2 */ | ||
| 45 | plist_set_int_val(iii, 0x8000000000000000LL); | ||
| 46 | plist_to_xml(iii, &xml, &xlen); | ||
| 47 | const char* match2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
| 48 | "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" | ||
| 49 | "<plist version=\"1.0\">\n" | ||
| 50 | "<integer>-9223372036854775808</integer>\n" | ||
| 51 | "</plist>\n"; | ||
| 52 | if (strcmp(xml, match2) != 0) { | ||
| 53 | printf("ERROR: plist_set_int_val with 0x8000000000000000LL failed\n"); | ||
| 54 | err++; | ||
| 55 | } else { | ||
| 56 | printf("SUCCESS: plist_set_int_val with 0x8000000000000000LL\n"); | ||
| 57 | } | ||
| 58 | free(xml); | ||
| 59 | xml = NULL; | ||
| 60 | |||
| 61 | /* test 3 */ | ||
| 62 | plist_set_uint_val(iii, (uint64_t)-1LL); | ||
| 63 | plist_to_xml(iii, &xml, &xlen); | ||
| 64 | const char* match3 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
| 65 | "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" | ||
| 66 | "<plist version=\"1.0\">\n" | ||
| 67 | "<integer>18446744073709551615</integer>\n" | ||
| 68 | "</plist>\n"; | ||
| 69 | if (strcmp(xml, match3) != 0) { | ||
| 70 | printf("ERROR: plist_set_uint_val with (uint64_t)-1LL failed\n"); | ||
| 71 | err++; | ||
| 72 | } else { | ||
| 73 | printf("SUCCESS: plist_set_uint_val with (uint64_t)-1LL\n"); | ||
| 74 | } | ||
| 75 | free(xml); | ||
| 76 | xml = NULL; | ||
| 77 | |||
| 78 | /* test 4 */ | ||
| 79 | plist_set_int_val(iii, -1LL); | ||
| 80 | plist_to_xml(iii, &xml, &xlen); | ||
| 81 | const char* match4 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
| 82 | "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" | ||
| 83 | "<plist version=\"1.0\">\n" | ||
| 84 | "<integer>-1</integer>\n" | ||
| 85 | "</plist>\n"; | ||
| 86 | if (strcmp(xml, match4) != 0) { | ||
| 87 | printf("ERROR: plist_set_int_val with -1LL failed\n"); | ||
| 88 | err++; | ||
| 89 | } else { | ||
| 90 | printf("SUCCESS: plist_set_int_val with -1LL\n"); | ||
| 91 | } | ||
| 92 | free(xml); | ||
| 93 | xml = NULL; | ||
| 94 | |||
| 95 | /* test 5 */ | ||
| 96 | plist_set_uint_val(iii, 0x8000000000000001LL); | ||
| 97 | plist_to_xml(iii, &xml, &xlen); | ||
| 98 | const char* match5 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
| 99 | "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" | ||
| 100 | "<plist version=\"1.0\">\n" | ||
| 101 | "<integer>9223372036854775809</integer>\n" | ||
| 102 | "</plist>\n"; | ||
| 103 | if (strcmp(xml, match5) != 0) { | ||
| 104 | printf("ERROR: plist_set_uint_val with 0x8000000000000001LL failed\n"); | ||
| 105 | err++; | ||
| 106 | } else { | ||
| 107 | printf("SUCCESS: plist_set_uint_val with 0x8000000000000001LL\n"); | ||
| 108 | } | ||
| 109 | free(xml); | ||
| 110 | xml = NULL; | ||
| 111 | |||
| 112 | /* test 6 */ | ||
| 113 | plist_set_uint_val(iii, 18446744073709551615uLL); | ||
| 114 | plist_to_xml(iii, &xml, &xlen); | ||
| 115 | const char* match6 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" | ||
| 116 | "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" | ||
| 117 | "<plist version=\"1.0\">\n" | ||
| 118 | "<integer>18446744073709551615</integer>\n" | ||
| 119 | "</plist>\n"; | ||
| 120 | if (strcmp(xml, match6) != 0) { | ||
| 121 | printf("ERROR: plist_set_uint_val with 0x8000000000000001LL failed\n"); | ||
| 122 | err++; | ||
| 123 | } else { | ||
| 124 | printf("SUCCESS: plist_set_uint_val with 0x8000000000000001LL\n"); | ||
| 125 | } | ||
| 126 | free(xml); | ||
| 127 | xml = NULL; | ||
| 128 | |||
| 129 | return (err > 0) ? EXIT_FAILURE : EXIT_SUCCESS; | ||
| 130 | } | ||
diff --git a/test/integer_set.test b/test/integer_set.test new file mode 100755 index 0000000..b917663 --- /dev/null +++ b/test/integer_set.test | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | ## -*- sh -*- | ||
| 2 | |||
| 3 | set -e | ||
| 4 | |||
| 5 | $top_builddir/test/integer_set_test | ||
