diff options
| author | 2023-04-19 17:49:07 +0200 | |
|---|---|---|
| committer | 2023-04-19 17:49:07 +0200 | |
| commit | ce9ce43efd707a85cc792ff2cc417603a53d4d1d (patch) | |
| tree | 64c471946cc9e2da8a373db1c1c85fb41bc84265 /src/plist.c | |
| parent | 3aa5f6a3a663a5f2694ec6fc8cdf9744b616e15e (diff) | |
| download | libplist-ce9ce43efd707a85cc792ff2cc417603a53d4d1d.tar.gz libplist-ce9ce43efd707a85cc792ff2cc417603a53d4d1d.tar.bz2 | |
Add plist_read_from_file() to interface, update plist_from_memory()
plist_read_from_file() is a convenience function that will open a
given file, checks its size, allocates a buffer large enough to
hold the full contents, and reads from file to fill the buffer.
Then, it calls plist_from_memory() to convert the data to plist
format.
A (breaking) change had to be made so that plist_from_memory() will
also return the parsed format in its 4th argument (if non-NULL).
Diffstat (limited to 'src/plist.c')
| -rw-r--r-- | src/plist.c | 52 |
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 | ||
| 200 | PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist) | 200 | PLIST_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 | |||
| 269 | PLIST_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 | ||
