commit 00b019b

default  ·  2024-03-09 07:32:20 +0000 UTC
parent e12af77
Backport from xs.
6 files changed,  +50, -15
M xs.h
M xs.h
+40, -4
 1@@ -109,6 +109,7 @@ xs_dict *xs_dict_append_m(xs_dict *dict, const xs_str *key, const xs_val *mem, i
 2 xs_dict *xs_dict_prepend_m(xs_dict *dict, const xs_str *key, const xs_val *mem, int dsz);
 3 #define xs_dict_prepend(dict, key, data) xs_dict_prepend_m(dict, key, data, xs_size(data))
 4 int xs_dict_iter(xs_dict **dict, xs_str **key, xs_val **value);
 5+int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt);
 6 xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def);
 7 #define xs_dict_get(dict, key) xs_dict_get_def(dict, key, NULL)
 8 xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key);
 9@@ -1024,17 +1025,52 @@ int xs_dict_iter(xs_dict **dict, xs_str **key, xs_val **value)
10 }
11 
12 
13+int xs_dict_next(const xs_dict *dict, xs_str **key, xs_val **value, int *ctxt)
14+/* iterates a dict, with context */
15+{
16+    int goon = 1;
17+
18+    char *p = (char *)dict;
19+
20+    /* skip the start of the list */
21+    if (*ctxt == 0)
22+        *ctxt = 1 + _XS_TYPE_SIZE;
23+
24+    p += *ctxt;
25+
26+    /* an element? */
27+    if (xs_type(p) == XSTYPE_DITEM) {
28+        p++;
29+
30+        *key = p;
31+        p += xs_size(*key);
32+
33+        *value = p;
34+        p += xs_size(*value);
35+    }
36+    else {
37+        /* end of list */
38+        goon = 0;
39+    }
40+
41+    /* store back the pointer */
42+    *ctxt = p - dict;
43+
44+    return goon;
45+}
46+
47+
48 xs_val *xs_dict_get_def(const xs_dict *dict, const xs_str *key, const xs_val *def)
49 /* returns the value directed by key, or the default value */
50 {
51     XS_ASSERT_TYPE(dict, XSTYPE_DICT);
52     XS_ASSERT_TYPE(key, XSTYPE_STRING);
53 
54-    xs_dict *p = (xs_dict *)dict;
55     xs_str *k;
56     xs_val *v;
57+    int c = 0;
58 
59-    while (xs_dict_iter(&p, &k, &v)) {
60+    while (xs_dict_next(dict, &k, &v, &c)) {
61         if (strcmp(k, key) == 0)
62             return v;
63     }
64@@ -1051,9 +1087,9 @@ xs_dict *xs_dict_del(xs_dict *dict, const xs_str *key)
65 
66     xs_str *k;
67     xs_val *v;
68-    xs_dict *p = dict;
69+    int c = 0;
70 
71-    while (xs_dict_iter(&p, &k, &v)) {
72+    while (xs_dict_next(dict, &k, &v, &c)) {
73         if (strcmp(k, key) == 0) {
74             /* the address of the item is just behind the key */
75             char *i = k - 1;
+2, -3
 1@@ -93,7 +93,6 @@ xs_dict *xs_http_request(const char *method, const char *url,
 2     xs_dict *response;
 3     CURL *curl;
 4     struct curl_slist *list = NULL;
 5-    xs_dict *p;
 6     xs_str *k;
 7     xs_val *v;
 8     long lstatus = 0;
 9@@ -147,8 +146,8 @@ xs_dict *xs_http_request(const char *method, const char *url,
10     }
11 
12     /* fill the request headers */
13-    p = (xs_dict *)headers;
14-    while (xs_dict_iter(&p, &k, &v)) {
15+    int c = 0;
16+    while (xs_dict_next(headers, &k, &v, &c)) {
17         xs *h = xs_fmt("%s: %s", k, v);
18 
19         list = curl_slist_append(list, h);
+2, -3
 1@@ -293,7 +293,6 @@ void xs_fcgi_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b
 2     struct fcgi_record_header hdr = {0};
 3     struct fcgi_end_request ereq = {0};
 4     xs *out = xs_str_new(NULL);
 5-    xs_dict *p;
 6     xs_str *k;
 7     xs_str *v;
 8 
 9@@ -307,8 +306,8 @@ void xs_fcgi_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b
10         out = xs_str_cat(out, s1);
11     }
12 
13-    p = headers;
14-    while (xs_dict_iter(&p, &k, &v)) {
15+    int c = 0;
16+    while (xs_dict_next(headers, &k, &v, &c)) {
17         xs *s1 = xs_fmt("%s: %s\r\n", k, v);
18         out = xs_str_cat(out, s1);
19     }
+2, -3
 1@@ -98,15 +98,14 @@ void xs_httpd_response(FILE *f, int status, xs_dict *headers, xs_str *body, int
 2 /* sends an httpd response */
 3 {
 4     xs *proto;
 5-    xs_dict *p;
 6     xs_str *k;
 7     xs_val *v;
 8 
 9     proto = xs_fmt("HTTP/1.1 %d %s", status, status / 100 == 2 ? "OK" : "ERROR");
10     fprintf(f, "%s\r\n", proto);
11 
12-    p = headers;
13-    while (xs_dict_iter(&p, &k, &v)) {
14+    int c = 0;
15+    while (xs_dict_next(headers, &k, &v, &c)) {
16         fprintf(f, "%s: %s\r\n", k, v);
17     }
18 
+3, -1
 1@@ -115,7 +115,9 @@ static void _xs_json_dump(const xs_val *s_data, int level, int indent, FILE *f)
 2         fputc('{', f);
 3 
 4         xs_str *k;
 5-        while (xs_dict_iter(&data, &k, &v)) {
 6+        int ct = 0;
 7+
 8+        while (xs_dict_next(s_data, &k, &v, &ct)) {
 9             if (c != 0)
10                 fputc(',', f);
11 
+1, -1
1@@ -1 +1 @@
2-/* 73ff6e75bec88fa0b908b039462180a8ac1401de 2024-03-08T07:17:30+01:00 */
3+/* f46d5b29627b20a6e9ec4ef60c01df1d2d778520 2024-03-09T08:26:31+01:00 */