Skip to content

Commit

Permalink
Rename PLIST_UINT to PLIST_INT and add plist_new_int() and plist_get_…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
nikias committed Jan 16, 2023
1 parent 47a7fbe commit d886885
Show file tree
Hide file tree
Showing 17 changed files with 382 additions and 62 deletions.
3 changes: 2 additions & 1 deletion cython/plist.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
55 changes: 45 additions & 10 deletions cython/plist.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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)
Expand All @@ -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

Expand Down
8 changes: 7 additions & 1 deletion include/plist/Integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

};
Expand Down
79 changes: 67 additions & 12 deletions include/plist/plist.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand All @@ -117,6 +117,9 @@ extern "C"
PLIST_NONE /**< No type */
} plist_type;

/* for backwards compatibility */
#define PLIST_UINT PLIST_INT

/**
* libplist error values
*/
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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 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_UINT
* @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,
Expand Down
35 changes: 31 additions & 4 deletions src/Integer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
namespace PList
{

Integer::Integer(Node* parent) : Node(PLIST_UINT, parent)
Integer::Integer(Node* parent) : Node(PLIST_INT, parent)
{
}

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());
}
Expand All @@ -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()
{
}
Expand All @@ -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
Loading

0 comments on commit d886885

Please sign in to comment.