diff options
Diffstat (limited to 'include/plist/plist.h')
-rw-r--r-- | include/plist/plist.h | 529 |
1 files changed, 403 insertions, 126 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h index ab91612..46aca16 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -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 @@ -44,6 +44,7 @@ extern "C" #include <stdint.h> #endif +/*{{{ deprecation macros */ #ifdef __llvm__ #if defined(__has_extension) #if (__has_extension(attribute_deprecated_with_message)) @@ -72,12 +73,24 @@ extern "C" #define PLIST_WARN_DEPRECATED(x) #pragma message("WARNING: You need to implement DEPRECATED for this compiler") #endif +/*}}}*/ + +#ifndef PLIST_API + #ifdef LIBPLIST_STATIC + #define PLIST_API + #elif defined(_WIN32) + #define PLIST_API __declspec(dllimport) + #else + #define PLIST_API + #endif +#endif #include <sys/types.h> #include <stdarg.h> +#include <stdio.h> /** - * \mainpage libplist : A library to handle Apple Property Lists + * libplist : A library to handle Apple Property Lists * \defgroup PublicAPI Public libplist API */ /*@{*/ @@ -103,19 +116,68 @@ extern "C" */ typedef enum { - PLIST_BOOLEAN, /**< Boolean, scalar type */ - PLIST_UINT, /**< Unsigned integer, scalar type */ - PLIST_REAL, /**< Real, scalar type */ - PLIST_STRING, /**< ASCII string, scalar type */ - PLIST_ARRAY, /**< Ordered array, structured type */ - PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ - PLIST_DATE, /**< Date, scalar type */ - PLIST_DATA, /**< Binary data, scalar type */ - PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ + PLIST_NONE =-1, /**< No type */ + PLIST_BOOLEAN, /**< Boolean, scalar type */ + PLIST_INT, /**< Integer, scalar type */ + PLIST_REAL, /**< Real, scalar type */ + PLIST_STRING, /**< ASCII string, scalar type */ + PLIST_ARRAY, /**< Ordered array, structured type */ + PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ + PLIST_DATE, /**< Date, scalar type */ + PLIST_DATA, /**< Binary data, scalar type */ + PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ PLIST_UID, /**< Special type used for 'keyed encoding' */ - PLIST_NONE /**< No type */ + PLIST_NULL, /**< NULL type */ } plist_type; + /* for backwards compatibility */ + #define PLIST_UINT PLIST_INT + + /** + * libplist error values + */ + typedef enum + { + PLIST_ERR_SUCCESS = 0, /**< operation successful */ + PLIST_ERR_INVALID_ARG = -1, /**< one or more of the parameters are invalid */ + PLIST_ERR_FORMAT = -2, /**< the plist contains nodes not compatible with the output format */ + PLIST_ERR_PARSE = -3, /**< parsing of the input format failed */ + PLIST_ERR_NO_MEM = -4, /**< not enough memory to handle the operation */ + PLIST_ERR_IO = -5, /**< I/O error */ + PLIST_ERR_UNKNOWN = -255 /**< an unspecified error occurred */ + } plist_err_t; + + /** + * libplist format types + */ + typedef enum + { + PLIST_FORMAT_NONE = 0, /**< No format */ + PLIST_FORMAT_XML = 1, /**< XML format */ + PLIST_FORMAT_BINARY = 2, /**< bplist00 format */ + PLIST_FORMAT_JSON = 3, /**< JSON format */ + PLIST_FORMAT_OSTEP = 4, /**< OpenStep "old-style" plist format */ + /* 5-9 are reserved for possible future use */ + PLIST_FORMAT_PRINT = 10, /**< human-readable output-only format */ + PLIST_FORMAT_LIMD = 11, /**< "libimobiledevice" output-only format (ideviceinfo) */ + PLIST_FORMAT_PLUTIL = 12, /**< plutil-style output-only format */ + } plist_format_t; + + /** + * libplist write options + */ + typedef enum + { + PLIST_OPT_NONE = 0, /**< Default value to use when none of the options is needed. */ + PLIST_OPT_COMPACT = 1 << 0, /**< Use a compact representation (non-prettified). Only valid for #PLIST_FORMAT_JSON and #PLIST_FORMAT_OSTEP. */ + PLIST_OPT_PARTIAL_DATA = 1 << 1, /**< Print 24 bytes maximum of #PLIST_DATA values. If the data is longer than 24 bytes, the first 16 and last 8 bytes will be written. Only valid for #PLIST_FORMAT_PRINT. */ + PLIST_OPT_NO_NEWLINE = 1 << 2, /**< Do not print a final newline character. Only valid for #PLIST_FORMAT_PRINT, #PLIST_FORMAT_LIMD, and #PLIST_FORMAT_PLUTIL. */ + PLIST_OPT_INDENT = 1 << 3, /**< Indent each line of output. Currently only #PLIST_FORMAT_PRINT and #PLIST_FORMAT_LIMD are supported. Use #PLIST_OPT_INDENT_BY() macro to specify the level of indentation. */ + } plist_write_options_t; + + /** To be used with #PLIST_OPT_INDENT - encodes the level of indentation for OR'ing it into the #plist_write_options_t bitfield. */ + #define PLIST_OPT_INDENT_BY(x) ((x & 0xFF) << 24) + /******************************************** * * @@ -129,7 +191,7 @@ extern "C" * @return the created plist * @sa #plist_type */ - plist_t plist_new_dict(void); + PLIST_API plist_t plist_new_dict(void); /** * Create a new root plist_t type #PLIST_ARRAY @@ -137,7 +199,7 @@ extern "C" * @return the created plist * @sa #plist_type */ - plist_t plist_new_array(void); + PLIST_API plist_t plist_new_array(void); /** * Create a new plist_t type #PLIST_STRING @@ -146,7 +208,7 @@ extern "C" * @return the created item * @sa #plist_type */ - plist_t plist_new_string(const char *val); + PLIST_API plist_t plist_new_string(const char *val); /** * Create a new plist_t type #PLIST_BOOLEAN @@ -155,16 +217,29 @@ extern "C" * @return the created item * @sa #plist_type */ - plist_t plist_new_bool(uint8_t val); + PLIST_API 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); + PLIST_API 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_API plist_t plist_new_int(int64_t val); /** * Create a new plist_t type #PLIST_REAL @@ -173,7 +248,7 @@ extern "C" * @return the created item * @sa #plist_type */ - plist_t plist_new_real(double val); + PLIST_API plist_t plist_new_real(double val); /** * Create a new plist_t type #PLIST_DATA @@ -183,7 +258,7 @@ extern "C" * @return the created item * @sa #plist_type */ - plist_t plist_new_data(const char *val, uint64_t length); + PLIST_API plist_t plist_new_data(const char *val, uint64_t length); /** * Create a new plist_t type #PLIST_DATE @@ -193,7 +268,7 @@ extern "C" * @return the created item * @sa #plist_type */ - plist_t plist_new_date(int32_t sec, int32_t usec); + PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec); /** * Create a new plist_t type #PLIST_UID @@ -202,14 +277,23 @@ extern "C" * @return the created item * @sa #plist_type */ - plist_t plist_new_uid(uint64_t val); + PLIST_API plist_t plist_new_uid(uint64_t val); + + /** + * Create a new plist_t type #PLIST_NULL + * @return the created item + * @sa #plist_type + * @note This type is not valid for all formats, e.g. the XML format + * does not support it. + */ + PLIST_API plist_t plist_new_null(void); /** * Destruct a plist_t node and all its children recursively * * @param plist the plist to free */ - void plist_free(plist_t plist); + PLIST_API void plist_free(plist_t plist); /** * Return a copy of passed node and it's children @@ -217,7 +301,7 @@ extern "C" * @param node the plist to copy * @return copied plist */ - plist_t plist_copy(plist_t node); + PLIST_API plist_t plist_copy(plist_t node); /******************************************** @@ -232,7 +316,7 @@ extern "C" * @param node the node of type #PLIST_ARRAY * @return size of the #PLIST_ARRAY node */ - uint32_t plist_array_get_size(plist_t node); + PLIST_API uint32_t plist_array_get_size(plist_t node); /** * Get the nth item in a #PLIST_ARRAY node. @@ -241,7 +325,7 @@ extern "C" * @param n the index of the item to get. Range is [0, array_size[ * @return the nth item or NULL if node is not of type #PLIST_ARRAY */ - plist_t plist_array_get_item(plist_t node, uint32_t n); + PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n); /** * Get the index of an item. item must be a member of a #PLIST_ARRAY node. @@ -249,7 +333,7 @@ extern "C" * @param node the node * @return the node index or UINT_MAX if node index can't be determined */ - uint32_t plist_array_get_item_index(plist_t node); + PLIST_API uint32_t plist_array_get_item_index(plist_t node); /** * Set the nth item in a #PLIST_ARRAY node. @@ -259,7 +343,7 @@ extern "C" * @param item the new item at index n. The array is responsible for freeing item when it is no longer needed. * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range. */ - void plist_array_set_item(plist_t node, plist_t item, uint32_t n); + PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n); /** * Append a new item at the end of a #PLIST_ARRAY node. @@ -267,7 +351,7 @@ extern "C" * @param node the node of type #PLIST_ARRAY * @param item the new item. The array is responsible for freeing item when it is no longer needed. */ - void plist_array_append_item(plist_t node, plist_t item); + PLIST_API void plist_array_append_item(plist_t node, plist_t item); /** * Insert a new item at position n in a #PLIST_ARRAY node. @@ -276,7 +360,7 @@ extern "C" * @param item the new item to insert. The array is responsible for freeing item when it is no longer needed. * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range. */ - void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); + PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); /** * Remove an existing position in a #PLIST_ARRAY node. @@ -285,7 +369,7 @@ extern "C" * @param node the node of type #PLIST_ARRAY * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range. */ - void plist_array_remove_item(plist_t node, uint32_t n); + PLIST_API void plist_array_remove_item(plist_t node, uint32_t n); /** * Remove a node that is a child node of a #PLIST_ARRAY node. @@ -293,7 +377,7 @@ extern "C" * * @param node The node to be removed from its #PLIST_ARRAY parent. */ - void plist_array_item_remove(plist_t node); + PLIST_API void plist_array_item_remove(plist_t node); /** * Create an iterator of a #PLIST_ARRAY node. @@ -302,7 +386,7 @@ extern "C" * @param node The node of type #PLIST_ARRAY * @param iter Location to store the iterator for the array. */ - void plist_array_new_iter(plist_t node, plist_array_iter *iter); + PLIST_API void plist_array_new_iter(plist_t node, plist_array_iter *iter); /** * Increment iterator of a #PLIST_ARRAY node. @@ -313,7 +397,7 @@ extern "C" * returned item. Will be set to NULL when no more items are left * to iterate. */ - void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item); + PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item); /******************************************** @@ -328,7 +412,7 @@ extern "C" * @param node the node of type #PLIST_DICT * @return size of the #PLIST_DICT node */ - uint32_t plist_dict_get_size(plist_t node); + PLIST_API uint32_t plist_dict_get_size(plist_t node); /** * Create an iterator of a #PLIST_DICT node. @@ -337,7 +421,7 @@ extern "C" * @param node The node of type #PLIST_DICT. * @param iter Location to store the iterator for the dictionary. */ - void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); + PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); /** * Increment iterator of a #PLIST_DICT node. @@ -350,7 +434,7 @@ extern "C" * free the returned value. Will be set to NULL when no more * key/value pairs are left to iterate. */ - void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); + PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); /** * Get key associated key to an item. Item must be member of a dictionary. @@ -358,7 +442,7 @@ extern "C" * @param node the item * @param key a location to store the key. The caller is responsible for freeing the returned string. */ - void plist_dict_get_item_key(plist_t node, char **key); + PLIST_API void plist_dict_get_item_key(plist_t node, char **key); /** * Get the nth item in a #PLIST_DICT node. @@ -368,7 +452,7 @@ extern "C" * @return the item or NULL if node is not of type #PLIST_DICT. The caller should not free * the returned node. */ - plist_t plist_dict_get_item(plist_t node, const char* key); + PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key); /** * Get key node associated to an item. Item must be member of a dictionary. @@ -376,7 +460,7 @@ extern "C" * @param node the item * @return the key node of the given item, or NULL. */ - plist_t plist_dict_item_get_key(plist_t node); + PLIST_API plist_t plist_dict_item_get_key(plist_t node); /** * Set item identified by key in a #PLIST_DICT node. @@ -387,19 +471,7 @@ extern "C" * @param item the new item associated to key * @param key the identifier of the item to set. */ - void plist_dict_set_item(plist_t node, const char* key, plist_t item); - - /** - * Insert a new item into a #PLIST_DICT node. - * - * @deprecated Deprecated. Use plist_dict_set_item instead. - * - * @param node the node of type #PLIST_DICT - * @param item the new item to insert - * @param key The identifier of the item to insert. - */ - PLIST_WARN_DEPRECATED("use plist_dict_set_item instead") - void plist_dict_insert_item(plist_t node, const char* key, plist_t item); + PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item); /** * Remove an existing position in a #PLIST_DICT node. @@ -408,7 +480,7 @@ extern "C" * @param node the node of type #PLIST_DICT * @param key The identifier of the item to remove. Assert if identifier is not present. */ - void plist_dict_remove_item(plist_t node, const char* key); + PLIST_API void plist_dict_remove_item(plist_t node, const char* key); /** * Merge a dictionary into another. This will add all key/value pairs @@ -418,7 +490,7 @@ extern "C" * @param target pointer to an existing node of type #PLIST_DICT * @param source node of type #PLIST_DICT that should be merged into target */ - void plist_dict_merge(plist_t *target, plist_t source); + PLIST_API void plist_dict_merge(plist_t *target, plist_t source); /******************************************** @@ -432,7 +504,7 @@ extern "C" * * @param node the parent (NULL if node is root) */ - plist_t plist_get_parent(plist_t node); + PLIST_API plist_t plist_get_parent(plist_t node); /** * Get the #plist_type of a node. @@ -440,7 +512,7 @@ extern "C" * @param node the node * @return the type of the node */ - plist_type plist_get_node_type(plist_t node); + PLIST_API plist_type plist_get_node_type(plist_t node); /** * Get the value of a #PLIST_KEY node. @@ -449,8 +521,9 @@ extern "C" * @param node the node * @param val a pointer to a C-string. This function allocates the memory, * caller is responsible for freeing it. + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_get_key_val(plist_t node, char **val); + PLIST_API void plist_get_key_val(plist_t node, char **val); /** * Get the value of a #PLIST_STRING node. @@ -459,8 +532,9 @@ extern "C" * @param node the node * @param val a pointer to a C-string. This function allocates the memory, * caller is responsible for freeing it. Data is UTF-8 encoded. + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_get_string_val(plist_t node, char **val); + PLIST_API void plist_get_string_val(plist_t node, char **val); /** * Get a pointer to the buffer of a #PLIST_STRING node. @@ -473,7 +547,7 @@ extern "C" * * @return Pointer to the NULL-terminated buffer. */ - const char* plist_get_string_ptr(plist_t node, uint64_t* length); + PLIST_API const char* plist_get_string_ptr(plist_t node, uint64_t* length); /** * Get the value of a #PLIST_BOOLEAN node. @@ -482,16 +556,25 @@ extern "C" * @param node the node * @param val a pointer to a uint8_t variable. */ - void plist_get_bool_val(plist_t node, uint8_t * val); + PLIST_API 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); + PLIST_API 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. + */ + PLIST_API void plist_get_int_val(plist_t node, int64_t * val); /** * Get the value of a #PLIST_REAL node. @@ -500,7 +583,7 @@ extern "C" * @param node the node * @param val a pointer to a double variable. */ - void plist_get_real_val(plist_t node, double *val); + PLIST_API void plist_get_real_val(plist_t node, double *val); /** * Get the value of a #PLIST_DATA node. @@ -510,8 +593,9 @@ extern "C" * @param val a pointer to an unallocated char buffer. This function allocates the memory, * caller is responsible for freeing it. * @param length the length of the buffer + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_get_data_val(plist_t node, char **val, uint64_t * length); + PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length); /** * Get a pointer to the data buffer of a #PLIST_DATA node. @@ -524,7 +608,7 @@ extern "C" * * @return Pointer to the buffer */ - const char* plist_get_data_ptr(plist_t node, uint64_t* length); + PLIST_API const char* plist_get_data_ptr(plist_t node, uint64_t* length); /** * Get the value of a #PLIST_DATE node. @@ -534,7 +618,7 @@ extern "C" * @param sec a pointer to an int32_t variable. Represents the number of seconds since 01/01/2001. * @param usec a pointer to an int32_t variable. Represents the number of microseconds */ - void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); + PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); /** * Get the value of a #PLIST_UID node. @@ -543,7 +627,7 @@ extern "C" * @param node the node * @param val a pointer to a uint64_t variable. */ - void plist_get_uid_val(plist_t node, uint64_t * val); + PLIST_API void plist_get_uid_val(plist_t node, uint64_t * val); /******************************************** @@ -559,7 +643,7 @@ extern "C" * @param node the node * @param val the key value */ - void plist_set_key_val(plist_t node, const char *val); + PLIST_API void plist_set_key_val(plist_t node, const char *val); /** * Set the value of a node. @@ -569,7 +653,7 @@ extern "C" * @param val the string value. The string is copied when set and will be * freed by the node. */ - void plist_set_string_val(plist_t node, const char *val); + PLIST_API void plist_set_string_val(plist_t node, const char *val); /** * Set the value of a node. @@ -578,16 +662,25 @@ extern "C" * @param node the node * @param val the boolean value */ - void plist_set_bool_val(plist_t node, uint8_t val); + PLIST_API void plist_set_bool_val(plist_t node, uint8_t val); /** * 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); + PLIST_API 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 + */ + PLIST_API void plist_set_int_val(plist_t node, int64_t val); /** * Set the value of a node. @@ -596,7 +689,7 @@ extern "C" * @param node the node * @param val the real value */ - void plist_set_real_val(plist_t node, double val); + PLIST_API void plist_set_real_val(plist_t node, double val); /** * Set the value of a node. @@ -607,7 +700,7 @@ extern "C" * be freed by the node. * @param length the length of the buffer */ - 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 char *val, uint64_t length); /** * Set the value of a node. @@ -617,7 +710,7 @@ extern "C" * @param sec the number of seconds since 01/01/2001 * @param usec the number of microseconds */ - void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); + PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); /** * Set the value of a node. @@ -626,7 +719,7 @@ extern "C" * @param node the node * @param val the unsigned integer value */ - void plist_set_uid_val(plist_t node, uint64_t val); + PLIST_API void plist_set_uid_val(plist_t node, uint64_t val); /******************************************** @@ -642,32 +735,49 @@ extern "C" * @param plist_xml a pointer to a C-string. This function allocates the memory, * caller is responsible for freeing it. Data is UTF-8 encoded. * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); + PLIST_API plist_err_t plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); /** - * Frees the memory allocated by plist_to_xml(). + * Export the #plist_t structure to binary format. * - * @param plist_xml The buffer allocated by plist_to_xml(). + * @param plist the root node to export + * @param plist_bin a pointer to a char* buffer. This function allocates the memory, + * caller is responsible for freeing it. + * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_to_xml_free(char *plist_xml); + PLIST_API plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); /** - * Export the #plist_t structure to binary format. + * Export the #plist_t structure to JSON format. * * @param plist the root node to export - * @param plist_bin a pointer to a char* buffer. This function allocates the memory, - * caller is responsible for freeing it. + * @param plist_json a pointer to a char* buffer. This function allocates the memory, + * caller is responsible for freeing it. * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. + * @param prettify pretty print the output if != 0 + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); + PLIST_API plist_err_t plist_to_json(plist_t plist, char **plist_json, uint32_t* length, int prettify); /** - * Frees the memory allocated by plist_to_bin(). + * Export the #plist_t structure to OpenStep format. * - * @param plist_bin The buffer allocated by plist_to_bin(). + * @param plist the root node to export + * @param plist_openstep a pointer to a char* buffer. This function allocates the memory, + * caller is responsible for freeing it. + * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. + * @param prettify pretty print the output if != 0 + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + * @note Use plist_mem_free() to free the allocated memory. */ - void plist_to_bin_free(char *plist_bin); + PLIST_API plist_err_t plist_to_openstep(plist_t plist, char **plist_openstep, uint32_t* length, int prettify); + /** * Import the #plist_t structure from XML format. @@ -675,8 +785,9 @@ extern "C" * @param plist_xml a pointer to the xml buffer. * @param length length of the buffer to read. * @param plist a pointer to the imported plist. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure */ - void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist); + PLIST_API plist_err_t plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist); /** * Import the #plist_t structure from binary format. @@ -684,33 +795,129 @@ extern "C" * @param plist_bin a pointer to the xml buffer. * @param length length of the buffer to read. * @param plist a pointer to the imported plist. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure */ - void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); + PLIST_API plist_err_t plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); /** - * Import the #plist_t structure from memory data. - * This method will look at the first bytes of plist_data - * to determine if plist_data contains a binary or XML plist. + * Import the #plist_t structure from JSON format. * - * @param plist_data a pointer to the memory buffer containing plist data. + * @param json a pointer to the JSON buffer. * @param length length of the buffer to read. * @param plist a pointer to the imported plist. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure */ - void plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist); + PLIST_API plist_err_t plist_from_json(const char *json, uint32_t length, plist_t * plist); /** - * Test if in-memory plist data is binary or XML - * This method will look at the first bytes of plist_data - * to determine if plist_data contains a binary or XML plist. - * This method is not validating the whole memory buffer to check if the - * content is truly a plist, it's only using some heuristic on the first few - * bytes of plist_data. + * Import the #plist_t structure from OpenStep plist format. + * + * @param openstep a pointer to the OpenStep plist buffer. + * @param length length of the buffer to read. + * @param plist a pointer to the imported plist. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + */ + PLIST_API plist_err_t plist_from_openstep(const char *openstep, uint32_t length, plist_t * plist); + + /** + * Import the #plist_t structure from memory data. + * + * This function will look at the first bytes of plist_data + * to determine if plist_data contains a binary, JSON, OpenStep, or XML plist + * and tries to parse the data in the appropriate format. + * @note This is just a convenience function and the format detection is + * very basic. It checks with plist_is_binary() if the data supposedly + * contains binary plist data, if not it checks if the first bytes have + * either '{' or '[' and assumes JSON format, and XML tags will result + * in parsing as XML, otherwise it will try to parse as OpenStep. + * + * @param plist_data A pointer to the memory buffer containing plist data. + * @param length Length of the buffer to read. + * @param plist A pointer to the imported plist. + * @param format If non-NULL, the #plist_format_t value pointed to will be set to the parsed format. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + */ + PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format); + + /** + * Import the #plist_t structure directly from file. + * + * This function will look at the first bytes of the file data + * to determine if it contains a binary, JSON, OpenStep, or XML plist + * and tries to parse the data in the appropriate format. + * Uses plist_from_memory() internally. + * + * @param filename The name of the file to parse. + * @param plist A pointer to the imported plist. + * @param format If non-NULL, the #plist_format_t value pointed to will be set to the parsed format. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure + */ + PLIST_API plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format); + + /** + * Write the #plist_t structure to a NULL-terminated string using the given format and options. + * + * @param plist The input plist structure + * @param output Pointer to a char* buffer. This function allocates the memory, + * caller is responsible for freeing it. + * @param length A pointer to a uint32_t value that will receive the lenght of the allocated buffer. + * @param format A #plist_format_t value that specifies the output format to use. + * @param options One or more bitwise ORed values of #plist_write_options_t. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure. + * @note Use plist_mem_free() to free the allocated memory. + * @note #PLIST_FORMAT_BINARY is not supported by this function. + */ + PLIST_API plist_err_t plist_write_to_string(plist_t plist, char **output, uint32_t* length, plist_format_t format, plist_write_options_t options); + + /** + * Write the #plist_t structure to a FILE* stream using the given format and options. + * + * @param plist The input plist structure + * @param stream A writeable FILE* stream that the data will be written to. + * @param format A #plist_format_t value that specifies the output format to use. + * @param options One or more bitwise ORed values of #plist_write_options_t. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure. + * @note While this function allows all formats to be written to the given stream, + * only the formats #PLIST_FORMAT_PRINT, #PLIST_FORMAT_LIMD, and #PLIST_FORMAT_PLUTIL + * (basically all output-only formats) are directly and efficiently written to the stream; + * the other formats are written to a memory buffer first. + */ + PLIST_API plist_err_t plist_write_to_stream(plist_t plist, FILE* stream, plist_format_t format, plist_write_options_t options); + + /** + * Write the #plist_t structure to a file at given path using the given format and options. + * + * @param plist The input plist structure + * @param filename The file name of the file to write to. Existing files will be overwritten. + * @param format A #plist_format_t value that specifies the output format to use. + * @param options One or more bitwise ORed values of #plist_write_options_t. + * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure. + * @note Use plist_mem_free() to free the allocated memory. + */ + PLIST_API plist_err_t plist_write_to_file(plist_t plist, const char *filename, plist_format_t format, plist_write_options_t options); + + /** + * Print the given plist in human-readable format to standard output. + * This is equivalent to + * <code>plist_write_to_stream(plist, stdout, PLIST_FORMAT_PRINT, PLIST_OPT_PARTIAL_DATA);</code> + * @param plist The #plist_t structure to print + * @note For #PLIST_DATA nodes, only a maximum of 24 bytes (first 16 and last 8) are written. + */ + PLIST_API void plist_print(plist_t plist); + + /** + * Test if in-memory plist data is in binary format. + * This function will look at the first bytes of plist_data to determine + * if it supposedly contains a binary plist. + * @note The function is not validating the whole memory buffer to check + * if the content is truly a plist, it is only using some heuristic on + * the first few bytes of plist_data. * * @param plist_data a pointer to the memory buffer containing plist data. * @param length length of the buffer to read. * @return 1 if the buffer is a binary plist, 0 otherwise. */ - int plist_is_binary(const char *plist_data, uint32_t length); + PLIST_API int plist_is_binary(const char *plist_data, uint32_t length); /******************************************** * * @@ -727,7 +934,7 @@ extern "C" * @param length length of the path to access * @return the value to access. */ - plist_t plist_access_path(plist_t plist, uint32_t length, ...); + PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...); /** * Variadic version of #plist_access_path. @@ -737,7 +944,7 @@ extern "C" * @param v list of array's index and dic'st key * @return the value to access. */ - plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); + PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); /** * Compare two node values @@ -746,42 +953,74 @@ extern "C" * @param node_r rigth node to compare * @return TRUE is type and value match, FALSE otherwise. */ - char plist_compare_node_value(plist_t node_l, plist_t node_r); + PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r); + /** Helper macro used by PLIST_IS_* macros that will evaluate the type of a plist node. */ #define _PLIST_IS_TYPE(__plist, __plist_type) (__plist && (plist_get_node_type(__plist) == PLIST_##__plist_type)) /* Helper macros for the different plist types */ + /** Evaluates to true if the given plist node is of type PLIST_BOOLEAN */ #define PLIST_IS_BOOLEAN(__plist) _PLIST_IS_TYPE(__plist, BOOLEAN) - #define PLIST_IS_UINT(__plist) _PLIST_IS_TYPE(__plist, UINT) + /** Evaluates to true if the given plist node is of type PLIST_INT */ + #define PLIST_IS_INT(__plist) _PLIST_IS_TYPE(__plist, INT) + /** Evaluates to true if the given plist node is of type PLIST_REAL */ #define PLIST_IS_REAL(__plist) _PLIST_IS_TYPE(__plist, REAL) + /** Evaluates to true if the given plist node is of type PLIST_STRING */ #define PLIST_IS_STRING(__plist) _PLIST_IS_TYPE(__plist, STRING) + /** Evaluates to true if the given plist node is of type PLIST_ARRAY */ #define PLIST_IS_ARRAY(__plist) _PLIST_IS_TYPE(__plist, ARRAY) + /** Evaluates to true if the given plist node is of type PLIST_DICT */ #define PLIST_IS_DICT(__plist) _PLIST_IS_TYPE(__plist, DICT) + /** Evaluates to true if the given plist node is of type PLIST_DATE */ #define PLIST_IS_DATE(__plist) _PLIST_IS_TYPE(__plist, DATE) + /** Evaluates to true if the given plist node is of type PLIST_DATA */ #define PLIST_IS_DATA(__plist) _PLIST_IS_TYPE(__plist, DATA) + /** Evaluates to true if the given plist node is of type PLIST_KEY */ #define PLIST_IS_KEY(__plist) _PLIST_IS_TYPE(__plist, KEY) + /** Evaluates to true if the given plist node is of type PLIST_UID */ #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); + PLIST_API 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. + */ + PLIST_API 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. + */ + PLIST_API 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, * or -1 if the node's value is less than cmpval. */ - int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval); + PLIST_API int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval); /** * Helper function to compare the value of a PLIST_UID node against @@ -793,7 +1032,7 @@ extern "C" * 1 if the node's value is greater than cmpval, * or -1 if the node's value is less than cmpval. */ - int plist_uid_val_compare(plist_t uidnode, uint64_t cmpval); + PLIST_API int plist_uid_val_compare(plist_t uidnode, uint64_t cmpval); /** * Helper function to compare the value of a PLIST_REAL node against @@ -810,7 +1049,7 @@ extern "C" * 1 if the node's value is greater than cmpval, * or -1 if the node's value is less than cmpval. */ - int plist_real_val_compare(plist_t realnode, double cmpval); + PLIST_API int plist_real_val_compare(plist_t realnode, double cmpval); /** * Helper function to compare the value of a PLIST_DATE node against @@ -823,7 +1062,7 @@ extern "C" * 1 if the node's date is greater than the supplied values, * or -1 if the node's date is less than the supplied values. */ - int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec); + PLIST_API int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec); /** * Helper function to compare the value of a PLIST_STRING node against @@ -836,7 +1075,7 @@ extern "C" * > 0 if the node's value is lexicographically greater than cmpval, * or < 0 if the node's value is lexicographically less than cmpval. */ - int plist_string_val_compare(plist_t strnode, const char* cmpval); + PLIST_API int plist_string_val_compare(plist_t strnode, const char* cmpval); /** * Helper function to compare the value of a PLIST_STRING node against @@ -850,7 +1089,7 @@ extern "C" * > 0 if the node's value is lexicographically greater than cmpval, * or < 0 if the node's value is lexicographically less than cmpval. */ - int plist_string_val_compare_with_size(plist_t strnode, const char* cmpval, size_t n); + PLIST_API int plist_string_val_compare_with_size(plist_t strnode, const char* cmpval, size_t n); /** * Helper function to match a given substring in the value of a @@ -861,7 +1100,7 @@ extern "C" * @return 1 if the node's value contains the given substring, * or 0 if not. */ - int plist_string_val_contains(plist_t strnode, const char* substr); + PLIST_API int plist_string_val_contains(plist_t strnode, const char* substr); /** * Helper function to compare the value of a PLIST_KEY node against @@ -874,7 +1113,7 @@ extern "C" * > 0 if the node's value is lexicographically greater than cmpval, * or < 0 if the node's value is lexicographically less than cmpval. */ - int plist_key_val_compare(plist_t keynode, const char* cmpval); + PLIST_API int plist_key_val_compare(plist_t keynode, const char* cmpval); /** * Helper function to compare the value of a PLIST_KEY node against @@ -888,7 +1127,7 @@ extern "C" * > 0 if the node's value is lexicographically greater than cmpval, * or < 0 if the node's value is lexicographically less than cmpval. */ - int plist_key_val_compare_with_size(plist_t keynode, const char* cmpval, size_t n); + PLIST_API int plist_key_val_compare_with_size(plist_t keynode, const char* cmpval, size_t n); /** * Helper function to match a given substring in the value of a @@ -899,7 +1138,7 @@ extern "C" * @return 1 if the node's value contains the given substring, * or 0 if not. */ - int plist_key_val_contains(plist_t keynode, const char* substr); + PLIST_API int plist_key_val_contains(plist_t keynode, const char* substr); /** * Helper function to compare the data of a PLIST_DATA node against @@ -915,7 +1154,7 @@ extern "C" * > 0 if the node's value is lexicographically greater than cmpval, * or < 0 if the node's value is lexicographically less than cmpval. */ - int plist_data_val_compare(plist_t datanode, const uint8_t* cmpval, size_t n); + PLIST_API int plist_data_val_compare(plist_t datanode, const uint8_t* cmpval, size_t n); /** * Helper function to compare the data of a PLIST_DATA node against @@ -931,7 +1170,7 @@ extern "C" * > 0 if the node's value is lexicographically greater than cmpval, * or < 0 if the node's value is lexicographically less than cmpval. */ - int plist_data_val_compare_with_size(plist_t datanode, const uint8_t* cmpval, size_t n); + PLIST_API int plist_data_val_compare_with_size(plist_t datanode, const uint8_t* cmpval, size_t n); /** * Helper function to match a given data blob within the value of a @@ -943,7 +1182,45 @@ extern "C" * @return 1 if the node's value contains the given data blob * or 0 if not. */ - int plist_data_val_contains(plist_t datanode, const uint8_t* cmpval, size_t n); + PLIST_API int plist_data_val_contains(plist_t datanode, const uint8_t* cmpval, size_t n); + + /** + * Sort all PLIST_DICT key/value pairs in a property list lexicographically + * by key. Recurses into the child nodes if necessary. + * + * @param plist The property list to perform the sorting operation on. + */ + PLIST_API void plist_sort(plist_t plist); + + /** + * Free memory allocated by relevant libplist API calls: + * - plist_to_xml() + * - plist_to_bin() + * - plist_get_key_val() + * - plist_get_string_val() + * - plist_get_data_val() + * + * @param ptr pointer to the memory to free + * + * @note Do not use this function to free plist_t nodes, use plist_free() + * instead. + */ + PLIST_API void plist_mem_free(void* ptr); + + /** + * Set debug level for the format parsers. + * @note This function does nothing if libplist was not configured with --enable-debug . + * + * @param debug Debug level. Currently, only 0 (off) and 1 (enabled) are supported. + */ + PLIST_API void plist_set_debug(int debug); + + /** + * Returns a static string of the libplist version. + * + * @return The libplist version as static ascii string + */ + PLIST_API const char* libplist_version(); /*@}*/ |