summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/plist/plist.h23
-rw-r--r--src/plist.c52
-rw-r--r--test/plist_cmp.c46
-rw-r--r--tools/plistutil.c2
4 files changed, 75 insertions, 48 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h
index b635996..9b16c58 100644
--- a/include/plist/plist.h
+++ b/include/plist/plist.h
@@ -44,6 +44,7 @@ extern "C"
44#include <stdint.h> 44#include <stdint.h>
45#endif 45#endif
46 46
47/*{{{ deprecation macros */
47#ifdef __llvm__ 48#ifdef __llvm__
48 #if defined(__has_extension) 49 #if defined(__has_extension)
49 #if (__has_extension(attribute_deprecated_with_message)) 50 #if (__has_extension(attribute_deprecated_with_message))
@@ -72,6 +73,7 @@ extern "C"
72 #define PLIST_WARN_DEPRECATED(x) 73 #define PLIST_WARN_DEPRECATED(x)
73 #pragma message("WARNING: You need to implement DEPRECATED for this compiler") 74 #pragma message("WARNING: You need to implement DEPRECATED for this compiler")
74#endif 75#endif
76/*}}}*/
75 77
76#include <sys/types.h> 78#include <sys/types.h>
77#include <stdarg.h> 79#include <stdarg.h>
@@ -819,7 +821,8 @@ extern "C"
819 821
820 /** 822 /**
821 * Import the #plist_t structure from memory data. 823 * Import the #plist_t structure from memory data.
822 * This method will look at the first bytes of plist_data 824 *
825 * This function will look at the first bytes of plist_data
823 * to determine if plist_data contains a binary, JSON, OpenStep, or XML plist 826 * to determine if plist_data contains a binary, JSON, OpenStep, or XML plist
824 * and tries to parse the data in the appropriate format. 827 * and tries to parse the data in the appropriate format.
825 * @note This is just a convenience function and the format detection is 828 * @note This is just a convenience function and the format detection is
@@ -831,9 +834,25 @@ extern "C"
831 * @param plist_data A pointer to the memory buffer containing plist data. 834 * @param plist_data A pointer to the memory buffer containing plist data.
832 * @param length Length of the buffer to read. 835 * @param length Length of the buffer to read.
833 * @param plist A pointer to the imported plist. 836 * @param plist A pointer to the imported plist.
837 * @param format If non-NULL, the #plist_format_t value pointed to will be set to the parsed format.
838 * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure
839 */
840 plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format);
841
842 /**
843 * Import the #plist_t structure directly from file.
844 *
845 * This function will look at the first bytes of the file data
846 * to determine if it contains a binary, JSON, OpenStep, or XML plist
847 * and tries to parse the data in the appropriate format.
848 * Uses #plist_read_from_data() internally.
849 *
850 * @param filename The name of the file to parse.
851 * @param plist A pointer to the imported plist.
852 * @param format If non-NULL, the #plist_format_t value pointed to will be set to the parsed format.
834 * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure 853 * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure
835 */ 854 */
836 plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist); 855 plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format);
837 856
838 /** 857 /**
839 * Write the #plist_t structure to a NULL-terminated string using the given format and options. 858 * Write the #plist_t structure to a NULL-terminated string using the given format and options.
diff --git a/src/plist.c b/src/plist.c
index 01e44df..48b012b 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -197,7 +197,7 @@ PLIST_API int plist_is_binary(const char *plist_data, uint32_t length)
197#define FIND_NEXT(blob, pos, len, chr) \ 197#define FIND_NEXT(blob, pos, len, chr) \
198 while (pos < len && (blob[pos] != chr)) pos++; 198 while (pos < len && (blob[pos] != chr)) pos++;
199 199
200PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist) 200PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format)
201{ 201{
202 int res = -1; 202 int res = -1;
203 if (!plist) { 203 if (!plist) {
@@ -207,8 +207,11 @@ PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length,
207 if (!plist_data || length == 0) { 207 if (!plist_data || length == 0) {
208 return PLIST_ERR_INVALID_ARG; 208 return PLIST_ERR_INVALID_ARG;
209 } 209 }
210 plist_format_t fmt = 0;
211 if (format) *format = 0;
210 if (plist_is_binary(plist_data, length)) { 212 if (plist_is_binary(plist_data, length)) {
211 res = plist_from_bin(plist_data, length, plist); 213 res = plist_from_bin(plist_data, length, plist);
214 fmt = PLIST_FORMAT_BINARY;
212 } else { 215 } else {
213 uint32_t pos = 0; 216 uint32_t pos = 0;
214 int is_json = 0; 217 int is_json = 0;
@@ -248,12 +251,59 @@ PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length,
248 } 251 }
249 if (is_xml) { 252 if (is_xml) {
250 res = plist_from_xml(plist_data, length, plist); 253 res = plist_from_xml(plist_data, length, plist);
254 fmt = PLIST_FORMAT_XML;
251 } else if (is_json) { 255 } else if (is_json) {
252 res = plist_from_json(plist_data, length, plist); 256 res = plist_from_json(plist_data, length, plist);
257 fmt = PLIST_FORMAT_JSON;
253 } else { 258 } else {
254 res = plist_from_openstep(plist_data, length, plist); 259 res = plist_from_openstep(plist_data, length, plist);
260 fmt = PLIST_FORMAT_OSTEP;
255 } 261 }
256 } 262 }
263 if (format && res == PLIST_ERR_SUCCESS) {
264 *format = fmt;
265 }
266 return res;
267}
268
269PLIST_API plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format)
270{
271 if (!filename || !plist) {
272 return PLIST_ERR_INVALID_ARG;
273 }
274 FILE *f = fopen(filename, "rb");
275 if (!f) {
276 return PLIST_ERR_IO;
277 }
278 struct stat fst;
279 fstat(fileno(f), &fst);
280 if (fst.st_size > UINT32_MAX) {
281 return PLIST_ERR_NO_MEM;
282 }
283 uint32_t total = (uint32_t)fst.st_size;
284 if (total == 0) {
285 return PLIST_ERR_PARSE;
286 }
287 char *buf = malloc(total);
288 if (!buf) {
289 fclose(f);
290 return PLIST_ERR_NO_MEM;
291 }
292 uint32_t done = 0;
293 while (done < total) {
294 ssize_t r = fread(buf + done, 1, total - done, f);
295 if (r <= 0) {
296 break;
297 }
298 done += r;
299 }
300 fclose(f);
301 if (done < total) {
302 free(buf);
303 return PLIST_ERR_IO;
304 }
305 plist_err_t res = plist_from_memory(buf, total, plist, format);
306 free(buf);
257 return res; 307 return res;
258} 308}
259 309
diff --git a/test/plist_cmp.c b/test/plist_cmp.c
index 4947276..c452032 100644
--- a/test/plist_cmp.c
+++ b/test/plist_cmp.c
@@ -75,21 +75,12 @@ static char compare_plist(plist_t node_l, plist_t node_r)
75 75
76int main(int argc, char *argv[]) 76int main(int argc, char *argv[])
77{ 77{
78 FILE *iplist1 = NULL;
79 FILE *iplist2 = NULL;
80 plist_t root_node1 = NULL; 78 plist_t root_node1 = NULL;
81 plist_t root_node2 = NULL; 79 plist_t root_node2 = NULL;
82 char *plist_1 = NULL;
83 char *plist_2 = NULL;
84 int size_in1 = 0;
85 int size_in2 = 0;
86 char *file_in1 = NULL; 80 char *file_in1 = NULL;
87 char *file_in2 = NULL; 81 char *file_in2 = NULL;
88 int res = 0; 82 int res = 0;
89 83
90 struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat));
91 struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat));
92
93 if (argc!= 3) 84 if (argc!= 3)
94 { 85 {
95 printf("Wrong input\n"); 86 printf("Wrong input\n");
@@ -99,36 +90,8 @@ int main(int argc, char *argv[])
99 file_in1 = argv[1]; 90 file_in1 = argv[1];
100 file_in2 = argv[2]; 91 file_in2 = argv[2];
101 92
102 //read input file 93 plist_read_from_file(file_in1, &root_node1, NULL);
103 iplist1 = fopen(file_in1, "rb"); 94 plist_read_from_file(file_in2, &root_node2, NULL);
104 iplist2 = fopen(file_in2, "rb");
105
106 if (!iplist1 || !iplist2)
107 {
108 printf("File does not exists\n");
109 return 2;
110 }
111
112 stat(file_in1, filestats1);
113 stat(file_in2, filestats2);
114
115 size_in1 = filestats1->st_size;
116 size_in2 = filestats2->st_size;
117
118 plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1));
119 plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1));
120
121 fread(plist_1, sizeof(char), size_in1, iplist1);
122 fread(plist_2, sizeof(char), size_in2, iplist2);
123
124 fclose(iplist1);
125 fclose(iplist2);
126
127 plist_1[size_in1] = '\0';
128 plist_2[size_in2] = '\0';
129
130 plist_from_memory(plist_1, size_in1, &root_node1);
131 plist_from_memory(plist_2, size_in2, &root_node2);
132 95
133 if (!root_node1 || !root_node2) 96 if (!root_node1 || !root_node2)
134 { 97 {
@@ -142,11 +105,6 @@ int main(int argc, char *argv[])
142 plist_free(root_node1); 105 plist_free(root_node1);
143 plist_free(root_node2); 106 plist_free(root_node2);
144 107
145 free(plist_1);
146 free(plist_2);
147 free(filestats1);
148 free(filestats2);
149
150 return !res; 108 return !res;
151} 109}
152 110
diff --git a/tools/plistutil.c b/tools/plistutil.c
index e339b8b..6da53e4 100644
--- a/tools/plistutil.c
+++ b/tools/plistutil.c
@@ -284,7 +284,7 @@ int main(int argc, char *argv[])
284 } 284 }
285 else 285 else
286 { 286 {
287 input_res = plist_from_memory(plist_entire, read_size, &root_node); 287 input_res = plist_from_memory(plist_entire, read_size, &root_node, NULL);
288 if (input_res == PLIST_ERR_SUCCESS) { 288 if (input_res == PLIST_ERR_SUCCESS) {
289 if (options->flags & OPT_SORT) { 289 if (options->flags & OPT_SORT) {
290 plist_sort(root_node); 290 plist_sort(root_node);