summaryrefslogtreecommitdiffstats
path: root/src/plist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plist.c')
-rw-r--r--src/plist.c52
1 files changed, 51 insertions, 1 deletions
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