summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2021-12-19 16:13:07 +0100
committerGravatar Nikias Bassen2021-12-19 16:13:07 +0100
commit810e1a5936867a9f2c9f07df3a33a9d02fc03466 (patch)
treec561f0301b98a95fddc32259978345eed8eb5cc5
parentc81471ce6e8821ba03427824217612dcab8e091b (diff)
downloadlibplist-810e1a5936867a9f2c9f07df3a33a9d02fc03466.tar.gz
libplist-810e1a5936867a9f2c9f07df3a33a9d02fc03466.tar.bz2
Add support for PLIST_NULL type
-rw-r--r--include/plist/plist.h30
-rw-r--r--src/bplist.c12
-rw-r--r--src/plist.c9
-rw-r--r--src/xplist.c24
4 files changed, 60 insertions, 15 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h
index 67050ee..0f69d40 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -103,17 +103,18 @@ extern "C"
103 */ 103 */
104 typedef enum 104 typedef enum
105 { 105 {
106 PLIST_BOOLEAN, /**< Boolean, scalar type */ 106 PLIST_BOOLEAN, /**< Boolean, scalar type */
107 PLIST_UINT, /**< Unsigned integer, scalar type */ 107 PLIST_UINT, /**< Unsigned integer, scalar type */
108 PLIST_REAL, /**< Real, scalar type */ 108 PLIST_REAL, /**< Real, scalar type */
109 PLIST_STRING, /**< ASCII string, scalar type */ 109 PLIST_STRING, /**< ASCII string, scalar type */
110 PLIST_ARRAY, /**< Ordered array, structured type */ 110 PLIST_ARRAY, /**< Ordered array, structured type */
111 PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ 111 PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */
112 PLIST_DATE, /**< Date, scalar type */ 112 PLIST_DATE, /**< Date, scalar type */
113 PLIST_DATA, /**< Binary data, scalar type */ 113 PLIST_DATA, /**< Binary data, scalar type */
114 PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ 114 PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */
115 PLIST_UID, /**< Special type used for 'keyed encoding' */ 115 PLIST_UID, /**< Special type used for 'keyed encoding' */
116 PLIST_NONE /**< No type */ 116 PLIST_NULL, /**< NULL type */
117 PLIST_NONE /**< No type */
117 } plist_type; 118 } plist_type;
118 119
119 120
@@ -205,6 +206,15 @@ extern "C"
205 plist_t plist_new_uid(uint64_t val); 206 plist_t plist_new_uid(uint64_t val);
206 207
207 /** 208 /**
209 * Create a new plist_t type #PLIST_NULL
210 * @return the created item
211 * @sa #plist_type
212 * @note This type is not valid for all formats, e.g. the XML format
213 * does not support it.
214 */
215 plist_t plist_new_null(void);
216
217 /**
208 * Destruct a plist_t node and all its children recursively 218 * Destruct a plist_t node and all its children recursively
209 * 219 *
210 * @param plist the plist to free 220 * @param plist the plist to free
diff --git a/src/bplist.c b/src/bplist.c
index a41ce1a..a6e6ded 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -630,6 +630,13 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
630 } 630 }
631 631
632 case BPLIST_NULL: 632 case BPLIST_NULL:
633 {
634 plist_data_t data = plist_new_plist_data();
635 data->type = PLIST_NULL;
636 data->length = 0;
637 return node_create(NULL, data);
638 }
639
633 default: 640 default:
634 return NULL; 641 return NULL;
635 } 642 }
@@ -1295,6 +1302,11 @@ PLIST_API void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
1295 1302
1296 switch (data->type) 1303 switch (data->type)
1297 { 1304 {
1305 case PLIST_NULL: {
1306 uint8_t b = 0;
1307 byte_array_append(bplist_buff, &b, 1);
1308 break;
1309 }
1298 case PLIST_BOOLEAN: { 1310 case PLIST_BOOLEAN: {
1299 uint8_t b = data->boolval ? BPLIST_TRUE : BPLIST_FALSE; 1311 uint8_t b = data->boolval ? BPLIST_TRUE : BPLIST_FALSE;
1300 byte_array_append(bplist_buff, &b, 1); 1312 byte_array_append(bplist_buff, &b, 1);
diff --git a/src/plist.c b/src/plist.c
index 386b04e..5453176 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -374,6 +374,15 @@ PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec)
374 return plist_new_node(data); 374 return plist_new_node(data);
375} 375}
376 376
377PLIST_API plist_t plist_new_null(void)
378{
379 plist_data_t data = plist_new_plist_data();
380 data->type = PLIST_NULL;
381 data->intval = 0;
382 data->length = 0;
383 return plist_new_node(data);
384}
385
377PLIST_API void plist_free(plist_t plist) 386PLIST_API void plist_free(plist_t plist)
378{ 387{
379 if (plist) 388 if (plist)
diff --git a/src/xplist.c b/src/xplist.c
index c45a984..94006f1 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -81,8 +81,10 @@ static const char XML_PLIST_EPILOG[] = "</plist>\n";
81#ifdef DEBUG 81#ifdef DEBUG
82static int plist_xml_debug = 0; 82static int plist_xml_debug = 0;
83#define PLIST_XML_ERR(...) if (plist_xml_debug) { fprintf(stderr, "libplist[xmlparser] ERROR: " __VA_ARGS__); } 83#define PLIST_XML_ERR(...) if (plist_xml_debug) { fprintf(stderr, "libplist[xmlparser] ERROR: " __VA_ARGS__); }
84#define PLIST_XML_WRITE_ERR(...) if (plist_xml_debug) { fprintf(stderr, "libplist[xmlwriter] ERROR: " __VA_ARGS__); }
84#else 85#else
85#define PLIST_XML_ERR(...) 86#define PLIST_XML_ERR(...)
87#define PLIST_XML_WRITE_ERR(...)
86#endif 88#endif
87 89
88void plist_xml_init(void) 90void plist_xml_init(void)
@@ -125,7 +127,7 @@ static size_t dtostr(char *buf, size_t bufsize, double realval)
125 return len; 127 return len;
126} 128}
127 129
128static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth) 130static int node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
129{ 131{
130 plist_data_t node_data = NULL; 132 plist_data_t node_data = NULL;
131 133
@@ -139,8 +141,10 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
139 141
140 uint32_t i = 0; 142 uint32_t i = 0;
141 143
142 if (!node) 144 if (!node) {
143 return; 145 PLIST_XML_WRITE_ERR("Encountered invalid empty node in property list\n");
146 return -1;
147 }
144 148
145 node_data = plist_get_data(node); 149 node_data = plist_get_data(node);
146 150
@@ -232,6 +236,9 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
232 val_len = snprintf(val, 64, "%"PRIi64, node_data->intval); 236 val_len = snprintf(val, 64, "%"PRIi64, node_data->intval);
233 } 237 }
234 break; 238 break;
239 case PLIST_NULL:
240 PLIST_XML_WRITE_ERR("PLIST_NULL type is not valid for XML format\n");
241 return -1;
235 default: 242 default:
236 break; 243 break;
237 } 244 }
@@ -353,7 +360,8 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
353 } 360 }
354 node_t *ch; 361 node_t *ch;
355 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { 362 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
356 node_to_xml(ch, outbuf, depth+1); 363 int res = node_to_xml(ch, outbuf, depth+1);
364 if (res < 0) return res;
357 } 365 }
358 366
359 /* fix indent for structured types */ 367 /* fix indent for structured types */
@@ -369,6 +377,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
369 str_buf_append(*outbuf, ">", 1); 377 str_buf_append(*outbuf, ">", 1);
370 } 378 }
371 str_buf_append(*outbuf, "\n", 1); 379 str_buf_append(*outbuf, "\n", 1);
380 return 0;
372} 381}
373 382
374static void parse_date(const char *strval, struct TM *btime) 383static void parse_date(const char *strval, struct TM *btime)
@@ -519,7 +528,12 @@ PLIST_API void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
519 528
520 str_buf_append(outbuf, XML_PLIST_PROLOG, sizeof(XML_PLIST_PROLOG)-1); 529 str_buf_append(outbuf, XML_PLIST_PROLOG, sizeof(XML_PLIST_PROLOG)-1);
521 530
522 node_to_xml(plist, &outbuf, 0); 531 if (node_to_xml(plist, &outbuf, 0) < 0) {
532 str_buf_free(outbuf);
533 *plist_xml = NULL;
534 *length = 0;
535 return;
536 }
523 537
524 str_buf_append(outbuf, XML_PLIST_EPILOG, sizeof(XML_PLIST_EPILOG)); 538 str_buf_append(outbuf, XML_PLIST_EPILOG, sizeof(XML_PLIST_EPILOG));
525 539