summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml2
-rw-r--r--Makefile.am1
-rw-r--r--NEWS8
-rw-r--r--configure.ac6
-rw-r--r--cython/plist.pyx8
-rw-r--r--include/plist/Data.h6
-rw-r--r--include/plist/plist.h170
-rw-r--r--src/Data.cpp12
-rw-r--r--src/plist.c256
9 files changed, 442 insertions, 27 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 68948af..e2caf04 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -50,7 +50,7 @@ jobs:
else
brew install libtool autoconf automake
fi
- pip3 install cython
+ pip3 install --break-system-packages cython
shell: bash
- uses: actions/checkout@v4
with:
diff --git a/Makefile.am b/Makefile.am
index f44a6bc..e6923a4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,6 +19,7 @@ EXTRA_DIST = \
git-version-gen
dist-hook:
+ @if ! git diff --quiet; then echo "Uncommitted changes present; not releasing"; exit 1; fi
echo $(VERSION) > $(distdir)/.tarball-version
docs/html: $(top_builddir)/doxygen.cfg $(top_srcdir)/include/plist/*.h
diff --git a/NEWS b/NEWS
index 760f4e4..16c8ddf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+Version 2.5.0
+~~~~~~~~~~~~~
+
+- Changes:
+ * Change API around PLIST_DATA to use uint8_t* instead of char*
+ * Add PLIST_DICT helper functions for different operations
+ * Require Cython 3.0 for python bindings
+
Version 2.4.0
~~~~~~~~~~~~~
diff --git a/configure.ac b/configure.ac
index 757ea95..ffa53dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ dnl libtool versioning
# changes to the signature and the semantic)
# ? :+1 : ? == just internal changes
# CURRENT : REVISION : AGE
-LIBPLIST_SO_VERSION=8:0:4
+LIBPLIST_SO_VERSION=9:0:5
AC_SUBST(LIBPLIST_SO_VERSION)
@@ -147,9 +147,9 @@ AC_ARG_WITH([cython],
[build_cython=false],
[build_cython=true])
if test "$build_cython" = "true"; then
- AC_PROG_CYTHON([0.17.0])
+ AC_PROG_CYTHON([3.0.0])
if [test "x$CYTHON" != "xfalse"]; then
- AM_PATH_PYTHON([2.3], [CYTHON_PYTHON])
+ AM_PATH_PYTHON([3.0], [CYTHON_PYTHON])
fi
else
CYTHON=false
diff --git a/cython/plist.pyx b/cython/plist.pyx
index b5f4ef6..a16e7be 100644
--- a/cython/plist.pyx
+++ b/cython/plist.pyx
@@ -48,9 +48,9 @@ cdef extern from *:
void plist_get_string_val(plist_t node, char **val)
void plist_set_string_val(plist_t node, char *val)
- plist_t plist_new_data(char *val, uint64_t length)
- 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_data(uint8_t *val, uint64_t length)
+ void plist_get_data_val(plist_t node, uint8_t **val, uint64_t * length)
+ void plist_set_data_val(plist_t node, uint8_t *val, uint64_t length)
plist_t plist_new_null();
@@ -579,7 +579,7 @@ cdef class Data(Node):
cpdef bytes get_value(self):
cdef:
- char* val = NULL
+ uint8_t* val = NULL
uint64_t length = 0
plist_get_data_val(self._c_node, &val, &length)
diff --git a/include/plist/Data.h b/include/plist/Data.h
index b566a6c..3f1c329 100644
--- a/include/plist/Data.h
+++ b/include/plist/Data.h
@@ -35,13 +35,13 @@ public :
Data(plist_t node, Node* parent = NULL);
Data(const Data& d);
Data& operator=(const Data& b);
- Data(const std::vector<char>& buff);
+ Data(const std::vector<uint8_t>& buff);
virtual ~Data();
Node* Clone() const;
- void SetValue(const std::vector<char>& buff);
- std::vector<char> GetValue() const;
+ void SetValue(const std::vector<uint8_t>& buff);
+ std::vector<uint8_t> GetValue() const;
};
};
diff --git a/include/plist/plist.h b/include/plist/plist.h
index 46aca16..7d5b4cb 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -258,7 +258,7 @@ extern "C"
* @return the created item
* @sa #plist_type
*/
- PLIST_API plist_t plist_new_data(const char *val, uint64_t length);
+ PLIST_API plist_t plist_new_data(const uint8_t *val, uint64_t length);
/**
* Create a new plist_t type #PLIST_DATE
@@ -445,7 +445,7 @@ extern "C"
PLIST_API void plist_dict_get_item_key(plist_t node, char **key);
/**
- * Get the nth item in a #PLIST_DICT node.
+ * Get the item for given key in a #PLIST_DICT node.
*
* @param node the node of type #PLIST_DICT
* @param key the identifier of the item to get.
@@ -492,6 +492,166 @@ extern "C"
*/
PLIST_API void plist_dict_merge(plist_t *target, plist_t source);
+ /**
+ * Get a boolean value from a given #PLIST_DICT entry.
+ *
+ * The value node can be of type #PLIST_BOOLEAN, but also
+ * #PLIST_STRING (either 'true' or 'false'),
+ * #PLIST_INT with a numerical value of 0 or >= 1,
+ * or #PLIST_DATA with a single byte with a value of 0 or >= 1.
+ *
+ * @note This function returns 0 if the dictionary does not contain an
+ * entry for the given key, if the value node is of any other than
+ * the above mentioned type, or has any mismatching value.
+ *
+ * @param dict A node of type #PLIST_DICT
+ * @param key The key to look for in dict
+ * @return 0 or 1 depending on the value of the node.
+ */
+ PLIST_API uint8_t plist_dict_get_bool(plist_t dict, const char *key);
+
+ /**
+ * Get a signed integer value from a given #PLIST_DICT entry.
+ * The value node can be of type #PLIST_INT, but also
+ * #PLIST_STRING with a numerical value as string (decimal or hexadecimal),
+ * or #PLIST_DATA with a size of 1, 2, 4, or 8 bytes in little endian byte order.
+ *
+ * @note This function returns 0 if the dictionary does not contain an
+ * entry for the given key, if the value node is of any other than
+ * the above mentioned type, or has any mismatching value.
+ *
+ * @param dict A node of type #PLIST_DICT
+ * @param key The key to look for in dict
+ * @return Signed integer value depending on the value of the node.
+ */
+ PLIST_API int64_t plist_dict_get_int(plist_t dict, const char *key);
+
+ /**
+ * Get an unsigned integer value from a given #PLIST_DICT entry.
+ * The value node can be of type #PLIST_INT, but also
+ * #PLIST_STRING with a numerical value as string (decimal or hexadecimal),
+ * or #PLIST_DATA with a size of 1, 2, 4, or 8 bytes in little endian byte order.
+ *
+ * @note This function returns 0 if the dictionary does not contain an
+ * entry for the given key, if the value node is of any other than
+ * the above mentioned type, or has any mismatching value.
+ *
+ * @param dict A node of type #PLIST_DICT
+ * @param key The key to look for in dict
+ * @return Signed integer value depending on the value of the node.
+ */
+ PLIST_API uint64_t plist_dict_get_uint(plist_t dict, const char *key);
+
+ /**
+ * Copy a node from *source_dict* to *target_dict*.
+ * The node is looked up in *source_dict* with given *key*, unless *alt_source_key*
+ * is non-NULL, in which case it is looked up with *alt_source_key*.
+ * The entry in *target_dict* is **always** created with *key*.
+ *
+ * @param target_dict The target dictionary to copy to.
+ * @param source_dict The source dictionary to copy from.
+ * @param key The key for the node to copy.
+ * @param alt_source_key The alternative source key for lookup in *source_dict* or NULL.
+ *
+ * @result PLIST_ERR_SUCCESS on success or PLIST_ERR_INVALID_ARG if the source dictionary does not contain
+ * any entry with given key or alt_source_key.
+ */
+ PLIST_API plist_err_t plist_dict_copy_item(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key);
+
+ /**
+ * Copy a boolean value from *source_dict* to *target_dict*.
+ * The node is looked up in *source_dict* with given *key*, unless *alt_source_key*
+ * is non-NULL, in which case it is looked up with *alt_source_key*.
+ * The entry in *target_dict* is **always** created with *key*.
+ *
+ * @note The boolean value from *source_dict* is retrieved with #plist_dict_get_bool,
+ * but is **always** created as #PLIST_BOOLEAN in *target_dict*.
+ *
+ * @param target_dict The target dictionary to copy to.
+ * @param source_dict The source dictionary to copy from.
+ * @param key The key for the node to copy.
+ * @param alt_source_key The alternative source key for lookup in *source_dict* or NULL.
+ *
+ * @result PLIST_ERR_SUCCESS on success or PLIST_ERR_INVALID_ARG if the source dictionary does not contain
+ * any entry with given key or alt_source_key.
+ */
+ PLIST_API plist_err_t plist_dict_copy_bool(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key);
+
+ /**
+ * Copy a signed integer value from *source_dict* to *target_dict*.
+ * The node is looked up in *source_dict* with given *key*, unless *alt_source_key*
+ * is non-NULL, in which case it is looked up with *alt_source_key*.
+ * The entry in *target_dict* is **always** created with *key*.
+ *
+ * @note The signed integer value from *source_dict* is retrieved with #plist_dict_get_int,
+ * but is **always** created as #PLIST_INT.
+ *
+ * @param target_dict The target dictionary to copy to.
+ * @param source_dict The source dictionary to copy from.
+ * @param key The key for the node value to copy.
+ * @param alt_source_key The alternative source key for lookup in *source_dict* or NULL.
+ *
+ * @result PLIST_ERR_SUCCESS on success or PLIST_ERR_INVALID_ARG if the source dictionary does not contain
+ * any entry with given key or alt_source_key.
+ */
+ PLIST_API plist_err_t plist_dict_copy_int(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key);
+
+ /**
+ * Copy an unsigned integer value from *source_dict* to *target_dict*.
+ * The node is looked up in *source_dict* with given *key*, unless *alt_source_key*
+ * is non-NULL, in which case it is looked up with *alt_source_key*.
+ * The entry in *target_dict* is **always** created with *key*.
+ *
+ * @note The unsigned integer value from *source_dict* is retrieved with #plist_dict_get_uint,
+ * but is **always** created as #PLIST_INT.
+ *
+ * @param target_dict The target dictionary to copy to.
+ * @param source_dict The source dictionary to copy from.
+ * @param key The key for the node value to copy.
+ * @param alt_source_key The alternative source key for lookup in *source_dict* or NULL.
+ *
+ * @result PLIST_ERR_SUCCESS on success or PLIST_ERR_INVALID_ARG if the source dictionary does not contain
+ * any entry with given key or alt_source_key.
+ */
+ PLIST_API plist_err_t plist_dict_copy_uint(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key);
+
+ /**
+ * Copy a #PLIST_DATA node from *source_dict* to *target_dict*.
+ * The node is looked up in *source_dict* with given *key*, unless *alt_source_key*
+ * is non-NULL, in which case it is looked up with *alt_source_key*.
+ * The entry in *target_dict* is **always** created with *key*.
+ *
+ * @note This function is like #plist_dict_copy_item, except that it fails
+ * if the source node is not of type #PLIST_DATA.
+ *
+ * @param target_dict The target dictionary to copy to.
+ * @param source_dict The source dictionary to copy from.
+ * @param key The key for the node value to copy.
+ * @param alt_source_key The alternative source key for lookup in *source_dict* or NULL.
+ *
+ * @result PLIST_ERR_SUCCESS on success or PLIST_ERR_INVALID_ARG if the source dictionary does not contain
+ * any entry with given key or alt_source_key, or if it is not of type #PLIST_DATA.
+ */
+ PLIST_API plist_err_t plist_dict_copy_data(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key);
+
+ /**
+ * Copy a #PLIST_STRING node from *source_dict* to *target_dict*.
+ * The node is looked up in *source_dict* with given *key*, unless *alt_source_key*
+ * is non-NULL, in which case it is looked up with *alt_source_key*.
+ * The entry in *target_dict* is **always** created with *key*.
+ *
+ * @note This function is like #plist_dict_copy_item, except that it fails
+ * if the source node is not of type #PLIST_STRING.
+ *
+ * @param target_dict The target dictionary to copy to.
+ * @param source_dict The source dictionary to copy from.
+ * @param key The key for the node value to copy.
+ * @param alt_source_key The alternative source key for lookup in *source_dict* or NULL.
+ *
+ * @result PLIST_ERR_SUCCESS on success or PLIST_ERR_INVALID_ARG if the source dictionary does not contain
+ * any entry with given key or alt_source_key, or if it is not of type #PLIST_STRING.
+ */
+ PLIST_API plist_err_t plist_dict_copy_string(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key);
/********************************************
* *
@@ -595,7 +755,7 @@ extern "C"
* @param length the length of the buffer
* @note Use plist_mem_free() to free the allocated memory.
*/
- PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length);
+ PLIST_API void plist_get_data_val(plist_t node, uint8_t **val, uint64_t * length);
/**
* Get a pointer to the data buffer of a #PLIST_DATA node.
@@ -608,7 +768,7 @@ extern "C"
*
* @return Pointer to the buffer
*/
- PLIST_API const char* plist_get_data_ptr(plist_t node, uint64_t* length);
+ PLIST_API const uint8_t* plist_get_data_ptr(plist_t node, uint64_t* length);
/**
* Get the value of a #PLIST_DATE node.
@@ -700,7 +860,7 @@ extern "C"
* be freed by the node.
* @param length the length of the buffer
*/
- PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length);
+ PLIST_API void plist_set_data_val(plist_t node, const uint8_t *val, uint64_t length);
/**
* Set the value of a node.
diff --git a/src/Data.cpp b/src/Data.cpp
index a96fc50..c4709f7 100644
--- a/src/Data.cpp
+++ b/src/Data.cpp
@@ -34,7 +34,7 @@ Data::Data(plist_t node, Node* parent) : Node(node, parent)
Data::Data(const PList::Data& d) : Node(PLIST_DATA)
{
- std::vector<char> b = d.GetValue();
+ std::vector<uint8_t> b = d.GetValue();
plist_set_data_val(_node, &b[0], b.size());
}
@@ -45,7 +45,7 @@ Data& Data::operator=(const PList::Data& b)
return *this;
}
-Data::Data(const std::vector<char>& buff) : Node(PLIST_DATA)
+Data::Data(const std::vector<uint8_t>& buff) : Node(PLIST_DATA)
{
plist_set_data_val(_node, &buff[0], buff.size());
}
@@ -59,17 +59,17 @@ Node* Data::Clone() const
return new Data(*this);
}
-void Data::SetValue(const std::vector<char>& buff)
+void Data::SetValue(const std::vector<uint8_t>& buff)
{
plist_set_data_val(_node, &buff[0], buff.size());
}
-std::vector<char> Data::GetValue() const
+std::vector<uint8_t> Data::GetValue() const
{
- char* buff = NULL;
+ uint8_t* buff = NULL;
uint64_t length = 0;
plist_get_data_val(_node, &buff, &length);
- std::vector<char> ret(buff, buff + length);
+ std::vector<uint8_t> ret(buff, buff + length);
delete buff;
return ret;
}
diff --git a/src/plist.c b/src/plist.c
index 2078520..d1b0b5a 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -35,6 +35,7 @@
#include <limits.h>
#include <float.h>
#include <ctype.h>
+#include <inttypes.h>
#ifdef WIN32
#include <windows.h>
@@ -51,6 +52,13 @@
typedef SSIZE_T ssize_t;
#endif
+#ifdef DEBUG
+static int plist_debug = 0;
+#define PLIST_ERR(...) if (plist_debug > 0) { fprintf(stderr, "libplist ERROR: " __VA_ARGS__); }
+#else
+#define PLIST_ERR(...)
+#endif
+
extern void plist_xml_init(void);
extern void plist_xml_deinit(void);
extern void plist_bin_init(void);
@@ -60,6 +68,52 @@ extern void plist_json_deinit(void);
extern void plist_ostep_init(void);
extern void plist_ostep_deinit(void);
+#ifndef bswap16
+#define bswap16(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
+#endif
+
+#ifndef bswap32
+#define bswap32(x) ((((x) & 0xFF000000) >> 24) \
+ | (((x) & 0x00FF0000) >> 8) \
+ | (((x) & 0x0000FF00) << 8) \
+ | (((x) & 0x000000FF) << 24))
+#endif
+
+#ifndef bswap64
+#define bswap64(x) ((((x) & 0xFF00000000000000ull) >> 56) \
+ | (((x) & 0x00FF000000000000ull) >> 40) \
+ | (((x) & 0x0000FF0000000000ull) >> 24) \
+ | (((x) & 0x000000FF00000000ull) >> 8) \
+ | (((x) & 0x00000000FF000000ull) << 8) \
+ | (((x) & 0x0000000000FF0000ull) << 24) \
+ | (((x) & 0x000000000000FF00ull) << 40) \
+ | (((x) & 0x00000000000000FFull) << 56))
+#endif
+
+#ifndef le16toh
+#ifdef __LITTLE_ENDIAN__
+#define le16toh(x) (x)
+#else
+#define le16toh(x) bswap16(x)
+#endif
+#endif
+
+#ifndef le32toh
+#ifdef __LITTLE_ENDIAN__
+#define le32toh(x) (x)
+#else
+#define le32toh(x) bswap32(x)
+#endif
+#endif
+
+#ifndef le64toh
+#ifdef __LITTLE_ENDIAN__
+#define le64toh(x) (x)
+#else
+#define le64toh(x) bswap64(x)
+#endif
+#endif
+
static void internal_plist_init(void)
{
plist_bin_init();
@@ -490,7 +544,7 @@ plist_t plist_new_real(double val)
return plist_new_node(data);
}
-plist_t plist_new_data(const char *val, uint64_t length)
+plist_t plist_new_data(const uint8_t *val, uint64_t length)
{
plist_data_t data = plist_new_plist_data();
data->type = PLIST_DATA;
@@ -957,6 +1011,195 @@ void plist_dict_merge(plist_t *target, plist_t source)
free(it);
}
+uint8_t plist_dict_get_bool(plist_t dict, const char *key)
+{
+ uint8_t bval = 0;
+ uint64_t uintval = 0;
+ const char *strval = NULL;
+ uint64_t strsz = 0;
+ plist_t node = plist_dict_get_item(dict, key);
+ if (!node) {
+ return 0;
+ }
+ switch (plist_get_node_type(node)) {
+ case PLIST_BOOLEAN:
+ plist_get_bool_val(node, &bval);
+ break;
+ case PLIST_INT:
+ plist_get_uint_val(node, &uintval);
+ bval = (uintval) ? 1 : 0;
+ break;
+ case PLIST_STRING:
+ strval = plist_get_string_ptr(node, NULL);
+ if (strval) {
+ if (strcmp(strval, "true")) {
+ bval = 1;
+ } else if (strcmp(strval, "false")) {
+ bval = 0;
+ } else {
+ PLIST_ERR("%s: invalid string '%s' for string to boolean conversion\n", __func__, strval);
+ }
+ }
+ break;
+ case PLIST_DATA:
+ strval = (const char*)plist_get_data_ptr(node, &strsz);
+ if (strval) {
+ if (strsz == 1) {
+ bval = (strval[0]) ? 1 : 0;
+ } else {
+ PLIST_ERR("%s: invalid size %" PRIu64 " for data to boolean conversion\n", __func__, strsz);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return bval;
+}
+
+int64_t plist_dict_get_int(plist_t dict, const char *key)
+{
+ int64_t intval = 0;
+ const char *strval = NULL;
+ uint64_t strsz = 0;
+ plist_t node = plist_dict_get_item(dict, key);
+ if (!node) {
+ return intval;
+ }
+ switch (plist_get_node_type(node)) {
+ case PLIST_INT:
+ plist_get_int_val(node, &intval);
+ break;
+ case PLIST_STRING:
+ strval = plist_get_string_ptr(node, NULL);
+ if (strval) {
+ intval = strtoll(strval, NULL, 0);
+ }
+ break;
+ case PLIST_DATA:
+ strval = (const char*)plist_get_data_ptr(node, &strsz);
+ if (strval) {
+ if (strsz == 8) {
+ intval = le64toh(*(int64_t*)strval);
+ } else if (strsz == 4) {
+ intval = le32toh(*(int32_t*)strval);
+ } else if (strsz == 2) {
+ intval = le16toh(*(int16_t*)strval);
+ } else if (strsz == 1) {
+ intval = strval[0];
+ } else {
+ PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return intval;
+}
+
+
+uint64_t plist_dict_get_uint(plist_t dict, const char *key)
+{
+ uint64_t uintval = 0;
+ const char *strval = NULL;
+ uint64_t strsz = 0;
+ plist_t node = plist_dict_get_item(dict, key);
+ if (!node) {
+ return uintval;
+ }
+ switch (plist_get_node_type(node)) {
+ case PLIST_INT:
+ plist_get_uint_val(node, &uintval);
+ break;
+ case PLIST_STRING:
+ strval = plist_get_string_ptr(node, NULL);
+ if (strval) {
+ uintval = strtoull(strval, NULL, 0);
+ }
+ break;
+ case PLIST_DATA:
+ strval = (const char*)plist_get_data_ptr(node, &strsz);
+ if (strval) {
+ if (strsz == 8) {
+ uintval = le64toh(*(uint64_t*)strval);
+ } else if (strsz == 4) {
+ uintval = le32toh(*(uint32_t*)strval);
+ } else if (strsz == 2) {
+ uintval = le16toh(*(uint16_t*)strval);
+ } else if (strsz == 1) {
+ uintval = strval[0];
+ } else {
+ PLIST_ERR("%s: invalid size %" PRIu64 " for data to integer conversion\n", __func__, strsz);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return uintval;
+}
+
+plist_err_t plist_dict_copy_item(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
+{
+ plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
+ if (!node) {
+ return PLIST_ERR_INVALID_ARG;
+ }
+ plist_dict_set_item(target_dict, key, plist_copy(node));
+ return PLIST_ERR_SUCCESS;
+}
+
+plist_err_t plist_dict_copy_bool(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
+{
+ if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
+ return PLIST_ERR_INVALID_ARG;
+ }
+ uint8_t bval = plist_dict_get_bool(source_dict, (alt_source_key) ? alt_source_key : key);
+ plist_dict_set_item(target_dict, key, plist_new_bool(bval));
+ return PLIST_ERR_SUCCESS;
+}
+
+plist_err_t plist_dict_copy_int(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
+{
+ if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
+ return PLIST_ERR_INVALID_ARG;
+ }
+ int64_t i64val = plist_dict_get_int(source_dict, (alt_source_key) ? alt_source_key : key);
+ plist_dict_set_item(target_dict, key, plist_new_int(i64val));
+ return PLIST_ERR_SUCCESS;
+}
+
+plist_err_t plist_dict_copy_uint(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
+{
+ if (plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key) == NULL) {
+ return PLIST_ERR_INVALID_ARG;
+ }
+ uint64_t u64val = plist_dict_get_uint(source_dict, (alt_source_key) ? alt_source_key : key);
+ plist_dict_set_item(target_dict, key, plist_new_uint(u64val));
+ return PLIST_ERR_SUCCESS;
+}
+
+plist_err_t plist_dict_copy_data(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
+{
+ plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
+ if (!PLIST_IS_DATA(node)) {
+ return PLIST_ERR_INVALID_ARG;
+ }
+ plist_dict_set_item(target_dict, key, plist_copy(node));
+ return PLIST_ERR_SUCCESS;
+}
+
+plist_err_t plist_dict_copy_string(plist_t target_dict, plist_t source_dict, const char *key, const char *alt_source_key)
+{
+ plist_t node = plist_dict_get_item(source_dict, (alt_source_key) ? alt_source_key : key);
+ if (!PLIST_IS_STRING(node)) {
+ return PLIST_ERR_INVALID_ARG;
+ }
+ plist_dict_set_item(target_dict, key, plist_copy(node));
+ return PLIST_ERR_SUCCESS;
+}
+
plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
{
plist_t current = plist;
@@ -1142,7 +1385,7 @@ void plist_get_real_val(plist_t node, double *val)
assert(length == sizeof(double));
}
-void plist_get_data_val(plist_t node, char **val, uint64_t * length)
+void plist_get_data_val(plist_t node, uint8_t **val, uint64_t * length)
{
if (!node || !val || !length)
return;
@@ -1152,7 +1395,7 @@ void plist_get_data_val(plist_t node, char **val, uint64_t * length)
plist_get_type_and_value(node, &type, (void *) val, length);
}
-const char* plist_get_data_ptr(plist_t node, uint64_t* length)
+const uint8_t* plist_get_data_ptr(plist_t node, uint64_t* length)
{
if (!node || !length)
return NULL;
@@ -1161,7 +1404,7 @@ const char* plist_get_data_ptr(plist_t node, uint64_t* length)
return NULL;
plist_data_t data = plist_get_data(node);
*length = data->length;
- return (const char*)data->buff;
+ return data->buff;
}
void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
@@ -1332,7 +1575,7 @@ void plist_set_real_val(plist_t node, double val)
plist_set_element_val(node, PLIST_REAL, &val, sizeof(double));
}
-void plist_set_data_val(plist_t node, const char *val, uint64_t length)
+void plist_set_data_val(plist_t node, const uint8_t *val, uint64_t length)
{
plist_set_element_val(node, PLIST_DATA, val, length);
}
@@ -1577,6 +1820,9 @@ extern void plist_ostep_set_debug(int debug);
void plist_set_debug(int debug)
{
+#if DEBUG
+ plist_debug = debug;
+#endif
plist_xml_set_debug(debug);
plist_bin_set_debug(debug);
plist_json_set_debug(debug);