diff options
author | Jo-Philipp Wich <jo@mein.io> | 2023-05-28 20:50:31 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2023-05-30 10:11:34 +0200 |
commit | d656d150905e8b24deb95707d675db60776c737f (patch) | |
tree | 27fe709eb0433397b9218bd8fc835f35325343ad /types.c | |
parent | d048ea88fe713eab288cdcd50e80223db3c64181 (diff) |
types: implement ucv_object_sort()
Introduce a new function `ucv_object_sort()` which works similar to
`ucv_array_sort()` and allows reordering the keys of an object.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'types.c')
-rw-r--r-- | types.c | 42 |
1 files changed, 42 insertions, 0 deletions
@@ -956,6 +956,48 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val) return true; } +void +ucv_object_sort(uc_value_t *uv, int (*cmp)(const void *, const void *)) +{ + uc_object_t *object = (uc_object_t *)uv; + struct lh_table *t; + struct lh_entry *e; + size_t i; + + struct { + struct lh_entry **entries; + size_t count; + } keys = { 0 }; + + if (ucv_type(uv) != UC_OBJECT || lh_table_length(object->table) <= 1) + return; + + for (t = object->table, e = t->head; e; e = e->next) + uc_vector_push(&keys, e); + + if (!keys.entries) + return; + + qsort(keys.entries, keys.count, sizeof(keys.entries[0]), cmp); + + for (i = 0; i < keys.count; i++) { + e = keys.entries[i]; + + if (i == 0) { + t->head = t->tail = e; + e->next = e->prev = NULL; + } + else { + t->tail->next = e; + e->prev = t->tail; + e->next = NULL; + t->tail = e; + } + } + + uc_vector_clear(&keys); +} + bool ucv_object_delete(uc_value_t *uv, const char *key) { |