mirror of
https://github.com/libimobiledevice/libplist.git
synced 2026-05-17 20:30:34 +00:00
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).
This commit is contained in:
+21
-2
@@ -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,6 +73,7 @@ extern "C"
|
||||
#define PLIST_WARN_DEPRECATED(x)
|
||||
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
|
||||
#endif
|
||||
/*}}}*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
@@ -819,7 +821,8 @@ extern "C"
|
||||
|
||||
/**
|
||||
* Import the #plist_t structure from memory data.
|
||||
* This method will look at the first bytes of plist_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
|
||||
@@ -831,9 +834,25 @@ extern "C"
|
||||
* @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_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist);
|
||||
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_read_from_data() 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_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.
|
||||
|
||||
+51
-1
@@ -197,7 +197,7 @@ PLIST_API int plist_is_binary(const char *plist_data, uint32_t length)
|
||||
#define FIND_NEXT(blob, pos, len, chr) \
|
||||
while (pos < len && (blob[pos] != chr)) pos++;
|
||||
|
||||
PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist)
|
||||
PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format)
|
||||
{
|
||||
int res = -1;
|
||||
if (!plist) {
|
||||
@@ -207,8 +207,11 @@ PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length,
|
||||
if (!plist_data || length == 0) {
|
||||
return PLIST_ERR_INVALID_ARG;
|
||||
}
|
||||
plist_format_t fmt = 0;
|
||||
if (format) *format = 0;
|
||||
if (plist_is_binary(plist_data, length)) {
|
||||
res = plist_from_bin(plist_data, length, plist);
|
||||
fmt = PLIST_FORMAT_BINARY;
|
||||
} else {
|
||||
uint32_t pos = 0;
|
||||
int is_json = 0;
|
||||
@@ -248,12 +251,59 @@ PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length,
|
||||
}
|
||||
if (is_xml) {
|
||||
res = plist_from_xml(plist_data, length, plist);
|
||||
fmt = PLIST_FORMAT_XML;
|
||||
} else if (is_json) {
|
||||
res = plist_from_json(plist_data, length, plist);
|
||||
fmt = PLIST_FORMAT_JSON;
|
||||
} else {
|
||||
res = plist_from_openstep(plist_data, length, plist);
|
||||
fmt = PLIST_FORMAT_OSTEP;
|
||||
}
|
||||
}
|
||||
if (format && res == PLIST_ERR_SUCCESS) {
|
||||
*format = fmt;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
PLIST_API plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format)
|
||||
{
|
||||
if (!filename || !plist) {
|
||||
return PLIST_ERR_INVALID_ARG;
|
||||
}
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
return PLIST_ERR_IO;
|
||||
}
|
||||
struct stat fst;
|
||||
fstat(fileno(f), &fst);
|
||||
if (fst.st_size > UINT32_MAX) {
|
||||
return PLIST_ERR_NO_MEM;
|
||||
}
|
||||
uint32_t total = (uint32_t)fst.st_size;
|
||||
if (total == 0) {
|
||||
return PLIST_ERR_PARSE;
|
||||
}
|
||||
char *buf = malloc(total);
|
||||
if (!buf) {
|
||||
fclose(f);
|
||||
return PLIST_ERR_NO_MEM;
|
||||
}
|
||||
uint32_t done = 0;
|
||||
while (done < total) {
|
||||
ssize_t r = fread(buf + done, 1, total - done, f);
|
||||
if (r <= 0) {
|
||||
break;
|
||||
}
|
||||
done += r;
|
||||
}
|
||||
fclose(f);
|
||||
if (done < total) {
|
||||
free(buf);
|
||||
return PLIST_ERR_IO;
|
||||
}
|
||||
plist_err_t res = plist_from_memory(buf, total, plist, format);
|
||||
free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+2
-44
@@ -75,21 +75,12 @@ static char compare_plist(plist_t node_l, plist_t node_r)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *iplist1 = NULL;
|
||||
FILE *iplist2 = NULL;
|
||||
plist_t root_node1 = NULL;
|
||||
plist_t root_node2 = NULL;
|
||||
char *plist_1 = NULL;
|
||||
char *plist_2 = NULL;
|
||||
int size_in1 = 0;
|
||||
int size_in2 = 0;
|
||||
char *file_in1 = NULL;
|
||||
char *file_in2 = NULL;
|
||||
int res = 0;
|
||||
|
||||
struct stat *filestats1 = (struct stat *) malloc(sizeof(struct stat));
|
||||
struct stat *filestats2 = (struct stat *) malloc(sizeof(struct stat));
|
||||
|
||||
if (argc!= 3)
|
||||
{
|
||||
printf("Wrong input\n");
|
||||
@@ -99,36 +90,8 @@ int main(int argc, char *argv[])
|
||||
file_in1 = argv[1];
|
||||
file_in2 = argv[2];
|
||||
|
||||
//read input file
|
||||
iplist1 = fopen(file_in1, "rb");
|
||||
iplist2 = fopen(file_in2, "rb");
|
||||
|
||||
if (!iplist1 || !iplist2)
|
||||
{
|
||||
printf("File does not exists\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
stat(file_in1, filestats1);
|
||||
stat(file_in2, filestats2);
|
||||
|
||||
size_in1 = filestats1->st_size;
|
||||
size_in2 = filestats2->st_size;
|
||||
|
||||
plist_1 = (char *) malloc(sizeof(char) * (size_in1 + 1));
|
||||
plist_2 = (char *) malloc(sizeof(char) * (size_in2 + 1));
|
||||
|
||||
fread(plist_1, sizeof(char), size_in1, iplist1);
|
||||
fread(plist_2, sizeof(char), size_in2, iplist2);
|
||||
|
||||
fclose(iplist1);
|
||||
fclose(iplist2);
|
||||
|
||||
plist_1[size_in1] = '\0';
|
||||
plist_2[size_in2] = '\0';
|
||||
|
||||
plist_from_memory(plist_1, size_in1, &root_node1);
|
||||
plist_from_memory(plist_2, size_in2, &root_node2);
|
||||
plist_read_from_file(file_in1, &root_node1, NULL);
|
||||
plist_read_from_file(file_in2, &root_node2, NULL);
|
||||
|
||||
if (!root_node1 || !root_node2)
|
||||
{
|
||||
@@ -142,11 +105,6 @@ int main(int argc, char *argv[])
|
||||
plist_free(root_node1);
|
||||
plist_free(root_node2);
|
||||
|
||||
free(plist_1);
|
||||
free(plist_2);
|
||||
free(filestats1);
|
||||
free(filestats2);
|
||||
|
||||
return !res;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -284,7 +284,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
input_res = plist_from_memory(plist_entire, read_size, &root_node);
|
||||
input_res = plist_from_memory(plist_entire, read_size, &root_node, NULL);
|
||||
if (input_res == PLIST_ERR_SUCCESS) {
|
||||
if (options->flags & OPT_SORT) {
|
||||
plist_sort(root_node);
|
||||
|
||||
Reference in New Issue
Block a user