Skip to content

Commit ca409a5

Browse files
committed
json: add json_variant_merge() helper
1 parent 15f1fb3 commit ca409a5

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

src/shared/json.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,69 @@ int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uintmax_
18361836
return json_variant_set_field(v, field, m);
18371837
}
18381838

1839+
int json_variant_merge(JsonVariant **v, JsonVariant *m) {
1840+
_cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
1841+
_cleanup_free_ JsonVariant **array = NULL;
1842+
size_t v_elements, m_elements, i, k;
1843+
bool v_blank, m_blank;
1844+
int r;
1845+
1846+
m = json_variant_dereference(m);
1847+
1848+
v_blank = json_variant_is_blank_object(*v);
1849+
m_blank = json_variant_is_blank_object(m);
1850+
1851+
if (!v_blank && !json_variant_is_object(*v))
1852+
return -EINVAL;
1853+
if (!m_blank && !json_variant_is_object(m))
1854+
return -EINVAL;
1855+
1856+
if (m_blank)
1857+
return 0; /* nothing to do */
1858+
1859+
if (v_blank) {
1860+
json_variant_unref(*v);
1861+
*v = json_variant_ref(m);
1862+
return 1;
1863+
}
1864+
1865+
v_elements = json_variant_elements(*v);
1866+
m_elements = json_variant_elements(m);
1867+
if (v_elements > SIZE_MAX - m_elements) /* overflow check */
1868+
return -ENOMEM;
1869+
1870+
array = new(JsonVariant*, v_elements + m_elements);
1871+
if (!array)
1872+
return -ENOMEM;
1873+
1874+
k = 0;
1875+
for (i = 0; i < v_elements; i += 2) {
1876+
JsonVariant *u;
1877+
1878+
u = json_variant_by_index(*v, i);
1879+
if (!json_variant_is_string(u))
1880+
return -EINVAL;
1881+
1882+
if (json_variant_by_key(m, json_variant_string(u)))
1883+
continue; /* skip if exists in second variant */
1884+
1885+
array[k++] = u;
1886+
array[k++] = json_variant_by_index(*v, i + 1);
1887+
}
1888+
1889+
for (i = 0; i < m_elements; i++)
1890+
array[k++] = json_variant_by_index(m, i);
1891+
1892+
r = json_variant_new_object(&w, array, k);
1893+
if (r < 0)
1894+
return r;
1895+
1896+
json_variant_unref(*v);
1897+
*v = TAKE_PTR(w);
1898+
1899+
return 1;
1900+
}
1901+
18391902
int json_variant_strv(JsonVariant *v, char ***ret) {
18401903
char **l = NULL;
18411904
size_t n, i;

src/shared/json.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ int json_variant_set_field(JsonVariant **v, const char *field, JsonVariant *valu
176176
int json_variant_set_field_string(JsonVariant **v, const char *field, const char *value);
177177
int json_variant_set_field_unsigned(JsonVariant **v, const char *field, uintmax_t value);
178178

179+
int json_variant_merge(JsonVariant **v, JsonVariant *m);
180+
179181
int json_variant_strv(JsonVariant *v, char ***ret);
180182

181183
typedef enum JsonParseFlags {

0 commit comments

Comments
 (0)