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.
This commit is contained in:
Nikias Bassen
2023-01-16 04:25:52 +01:00
parent 47a7fbe438
commit d886885b0e
17 changed files with 382 additions and 62 deletions
+2 -1
View File
@@ -19,7 +19,8 @@ cdef class Bool(Node):
cdef class Integer(Node):
cpdef set_value(self, object value)
cpdef uint64_t get_value(self)
cpdef get_value(self)
cpdef bint is_negative(self)
cdef class Uid(Node):
cpdef set_value(self, object value)
+45 -10
View File
@@ -5,7 +5,7 @@ from libc.stdint cimport *
cdef extern from *:
ctypedef enum plist_type:
PLIST_BOOLEAN,
PLIST_UINT,
PLIST_INT,
PLIST_REAL,
PLIST_STRING,
PLIST_ARRAY,
@@ -14,6 +14,7 @@ cdef extern from *:
PLIST_DATA,
PLIST_KEY,
PLIST_UID,
PLIST_NULL,
PLIST_NONE
plist_t plist_new_bool(uint8_t val)
@@ -24,6 +25,10 @@ cdef extern from *:
void plist_get_uint_val(plist_t node, uint64_t *val)
void plist_set_uint_val(plist_t node, uint64_t val)
plist_t plist_new_int(int64_t val)
void plist_get_int_val(plist_t node, int64_t *val)
void plist_set_int_val(plist_t node, int64_t val)
plist_t plist_new_real(double val)
void plist_get_real_val(plist_t node, double *val)
void plist_set_real_val(plist_t node, double val)
@@ -47,6 +52,8 @@ cdef extern from *:
void plist_get_data_val(plist_t node, char **val, uint64_t * length)
void plist_set_data_val(plist_t node, char *val, uint64_t length)
plist_t plist_new_null();
plist_t plist_new_dict()
int plist_dict_get_size(plist_t node)
plist_t plist_dict_get_item(plist_t node, char* key)
@@ -77,6 +84,8 @@ cdef extern from *:
void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist)
void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist)
int plist_int_val_is_negative(plist_t node);
cdef class Node:
def __init__(self, *args, **kwargs):
self._c_managed = True
@@ -177,13 +186,15 @@ cdef Bool Bool_factory(plist_t c_node, bint managed=True):
cdef class Integer(Node):
def __cinit__(self, object value=None, *args, **kwargs):
if value is None:
self._c_node = plist_new_uint(0)
self._c_node = plist_new_int(0)
else:
self._c_node = plist_new_uint(int(value))
if value < 0 or value <= INT64_MAX:
self._c_node = plist_new_int(int(value))
else:
self._c_node = plist_new_uint(int(value))
def __repr__(self):
cdef uint64_t i = self.get_value()
return '<Integer: %s>' % i
return '<Integer: %s>' % self.get_value()
def __int__(self):
return self.get_value()
@@ -210,10 +221,18 @@ cdef class Integer(Node):
cpdef set_value(self, object value):
plist_set_uint_val(self._c_node, int(value))
cpdef uint64_t get_value(self):
cdef uint64_t value
plist_get_uint_val(self._c_node, &value)
return value
cpdef get_value(self):
cdef int64_t ivalue
cdef uint64_t uvalue
if self.is_negative():
plist_get_int_val(self._c_node, &ivalue)
return int(ivalue)
else:
plist_get_uint_val(self._c_node, &uvalue)
return int(uvalue)
cpdef bint is_negative(self):
return plist_int_val_is_negative(self._c_node);
cdef Integer Integer_factory(plist_t c_node, bint managed=True):
cdef Integer instance = Integer.__new__(Integer)
@@ -314,6 +333,20 @@ cdef Uid Uid_factory(plist_t c_node, bint managed=True):
instance._c_node = c_node
return instance
cdef class Null(Node):
def __cinit__(self, object value=None, *args, **kwargs):
self._c_node = plist_new_null()
def __repr__(self):
cdef uint64_t i = self.get_value()
return '<Null>'
cdef Null Null_factory(plist_t c_node, bint managed=True):
cdef Null instance = Null.__new__(Null)
instance._c_managed = managed
instance._c_node = c_node
return instance
from cpython cimport PY_MAJOR_VERSION
cdef class Key(Node):
@@ -833,7 +866,7 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True):
cdef plist_type t = plist_get_node_type(c_plist)
if t == PLIST_BOOLEAN:
return Bool_factory(c_plist, managed)
if t == PLIST_UINT:
if t == PLIST_INT:
return Integer_factory(c_plist, managed)
if t == PLIST_KEY:
return Key_factory(c_plist, managed)
@@ -851,6 +884,8 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True):
return Data_factory(c_plist, managed)
if t == PLIST_UID:
return Uid_factory(c_plist, managed)
if t == PLIST_NULL:
return Null_factory(c_plist, managed)
if t == PLIST_NONE:
return None
+7 -1
View File
@@ -35,12 +35,18 @@ public :
Integer(const Integer& i);
Integer& operator=(const Integer& i);
Integer(uint64_t i);
Integer(int64_t i);
virtual ~Integer();
Node* Clone() const;
void SetValue(int64_t i);
void SetValue(uint64_t i);
uint64_t GetValue() const;
void SetUnsignedValue(uint64_t i);
int64_t GetValue() const;
uint64_t GetUnsignedValue() const;
bool isNegative() const;
};
};
+67 -12
View File
@@ -3,7 +3,7 @@
* @brief Main include of libplist
* \internal
*
* Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2012-2023 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2008-2009 Jonathan Beck, All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
@@ -104,7 +104,7 @@ extern "C"
typedef enum
{
PLIST_BOOLEAN, /**< Boolean, scalar type */
PLIST_UINT, /**< Unsigned integer, scalar type */
PLIST_INT, /**< Integer, scalar type */
PLIST_REAL, /**< Real, scalar type */
PLIST_STRING, /**< ASCII string, scalar type */
PLIST_ARRAY, /**< Ordered array, structured type */
@@ -117,6 +117,9 @@ extern "C"
PLIST_NONE /**< No type */
} plist_type;
/* for backwards compatibility */
#define PLIST_UINT PLIST_INT
/**
* libplist error values
*/
@@ -171,14 +174,27 @@ extern "C"
plist_t plist_new_bool(uint8_t val);
/**
* Create a new plist_t type #PLIST_UINT
* Create a new plist_t type #PLIST_INT with an unsigned integer value
*
* @param val the unsigned integer value
* @return the created item
* @sa #plist_type
* @note The value is always stored as uint64_t internally.
* Use #plist_get_uint_val or #plist_get_int_val to get the unsigned or signed value.
*/
plist_t plist_new_uint(uint64_t val);
/**
* Create a new plist_t type #PLIST_INT with a signed integer value
*
* @param val the signed integer value
* @return the created item
* @sa #plist_type
* @note The value is always stored as uint64_t internally.
* Use #plist_get_uint_val or #plist_get_int_val to get the unsigned or signed value.
*/
plist_t plist_new_int(int64_t val);
/**
* Create a new plist_t type #PLIST_REAL
*
@@ -509,14 +525,23 @@ extern "C"
void plist_get_bool_val(plist_t node, uint8_t * val);
/**
* Get the value of a #PLIST_UINT node.
* This function does nothing if node is not of type #PLIST_UINT
* Get the unsigned integer value of a #PLIST_INT node.
* This function does nothing if node is not of type #PLIST_INT
*
* @param node the node
* @param val a pointer to a uint64_t variable.
*/
void plist_get_uint_val(plist_t node, uint64_t * val);
/**
* Get the signed integer value of a #PLIST_INT node.
* This function does nothing if node is not of type #PLIST_INT
*
* @param node the node
* @param val a pointer to a int64_t variable.
*/
void plist_get_int_val(plist_t node, int64_t * val);
/**
* Get the value of a #PLIST_REAL node.
* This function does nothing if node is not of type #PLIST_REAL
@@ -607,13 +632,22 @@ extern "C"
/**
* Set the value of a node.
* Forces type of node to #PLIST_UINT
* Forces type of node to #PLIST_INT
*
* @param node the node
* @param val the unsigned integer value
*/
void plist_set_uint_val(plist_t node, uint64_t val);
/**
* Set the value of a node.
* Forces type of node to #PLIST_INT
*
* @param node the node
* @param val the signed integer value
*/
void plist_set_int_val(plist_t node, int64_t val);
/**
* Set the value of a node.
* Forces type of node to #PLIST_REAL
@@ -823,7 +857,7 @@ extern "C"
/* Helper macros for the different plist types */
#define PLIST_IS_BOOLEAN(__plist) _PLIST_IS_TYPE(__plist, BOOLEAN)
#define PLIST_IS_UINT(__plist) _PLIST_IS_TYPE(__plist, UINT)
#define PLIST_IS_INT(__plist) _PLIST_IS_TYPE(__plist, INT)
#define PLIST_IS_REAL(__plist) _PLIST_IS_TYPE(__plist, REAL)
#define PLIST_IS_STRING(__plist) _PLIST_IS_TYPE(__plist, STRING)
#define PLIST_IS_ARRAY(__plist) _PLIST_IS_TYPE(__plist, ARRAY)
@@ -832,21 +866,42 @@ extern "C"
#define PLIST_IS_DATA(__plist) _PLIST_IS_TYPE(__plist, DATA)
#define PLIST_IS_KEY(__plist) _PLIST_IS_TYPE(__plist, KEY)
#define PLIST_IS_UID(__plist) _PLIST_IS_TYPE(__plist, UID)
/* for backwards compatibility */
#define PLIST_IS_UINT PLIST_IS_INT
/**
* Helper function to check the value of a PLIST_BOOL node.
*
* @param boolnode node of type PLIST_BOOL
* @return 1 if the boolean node has a value of TRUE, 0 if FALSE,
* or -1 if the node is not of type PLIST_BOOL
* @return 1 if the boolean node has a value of TRUE or 0 if FALSE.
*/
int plist_bool_val_is_true(plist_t boolnode);
/**
* Helper function to compare the value of a PLIST_UINT node against
* a given value.
* Helper function to test if a given #PLIST_INT node's value is negative
*
* @param uintnode node of type PLIST_UINT
* @param intnode node of type PLIST_INT
* @return 1 if the node's value is negative, or 0 if positive.
*/
int plist_int_val_is_negative(plist_t intnode);
/**
* Helper function to compare the value of a PLIST_INT node against
* a given signed integer value.
*
* @param uintnode node of type PLIST_INT
* @param cmpval value to compare against
* @return 0 if the node's value and cmpval are equal,
* 1 if the node's value is greater than cmpval,
* or -1 if the node's value is less than cmpval.
*/
int plist_int_val_compare(plist_t uintnode, int64_t cmpval);
/**
* Helper function to compare the value of a PLIST_INT node against
* a given unsigned integer value.
*
* @param uintnode node of type PLIST_INT
* @param cmpval value to compare against
* @return 0 if the node's value and cmpval are equal,
* 1 if the node's value is greater than cmpval,
+31 -4
View File
@@ -24,7 +24,7 @@
namespace PList
{
Integer::Integer(Node* parent) : Node(PLIST_UINT, parent)
Integer::Integer(Node* parent) : Node(PLIST_INT, parent)
{
}
@@ -32,7 +32,7 @@ Integer::Integer(plist_t node, Node* parent) : Node(node, parent)
{
}
Integer::Integer(const PList::Integer& i) : Node(PLIST_UINT)
Integer::Integer(const PList::Integer& i) : Node(PLIST_INT)
{
plist_set_uint_val(_node, i.GetValue());
}
@@ -44,11 +44,16 @@ Integer& Integer::operator=(const PList::Integer& i)
return *this;
}
Integer::Integer(uint64_t i) : Node(PLIST_UINT)
Integer::Integer(uint64_t i) : Node(PLIST_INT)
{
plist_set_uint_val(_node, i);
}
Integer::Integer(int64_t i) : Node(PLIST_INT)
{
plist_set_int_val(_node, i);
}
Integer::~Integer()
{
}
@@ -58,16 +63,38 @@ Node* Integer::Clone() const
return new Integer(*this);
}
void Integer::SetValue(int64_t i)
{
plist_set_int_val(_node, i);
}
void Integer::SetValue(uint64_t i)
{
plist_set_uint_val(_node, i);
}
uint64_t Integer::GetValue() const
void Integer::SetUnsignedValue(uint64_t i)
{
plist_set_uint_val(_node, i);
}
int64_t Integer::GetValue() const
{
int64_t i = 0;
plist_get_int_val(_node, &i);
return i;
}
uint64_t Integer::GetUnsignedValue() const
{
uint64_t i = 0;
plist_get_uint_val(_node, &i);
return i;
}
bool Integer::isNegative() const
{
return plist_int_val_is_negative(_node);
}
} // namespace PList
+1 -1
View File
@@ -32,7 +32,7 @@ Key::Key(plist_t node, Node* parent) : Node(node, parent)
{
}
Key::Key(const PList::Key& k) : Node(PLIST_UINT)
Key::Key(const PList::Key& k) : Node(PLIST_INT)
{
plist_set_key_val(_node, k.GetValue().c_str());
}
+2 -2
View File
@@ -52,7 +52,7 @@ Node::Node(plist_type type, Node* parent) : _parent(parent)
case PLIST_BOOLEAN:
_node = plist_new_bool(0);
break;
case PLIST_UINT:
case PLIST_INT:
_node = plist_new_uint(0);
break;
case PLIST_REAL:
@@ -134,7 +134,7 @@ Node* Node::FromPlist(plist_t node, Node* parent)
case PLIST_BOOLEAN:
ret = new Boolean(node, parent);
break;
case PLIST_UINT:
case PLIST_INT:
ret = new Integer(node, parent);
break;
case PLIST_REAL:
+1 -1
View File
@@ -32,7 +32,7 @@ Real::Real(plist_t node, Node* parent) : Node(node, parent)
{
}
Real::Real(const PList::Real& d) : Node(PLIST_UINT)
Real::Real(const PList::Real& d) : Node(PLIST_INT)
{
plist_set_real_val(_node, d.GetValue());
}
+1 -1
View File
@@ -32,7 +32,7 @@ String::String(plist_t node, Node* parent) : Node(node, parent)
{
}
String::String(const PList::String& s) : Node(PLIST_UINT)
String::String(const PList::String& s) : Node(PLIST_INT)
{
plist_set_string_val(_node, s.GetValue().c_str());
}
+12 -12
View File
@@ -62,7 +62,7 @@ enum
BPLIST_FALSE = 0x08,
BPLIST_TRUE = 0x09,
BPLIST_FILL = 0x0F, /* will be used for length grabbing */
BPLIST_UINT = 0x10,
BPLIST_INT = 0x10,
BPLIST_REAL = 0x20,
BPLIST_DATE = 0x30,
BPLIST_DATA = 0x40,
@@ -229,7 +229,7 @@ void plist_bin_deinit(void)
static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node_index);
static plist_t parse_uint_node(const char **bnode, uint8_t size)
static plist_t parse_int_node(const char **bnode, uint8_t size)
{
plist_data_t data = plist_new_plist_data();
@@ -254,7 +254,7 @@ static plist_t parse_uint_node(const char **bnode, uint8_t size)
data->intval = UINT_TO_HOST(*bnode, size);
(*bnode) += size;
data->type = PLIST_UINT;
data->type = PLIST_INT;
return node_create(NULL, data);
}
@@ -583,8 +583,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
case BPLIST_DICT:
{
uint16_t next_size = **object & BPLIST_FILL;
if ((**object & BPLIST_MASK) != BPLIST_UINT) {
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);
if ((**object & BPLIST_MASK) != BPLIST_INT) {
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);
return NULL;
}
(*object)++;
@@ -641,12 +641,12 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
return NULL;
}
case BPLIST_UINT:
case BPLIST_INT:
if (pobject + (uint64_t)(1 << size) > poffset_table) {
PLIST_BIN_ERR("%s: BPLIST_UINT data bytes point outside of valid range\n", __func__);
PLIST_BIN_ERR("%s: BPLIST_INT data bytes point outside of valid range\n", __func__);
return NULL;
}
return parse_uint_node(object, size);
return parse_int_node(object, size);
case BPLIST_REAL:
if (pobject + (uint64_t)(1 << size) > poffset_table) {
@@ -896,7 +896,7 @@ static unsigned int plist_data_hash(const void* key)
switch (data->type)
{
case PLIST_BOOLEAN:
case PLIST_UINT:
case PLIST_INT:
case PLIST_REAL:
case PLIST_DATE:
case PLIST_UID:
@@ -973,7 +973,7 @@ static void write_int(bytearray_t * bplist, uint64_t val)
//do not write 3bytes int node
if (size == 3)
size++;
sz = BPLIST_UINT | Log2(size);
sz = BPLIST_INT | Log2(size);
val = be64toh(val);
byte_array_append(bplist, &sz, 1);
@@ -982,7 +982,7 @@ static void write_int(bytearray_t * bplist, uint64_t val)
static void write_uint(bytearray_t * bplist, uint64_t val)
{
uint8_t sz = BPLIST_UINT | 4;
uint8_t sz = BPLIST_INT | 4;
uint64_t zero = 0;
val = be64toh(val);
@@ -1346,7 +1346,7 @@ PLIST_API plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * l
byte_array_append(bplist_buff, &b, 1);
break;
}
case PLIST_UINT:
case PLIST_INT:
if (data->length == 16) {
write_uint(bplist_buff, data->intval);
} else {
+8 -4
View File
@@ -131,7 +131,7 @@ static int node_to_json(node_t* node, bytearray_t **outbuf, uint32_t depth, int
str_buf_append(*outbuf, "null", 4);
break;
case PLIST_UINT:
case PLIST_INT:
val = (char*)malloc(64);
if (node_data->length == 16) {
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
*size += data->length;
*size += 2;
break;
case PLIST_UINT:
case PLIST_INT:
if (data->length == 16) {
*size += num_digits_u(data->intval);
} else {
@@ -501,10 +501,15 @@ static plist_t parse_primitive(const char* js, jsmntok_info_t* ti, int* index)
val = plist_new_node(data);
} else if (isdigit(str_val[0]) || (str_val[0] == '-' && str_val+1 < str_end && isdigit(str_val[1]))) {
char* endp = (char*)str_val;
int is_neg = (str_val[0] == '-');
int64_t intpart = parse_decimal(str_val, str_end, &endp);
if (endp >= str_end) {
/* integer */
val = plist_new_uint((uint64_t)intpart);
if (is_neg || intpart <= INT64_MAX) {
val = plist_new_int(intpart);
} else {
val = plist_new_uint((uint64_t)intpart);
}
} 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)))))) {
/* floating point */
double dval = (double)intpart;
@@ -513,7 +518,6 @@ static plist_t parse_primitive(const char* js, jsmntok_info_t* ti, int* index)
do {
if (*endp == '.') {
fendp++;
int is_neg = (str_val[0] == '-');
double frac = 0;
double p = 0.1;
while (fendp < str_end && isdigit(*fendp)) {
+2 -2
View File
@@ -146,7 +146,7 @@ static int node_to_openstep(node_t* node, bytearray_t **outbuf, uint32_t depth,
switch (node_data->type)
{
case PLIST_UINT:
case PLIST_INT:
val = (char*)malloc(64);
if (node_data->length == 16) {
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
*size += data->length;
*size += 2;
break;
case PLIST_UINT:
case PLIST_INT:
if (data->length == 16) {
*size += num_digits_u(data->intval);
} else {
+60 -8
View File
@@ -2,7 +2,7 @@
* plist.c
* Builds plist XML structures
*
* Copyright (c) 2009-2019 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2009-2023 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved.
* Copyright (c) 2008 Zach C., All Rights Reserved.
*
@@ -390,7 +390,16 @@ PLIST_API plist_t plist_new_bool(uint8_t val)
PLIST_API plist_t plist_new_uint(uint64_t val)
{
plist_data_t data = plist_new_plist_data();
data->type = PLIST_UINT;
data->type = PLIST_INT;
data->intval = val;
data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t);
return plist_new_node(data);
}
PLIST_API plist_t plist_new_int(int64_t val)
{
plist_data_t data = plist_new_plist_data();
data->type = PLIST_INT;
data->intval = val;
data->length = sizeof(uint64_t);
return plist_new_node(data);
@@ -926,7 +935,7 @@ static void plist_get_type_and_value(plist_t node, plist_type * type, void *valu
case PLIST_BOOLEAN:
*((char *) value) = data->boolval;
break;
case PLIST_UINT:
case PLIST_INT:
case PLIST_UID:
*((uint64_t *) value) = data->intval;
break;
@@ -1024,12 +1033,17 @@ PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val)
return;
plist_type type = plist_get_node_type(node);
uint64_t length = 0;
if (PLIST_UINT != type)
if (PLIST_INT != type)
return;
plist_get_type_and_value(node, &type, (void *) val, &length);
assert(length == sizeof(uint64_t) || length == 16);
}
PLIST_API void plist_get_int_val(plist_t node, int64_t * val)
{
plist_get_uint_val(node, (uint64_t*)val);
}
PLIST_API void plist_get_uid_val(plist_t node, uint64_t * val)
{
if (!node || !val)
@@ -1116,7 +1130,7 @@ int plist_data_compare(const void *a, const void *b)
switch (val_a->type)
{
case PLIST_BOOLEAN:
case PLIST_UINT:
case PLIST_INT:
case PLIST_REAL:
case PLIST_DATE:
case PLIST_UID:
@@ -1180,7 +1194,7 @@ static void plist_set_element_val(plist_t node, plist_type type, const void *val
case PLIST_BOOLEAN:
data->boolval = *((char *) value);
break;
case PLIST_UINT:
case PLIST_INT:
case PLIST_UID:
data->intval = *((uint64_t *) value);
break;
@@ -1225,7 +1239,12 @@ PLIST_API void plist_set_bool_val(plist_t node, uint8_t val)
PLIST_API void plist_set_uint_val(plist_t node, uint64_t val)
{
plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t));
plist_set_element_val(node, PLIST_INT, &val, (val > INT64_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t));
}
PLIST_API void plist_set_int_val(plist_t node, int64_t val)
{
plist_set_element_val(node, PLIST_INT, &val, sizeof(uint64_t));
}
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)
return (bv == 1);
}
PLIST_API int plist_int_val_is_negative(plist_t intnode)
{
if (!PLIST_IS_INT(intnode)) {
return 0;
}
plist_data_t data = plist_get_data(intnode);
if (data->length == 16) {
return 0;
}
if ((int64_t)data->intval < 0) {
return 1;
}
return 0;
}
PLIST_API int plist_int_val_compare(plist_t uintnode, int64_t cmpval)
{
if (!PLIST_IS_INT(uintnode)) {
return -1;
}
int64_t uintval = 0;
plist_get_int_val(uintnode, &uintval);
if (uintval == cmpval) {
return 0;
}
if (uintval < cmpval) {
return -1;
}
return 1;
}
PLIST_API int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval)
{
if (!PLIST_IS_UINT(uintnode)) {
if (!PLIST_IS_INT(uintnode)) {
return -1;
}
uint64_t uintval = 0;
+3 -3
View File
@@ -162,7 +162,7 @@ static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
}
break;
case PLIST_UINT:
case PLIST_INT:
tag = XPLIST_INT;
tag_len = XPLIST_INT_LEN;
val = (char*)malloc(64);
@@ -479,7 +479,7 @@ static int node_estimate_size(node_t *node, uint64_t *size, uint32_t depth)
*size += data->length;
*size += (XPLIST_KEY_LEN << 1) + 6;
break;
case PLIST_UINT:
case PLIST_INT:
if (data->length == 16) {
*size += num_digits_u(data->intval);
} else {
@@ -1194,7 +1194,7 @@ static int node_from_xml(parse_ctx ctx, plist_t *plist)
data->intval = 0;
data->length = 8;
}
data->type = PLIST_UINT;
data->type = PLIST_INT;
} else if (!strcmp(tag, XPLIST_REAL)) {
if (!is_empty) {
text_part_t first_part = { NULL, 0, 0, NULL };
+5
View File
@@ -8,6 +8,7 @@ AM_LDFLAGS =
noinst_PROGRAMS = \
plist_cmp \
plist_test \
integer_set_test \
plist_btest \
plist_jtest \
plist_otest
@@ -20,6 +21,9 @@ plist_cmp_LDADD = \
plist_test_SOURCES = plist_test.c
plist_test_LDADD = $(top_builddir)/src/libplist-2.0.la
integer_set_test_SOURCES = integer_set.c
integer_set_test_LDADD = $(top_builddir)/src/libplist-2.0.la
plist_btest_SOURCES = plist_btest.c
plist_btest_LDADD = $(top_builddir)/src/libplist-2.0.la
@@ -54,6 +58,7 @@ TESTS = \
refsize.test \
malformed_dict.test \
uid.test \
integer_set.test \
json1.test \
json2.test \
json3.test \
+130
View File
@@ -0,0 +1,130 @@
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <plist/plist.h>
void print_plist(plist_t pl)
{
char *xml = NULL;
uint32_t xlen = 0;
plist_to_xml(pl, &xml, &xlen);
if (xml) {
printf("%s\n", xml);
}
free(xml);
}
int main(int argc, char** argv)
{
int err = 0;
char *xml = NULL;
uint32_t xlen = 0;
plist_t iii = plist_new_int(0);
/* test 1 */
plist_set_uint_val(iii, 0x8000000000000000LL);
plist_to_xml(iii, &xml, &xlen);
const char* match1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<integer>9223372036854775808</integer>\n"
"</plist>\n";
if (strcmp(xml, match1) != 0) {
printf("ERROR: plist_set_uint_val with 0x8000000000000000LL failed\n");
err++;
} else {
printf("SUCCESS: plist_set_uint_val with 0x8000000000000000LL\n");
}
free(xml);
xml = NULL;
/* test 2 */
plist_set_int_val(iii, 0x8000000000000000LL);
plist_to_xml(iii, &xml, &xlen);
const char* match2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<integer>-9223372036854775808</integer>\n"
"</plist>\n";
if (strcmp(xml, match2) != 0) {
printf("ERROR: plist_set_int_val with 0x8000000000000000LL failed\n");
err++;
} else {
printf("SUCCESS: plist_set_int_val with 0x8000000000000000LL\n");
}
free(xml);
xml = NULL;
/* test 3 */
plist_set_uint_val(iii, (uint64_t)-1LL);
plist_to_xml(iii, &xml, &xlen);
const char* match3 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<integer>18446744073709551615</integer>\n"
"</plist>\n";
if (strcmp(xml, match3) != 0) {
printf("ERROR: plist_set_uint_val with (uint64_t)-1LL failed\n");
err++;
} else {
printf("SUCCESS: plist_set_uint_val with (uint64_t)-1LL\n");
}
free(xml);
xml = NULL;
/* test 4 */
plist_set_int_val(iii, -1LL);
plist_to_xml(iii, &xml, &xlen);
const char* match4 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<integer>-1</integer>\n"
"</plist>\n";
if (strcmp(xml, match4) != 0) {
printf("ERROR: plist_set_int_val with -1LL failed\n");
err++;
} else {
printf("SUCCESS: plist_set_int_val with -1LL\n");
}
free(xml);
xml = NULL;
/* test 5 */
plist_set_uint_val(iii, 0x8000000000000001LL);
plist_to_xml(iii, &xml, &xlen);
const char* match5 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<integer>9223372036854775809</integer>\n"
"</plist>\n";
if (strcmp(xml, match5) != 0) {
printf("ERROR: plist_set_uint_val with 0x8000000000000001LL failed\n");
err++;
} else {
printf("SUCCESS: plist_set_uint_val with 0x8000000000000001LL\n");
}
free(xml);
xml = NULL;
/* test 6 */
plist_set_uint_val(iii, 18446744073709551615uLL);
plist_to_xml(iii, &xml, &xlen);
const char* match6 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<integer>18446744073709551615</integer>\n"
"</plist>\n";
if (strcmp(xml, match6) != 0) {
printf("ERROR: plist_set_uint_val with 0x8000000000000001LL failed\n");
err++;
} else {
printf("SUCCESS: plist_set_uint_val with 0x8000000000000001LL\n");
}
free(xml);
xml = NULL;
return (err > 0) ? EXIT_FAILURE : EXIT_SUCCESS;
}
+5
View File
@@ -0,0 +1,5 @@
## -*- sh -*-
set -e
$top_builddir/test/integer_set_test