summaryrefslogtreecommitdiff
path: root/imap
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2022-08-27 22:08:12 -0600
committerEduardo Chappa <chappa@washington.edu>2022-08-27 22:08:12 -0600
commita76c9cd40a3e6140d3f562de375d2299fd9865af (patch)
tree098a53e2b1a48fb2842e07820a32fceb5989aa73 /imap
parent701aebc00aff0585ce6c96653714e4ba94834c9c (diff)
downloadalpine-a76c9cd40a3e6140d3f562de375d2299fd9865af.tar.xz
* Addition of a first attempt to transform a json structure into a
string.
Diffstat (limited to 'imap')
-rw-r--r--imap/src/c-client/http.c14
-rw-r--r--imap/src/c-client/json.c141
-rw-r--r--imap/src/c-client/json.h1
-rw-r--r--imap/src/c-client/misc.c13
-rw-r--r--imap/src/c-client/misc.h1
5 files changed, 152 insertions, 18 deletions
diff --git a/imap/src/c-client/http.c b/imap/src/c-client/http.c
index d291c975..04ae0c09 100644
--- a/imap/src/c-client/http.c
+++ b/imap/src/c-client/http.c
@@ -88,7 +88,6 @@ typedef struct http_header_data_s {
HTTP_STATUS_S *http_status_line_get(unsigned char *);
void http_status_line_free(HTTP_STATUS_S **);
void http_header_free(HTTP_HEADER_DATA_S **);
-void buffer_add(unsigned char **, unsigned char *);
unsigned char *hex_escape_url_part(unsigned char *, unsigned char *);
unsigned char *encode_url_body_part(unsigned char *, unsigned char *);
@@ -771,19 +770,6 @@ http_add_header(HTTP_REQUEST_S **reqp, unsigned char *name, unsigned char *value
}
void
-buffer_add(unsigned char **bufp, unsigned char *text)
-{
- int len;
-
- if(!bufp || !text || !*text) return;
-
- len = *bufp ? strlen(*bufp) : 0;
- fs_resize((void **) bufp, (len + strlen(text) + 1)*sizeof(char));
- (*bufp)[len] = '\0';
- strcat(*bufp, text);
-}
-
-void
http_add_body(HTTP_REQUEST_S **reqp, unsigned char *text)
{
if(!reqp) return;
diff --git a/imap/src/c-client/json.c b/imap/src/c-client/json.c
index 23446e87..c6df062d 100644
--- a/imap/src/c-client/json.c
+++ b/imap/src/c-client/json.c
@@ -47,6 +47,8 @@ JSON_S *json_array_parse_work(unsigned char **);
JSON_S *json_array_parse(unsigned char **);
void json_array_free(JSON_S **);
+unsigned char *json_add_array_value(JSON_S *, unsigned char **);
+
/* we are parsing from the text of the json object, so it is
* never possible to have a null character, unless something
* is corrupt, in whose case we return JNumberError.
@@ -210,8 +212,9 @@ void *
json_value_parse(unsigned char **s, JObjType *jtype)
{
void *rv = NIL;
- unsigned char *u, *w;
+ unsigned char *t, *u, *v, *w;
unsigned long *l;
+ double d;
w = *s;
json_skipws(w);
@@ -268,10 +271,16 @@ json_value_parse(unsigned char **s, JObjType *jtype)
json_skipws(w);
break;
+ /* in order to make sure we go back and forth we save the
+ * original value, not the converted value.
+ */
case JDecimal :
- case JExponential: l = fs_get(sizeof(double));
- *l = strtod((char *) w, (char **) &w);
- rv = (void *) l;
+ case JExponential: t = w;
+ d = strtod((char *) w, (char **) &w);
+ u = v = fs_get(w-t);
+ for(; t < w; t++) *v++ = *t++;
+ *v = '\0';
+ rv = (void *) u;
json_skipws(w);
break;
@@ -477,3 +486,127 @@ json_by_name_and_type(JSON_S *json, char *name, JObjType jtype)
return j && j->jtype == jtype ? j : NIL;
}
+
+#define JSON_ADD_NAME(X) { \
+ if((X)){ \
+ unsigned char *buf; \
+ size_t len; \
+ len = strlen((X)) + 4; \
+ buf = fs_get(len); \
+ sprintf(buf, "\"%s\":", (X)); \
+ buffer_add(rv, buf); \
+ fs_give((void **) &buf); \
+ } \
+}
+
+#define JSON_ADD_STRING_VALUE(X) { \
+ if((X)){ \
+ unsigned char *buf; \
+ size_t len; \
+ len = strlen((X)) + 3; \
+ buf = fs_get(len); \
+ sprintf(buf, "\"%s\"", (X)); \
+ buffer_add(rv, buf); \
+ fs_give((void **) &buf); \
+ } \
+}
+
+#define JSON_ADD_LONG_VALUE(X) { \
+ if((X)){ \
+ unsigned char *buf; \
+ buf = fs_get(128 + 1); \
+ sprintf(buf, "%lu", (X)); \
+ buffer_add(rv, buf); \
+ fs_give((void **) &buf); \
+ } \
+}
+
+unsigned char *json2uchar(JSON_S *j, unsigned char **rv)
+{
+ JSON_S *jp;
+ unsigned char *buf = NIL;
+ unsigned long buflen = 0L;
+ size_t len;
+
+ if(!j || j->jtype != JObject) return *rv;
+
+ if(*rv) JSON_ADD_NAME(j->name);
+ buffer_add(rv, "{");
+
+ for(jp = (JSON_S *) j->value; jp; jp = jp->next){
+ switch(jp->jtype){
+ case JObject: *rv = json2uchar(jp, rv);
+ break;
+
+ case JString: JSON_ADD_NAME(jp->name);
+ JSON_ADD_STRING_VALUE((unsigned char *) jp->value);
+ break;
+
+ case JExponential:
+ case JDecimal:
+ case JNull:
+ case JBoolean: JSON_ADD_NAME(jp->name);
+ buffer_add(rv, (unsigned char *) jp->value);
+ break;
+
+ case JLong: JSON_ADD_NAME(jp->name);
+ JSON_ADD_LONG_VALUE(*(long *) jp->value);
+ break;
+
+ case JArray: JSON_ADD_NAME(jp->name);
+ *rv = json_add_array_value(jp, rv);
+ break;
+
+ default: break;
+ }
+ if(jp->next) buffer_add(rv, ",");
+ }
+
+ buffer_add(rv, "}");
+ return *rv;
+}
+
+unsigned char *json_add_array_value(JSON_S *j, unsigned char **rv)
+{
+ JSON_S *jp;
+ unsigned char *buf = NIL;
+ unsigned long buflen = 0L;
+ size_t len;
+
+ if(!j || j->jtype != JArray) return *rv;
+
+ if(*rv) JSON_ADD_NAME(j->name);
+ buffer_add(rv, "[");
+
+ for(jp = (JSON_S *) j->value; jp; jp = jp->next){
+ switch(jp->jtype){
+ case JObject: *rv = json2uchar(jp, rv);
+ break;
+
+ case JString: JSON_ADD_NAME(jp->name);
+ JSON_ADD_STRING_VALUE((unsigned char *) jp->value);
+ break;
+
+ case JExponential:
+ case JDecimal:
+ case JNull:
+ case JBoolean: JSON_ADD_NAME(jp->name);
+ buffer_add(rv, (unsigned char *) jp->value);
+ break;
+
+ case JLong: JSON_ADD_NAME(jp->name);
+ JSON_ADD_LONG_VALUE(*(long *) jp->value);
+ break;
+
+ case JArray: JSON_ADD_NAME(jp->name);
+ *rv = json_add_array_value(jp, rv);
+ break;
+
+ default: break;
+ }
+ if(jp->next) buffer_add(rv, ",");
+ }
+
+ buffer_add(rv, "]");
+ return *rv;
+}
diff --git a/imap/src/c-client/json.h b/imap/src/c-client/json.h
index ed7800f5..2911044b 100644
--- a/imap/src/c-client/json.h
+++ b/imap/src/c-client/json.h
@@ -38,5 +38,6 @@ JSON_S *json_by_name_and_type(JSON_S *, char *, JObjType);
JSON_S *json_parse(unsigned char *);
JSON_S *json_body_value(JSON_S *, unsigned char *);
void json_free(JSON_S **);
+unsigned char *json2uchar(JSON_S *, unsigned char **);
#endif /* JSON_H_INCLUDED */
diff --git a/imap/src/c-client/misc.c b/imap/src/c-client/misc.c
index 0ddab9cc..621118b2 100644
--- a/imap/src/c-client/misc.c
+++ b/imap/src/c-client/misc.c
@@ -490,3 +490,16 @@ int compare_csizedtext (unsigned char *s1,SIZEDTEXT *s2)
if (*s1) return 1; /* first string is longer */
return j ? -1 : 0; /* second string longer : strings identical */
}
+
+void
+buffer_add(unsigned char **bufp, unsigned char *text)
+{
+ size_t len;
+
+ if(!bufp || !text || !*text) return;
+
+ len = *bufp ? strlen(*bufp) : 0;
+ fs_resize((void **) bufp, len + strlen(text) + 1);
+ (*bufp)[len] = '\0';
+ strcat(*bufp, text);
+}
diff --git a/imap/src/c-client/misc.h b/imap/src/c-client/misc.h
index 4e7afc23..b178124d 100644
--- a/imap/src/c-client/misc.h
+++ b/imap/src/c-client/misc.h
@@ -105,3 +105,4 @@ int compare_uchar (unsigned char c1,unsigned char c2);
int compare_string (unsigned char *s1,unsigned char *s2);
int compare_cstring (unsigned char *s1,unsigned char *s2);
int compare_csizedtext (unsigned char *s1,SIZEDTEXT *s2);
+void buffer_add(unsigned char **, unsigned char *);