#include "json.h" #include #include #include #include char *json_str(const char *json, const char *key) { if (!json || !key) return NULL; char needle[128]; snprintf(needle, sizeof(needle), "\"%s\"", key); const char *p = strstr(json, needle); if (!p) return NULL; p += strlen(needle); while (*p == ' ' || *p == ':') p++; if (*p == '"') { p++; const char *end = p; while (*end && !(*end == '"' && *(end-1) != '\\')) end++; size_t len = end - p; char *r = malloc(len+1); memcpy(r, p, len); r[len] = 0; return r; } const char *end = p; while (*end && *end != ',' && *end != '}' && *end != ']') end++; size_t len = end - p; char *r = malloc(len+1); memcpy(r, p, len); r[len] = 0; return r; } char **json_array(const char *json, int *n) { *n = 0; if (!json) return NULL; const char *p = json; while (*p && *p != '[') p++; if (!*p) return NULL; p++; int cap = 64; char **arr = malloc(cap * sizeof(char*)); int depth = 0; const char *obj_start = NULL; int in_str = 0; for (; *p; p++) { if (*p == '"' && (p == json || *(p-1) != '\\')) { in_str = !in_str; continue; } if (in_str) continue; if (*p == '{' || *p == '[') { if (depth == 0) obj_start = p; depth++; } else if (*p == '}' || *p == ']') { depth--; if (depth == 0 && obj_start) { size_t len = p - obj_start + 1; char *obj = malloc(len+1); memcpy(obj, obj_start, len); obj[len] = 0; if (*n >= cap) { cap *= 2; arr = realloc(arr, cap*sizeof(char*)); } arr[(*n)++] = obj; obj_start = NULL; if (*p == ']') break; } } } return arr; } void urldecode(char *s) { char *w = s, *r = s; while (*r) { if (*r == '%' && r[1] && r[2]) { char hex[3] = {r[1], r[2], 0}; *w++ = (char)strtol(hex, NULL, 16); r += 3; } else if (*r == '+') { *w++ = ' '; r++; } else { *w++ = *r++; } } *w = 0; } char *qparam(const char *qs, const char *key) { if (!qs || !key) return NULL; char needle[128]; snprintf(needle, sizeof(needle), "%s=", key); const char *p = strstr(qs, needle); if (!p) return NULL; p += strlen(needle); const char *end = strchr(p, '&'); size_t len = end ? (size_t)(end-p) : strlen(p); char *r = malloc(len+1); memcpy(r, p, len); r[len] = 0; urldecode(r); return r; } void html_esc(Buf *b, const char *s) { for (; *s; s++) { if (*s == '<') buf_str(b, "<"); else if (*s == '>') buf_str(b, ">"); else if (*s == '&') buf_str(b, "&"); else if (*s == '"') buf_str(b, """); else buf_append(b, s, 1); } } void js_esc(Buf *b, const char *s) { for (; *s; s++) { if (*s == '\'') buf_str(b, "\\'"); else if (*s == '\\') buf_str(b, "\\\\"); else if (*s == '\n' || *s == '\r') {} else buf_append(b, s, 1); } } void fwrite_json_str(FILE *f, const char *s) { fputc('"', f); for (; *s; s++) { if (*s == '"' || *s == '\\') fputc('\\', f); if ((unsigned char)*s >= 0x20) fputc(*s, f); } fputc('"', f); } int str_icontains(const char *hay, const char *needle) { if (!hay || !needle || !*needle) return 1; char h[2048], n[256]; strncpy(h, hay, sizeof(h)-1); h[sizeof(h)-1] = 0; strncpy(n, needle, sizeof(n)-1); n[sizeof(n)-1] = 0; for (char *p = h; *p; p++) if (*p >= 'A' && *p <= 'Z') *p += 32; for (char *p = n; *p; p++) if (*p >= 'A' && *p <= 'Z') *p += 32; return strstr(h, n) != NULL; }