[util] Add code to parse a plist array to an array

This commit is contained in:
Bill Currie 2020-07-14 12:05:34 +09:00
parent 0945f30731
commit c6a8829a52
2 changed files with 57 additions and 2 deletions

View file

@ -99,6 +99,14 @@ typedef struct plfield_s {
void *data; ///< additional data for \a parser
} plfield_t;
typedef struct plelement_s {
pltype_t type; ///< the required type of the array elements
size_t stride; ///< the size of each element
void *(*alloc) (size_t size); ///< allocator for array memory
plparser_t parser; ///< custom parser function
void *data; ///< additional data for \a parser
} plelement_t;
/** Create an in-memory representation of the contents of a property list.
\param string the saved plist, as read from a file.
@ -316,6 +324,8 @@ void PL_Free (plitem_t *item);
*/
int PL_ParseDictionary (const plfield_t *fields, const plitem_t *dict,
void *data, plitem_t *messages);
int PL_ParseArray (const plfield_t *fields, const plitem_t *dict,
void *data, plitem_t *messages);
///@}

View file

@ -1130,8 +1130,7 @@ PL_ParseDictionary (const plfield_t *fields, const plitem_t *dict, void *data,
void **list, **l;
dictkey_t *current;
int result;
int (*parser) (const plfield_t *, const plitem_t *, void *,
plitem_t *);
plparser_t parser;
if (dict->type != QFDictionary) {
pl_message (messages, dict, "error: not a dictionary object");
@ -1177,3 +1176,49 @@ PL_ParseDictionary (const plfield_t *fields, const plitem_t *dict, void *data,
free (list);
return result;
}
VISIBLE int
PL_ParseArray (const plfield_t *field, const plitem_t *array, void *data,
plitem_t *messages)
{
int result;
plparser_t parser;
plarray_t *plarray = (plarray_t *) array->data;
plelement_t *element = (plelement_t *) field->data;
typedef struct arr_s DARRAY_TYPE(byte) arr_t;
arr_t *arr;
plfield_t f = { 0, 0, element->type, element->parser, element->data };
if (array->type != QFArray) {
pl_message (messages, array, "error: not an array object");
return 0;
}
if (field->parser) {
parser = field->parser;
} else {
parser = pl_default_parser;
}
arr = DARRAY_ALLOCFIXED (arr_t, plarray->numvals * element->stride,
element->alloc);
for (int i = 0; i < plarray->numvals; i++) {
plitem_t *item = plarray->values[i];
void *eledata = &arr->a[i * element->stride];
if (item->type != element->type) {
pl_message (messages, item,
"error: element %d is the wrong type"
" Got %s, expected %s", i,
pl_types[element->type],
pl_types[item->type]);
result = 0;
} else {
if (!parser (&f, item, eledata, messages)) {
result = 0;
}
}
}
*(arr_t **) data = arr;
return result;
}