mirror of
https://github.com/libimobiledevice/libplist.git
synced 2026-05-17 20:30:34 +00:00
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:
+2
-1
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 };
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
## -*- sh -*-
|
||||
|
||||
set -e
|
||||
|
||||
$top_builddir/test/integer_set_test
|
||||
Reference in New Issue
Block a user