mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[plist] Add functions to extend dictionaries and arrays
The idea is to make it easy (and efficient) to merge property list items.
This commit is contained in:
parent
5255c9c7a8
commit
654b208641
2 changed files with 105 additions and 14 deletions
|
@ -294,6 +294,20 @@ int PL_D_NumKeys (const plitem_t *dict) __attribute__((pure));
|
|||
*/
|
||||
qboolean PL_D_AddObject (plitem_t *dict, const char *key, plitem_t *value);
|
||||
|
||||
/** Copy contents of one dictionary into another.
|
||||
|
||||
The contents of \a srcDict are added to \a dstDict without affecting
|
||||
\a srcDict. Any collisions in \a dstDict result in those values in
|
||||
\a dstDict being replaced by the the values from \a srcDict: the new
|
||||
key-value pairs override the old.
|
||||
|
||||
\param dstDict The dictionary to extend
|
||||
\param srcDict The dictionary from which key-value pairs will be copied
|
||||
\return true if values were copied, false if nothing was copied (either
|
||||
dictionary is null, or not a dictionary, or if \a srcDict was empty)
|
||||
*/
|
||||
qboolean PL_D_Extend (plitem_t *dstDict, plitem_t *srcDict);
|
||||
|
||||
/** Add an item to an array.
|
||||
|
||||
\param array The array to which the item will be added
|
||||
|
@ -306,6 +320,18 @@ qboolean PL_D_AddObject (plitem_t *dict, const char *key, plitem_t *value);
|
|||
*/
|
||||
qboolean PL_A_AddObject (plitem_t *array, plitem_t *item);
|
||||
|
||||
/** Append contents of one array to another.
|
||||
|
||||
The contents of \a srcArray are added to \a dstArray without affecting
|
||||
\a srcArray. Those values are appended to the destination array values.
|
||||
|
||||
\param dstArray The array to extend
|
||||
\param srcArray The array from which values will be copied
|
||||
\return true if values were copied, false if nothing was copied (either
|
||||
array is null, or not an array, or if \a srcArray was empty)
|
||||
*/
|
||||
qboolean PL_A_Extend (plitem_t *dstArray, plitem_t *srcArray);
|
||||
|
||||
/** Retrieve the number of items in an array.
|
||||
|
||||
\param array The array from which to get the number of objects
|
||||
|
|
|
@ -414,7 +414,7 @@ PL_D_AddObject (plitem_t *item, const char *key, plitem_t *value)
|
|||
dictkey_t *k;
|
||||
|
||||
if ((k = Hash_Find (dict->tab, key))) {
|
||||
value->users++;
|
||||
PL_Retain (value);
|
||||
PL_Release (k->value);
|
||||
k->value = value;
|
||||
} else {
|
||||
|
@ -423,7 +423,7 @@ PL_D_AddObject (plitem_t *item, const char *key, plitem_t *value)
|
|||
if (!k)
|
||||
return false;
|
||||
|
||||
value->users++;
|
||||
PL_Retain (value);
|
||||
k->key = strdup (key);
|
||||
k->value = value;
|
||||
|
||||
|
@ -433,6 +433,60 @@ PL_D_AddObject (plitem_t *item, const char *key, plitem_t *value)
|
|||
return true;
|
||||
}
|
||||
|
||||
VISIBLE qboolean
|
||||
PL_D_Extend (plitem_t *dstDict, plitem_t *srcDict)
|
||||
{
|
||||
if (!dstDict || dstDict->type != QFDictionary
|
||||
|| !srcDict || srcDict->type != QFDictionary
|
||||
|| ((pldict_t *) srcDict->data)->keys.size < 1) {
|
||||
return false;
|
||||
}
|
||||
pldict_t *dst = dstDict->data;
|
||||
pldict_t *src = srcDict->data;
|
||||
size_t count = dst->keys.size;
|
||||
DARRAY_RESIZE (&dst->keys, dst->keys.size + src->keys.size);// open space
|
||||
DARRAY_RESIZE (&dst->keys, count); // put size back so it's correct
|
||||
for (size_t i = 0; i < src->keys.size; i++) {
|
||||
dictkey_t *key = src->keys.a[i];
|
||||
dictkey_t *k;
|
||||
if ((k = Hash_Find (dst->tab, key->key))) {
|
||||
PL_Retain (key->value);
|
||||
PL_Release (k->value);
|
||||
k->value = key->value;
|
||||
} else {
|
||||
k = malloc (sizeof (dictkey_t));
|
||||
|
||||
if (!k)
|
||||
return false;
|
||||
|
||||
PL_Retain (key->value);
|
||||
k->key = strdup (key->key);
|
||||
k->value = key->value;
|
||||
|
||||
Hash_Add (dst->tab, k);
|
||||
DARRAY_APPEND (&dst->keys, k);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean
|
||||
check_array_size (plarray_t *arr, int count)
|
||||
{
|
||||
if (count > arr->maxvals) {
|
||||
int newmax = (count + 127) & ~127;
|
||||
int size = newmax * sizeof (plitem_t *);
|
||||
plitem_t **tmp = realloc (arr->values, size);
|
||||
|
||||
if (!tmp)
|
||||
return false;
|
||||
|
||||
arr->maxvals = newmax;
|
||||
arr->values = tmp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
VISIBLE qboolean
|
||||
PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index)
|
||||
{
|
||||
|
@ -444,17 +498,8 @@ PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index)
|
|||
|
||||
arr = (plarray_t *)array->data;
|
||||
|
||||
if (arr->numvals == arr->maxvals) {
|
||||
int size = (arr->maxvals + 128) * sizeof (plitem_t *);
|
||||
plitem_t **tmp = realloc (arr->values, size);
|
||||
|
||||
if (!tmp)
|
||||
if (!check_array_size (arr, arr->numvals + 1)) {
|
||||
return false;
|
||||
|
||||
arr->maxvals += 128;
|
||||
arr->values = tmp;
|
||||
memset (arr->values + arr->numvals, 0,
|
||||
(arr->maxvals - arr->numvals) * sizeof (plitem_t *));
|
||||
}
|
||||
|
||||
if (index == -1)
|
||||
|
@ -466,7 +511,7 @@ PL_A_InsertObjectAtIndex (plitem_t *array, plitem_t *item, int index)
|
|||
memmove (arr->values + index + 1, arr->values + index,
|
||||
(arr->numvals - index) * sizeof (plitem_t *));
|
||||
|
||||
item->users++;
|
||||
PL_Retain (item);
|
||||
arr->values[index] = item;
|
||||
arr->numvals++;
|
||||
return true;
|
||||
|
@ -478,6 +523,26 @@ PL_A_AddObject (plitem_t *array, plitem_t *item)
|
|||
return PL_A_InsertObjectAtIndex (array, item, -1);
|
||||
}
|
||||
|
||||
VISIBLE qboolean
|
||||
PL_A_Extend (plitem_t *dstArray, plitem_t *srcArray)
|
||||
{
|
||||
if (!dstArray || dstArray->type != QFArray
|
||||
|| !srcArray || srcArray->type != QFArray
|
||||
|| ((plarray_t *) srcArray->data)->numvals < 1) {
|
||||
return false;
|
||||
}
|
||||
plarray_t *dst = dstArray->data;
|
||||
plarray_t *src = srcArray->data;
|
||||
if (!check_array_size (dst, dst->numvals + src->numvals)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < src->numvals; i++) {
|
||||
PL_Retain (src->values[i]);
|
||||
dst->values[dst->numvals++] = src->values[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
PL_A_NumObjects (const plitem_t *array)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue