Files
iptv-downloader/util/json.c
T

117 lines
3.6 KiB
C

#include "json.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
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, "&lt;");
else if (*s == '>') buf_str(b, "&gt;");
else if (*s == '&') buf_str(b, "&amp;");
else if (*s == '"') buf_str(b, "&quot;");
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;
}