summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2023-01-16 04:25:52 +0100
committerGravatar Nikias Bassen2023-01-16 04:25:52 +0100
commitd886885b0ec2506fa2caf0986a3d0e496fea91c2 (patch)
tree58bc4bcd1963ea885abd60a65bf87a2685526714 /src
parent47a7fbe438ee7350a2b151e007f07043ef596775 (diff)
downloadlibplist-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.
Diffstat (limited to 'src')
-rw-r--r--src/Integer.cpp35
-rw-r--r--src/Key.cpp2
-rw-r--r--src/Node.cpp4
-rw-r--r--src/Real.cpp2
-rw-r--r--src/String.cpp2
-rw-r--r--src/bplist.c24
-rw-r--r--src/jplist.c12
-rw-r--r--src/oplist.c4
-rw-r--r--src/plist.c68
-rw-r--r--src/xplist.c6
10 files changed, 121 insertions, 38 deletions
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 @@
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
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)
{
}
-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());
}
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)
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:
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)
{
}
-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());
}
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)
{
}
-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());
}
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
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 {
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
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)) {
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,
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 {
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 @@
* 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;
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)
}
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 };