-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjson.c
131 lines (113 loc) · 3.04 KB
/
json.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <unistd.h>
#include "json.h"
// Create a null-terminated string with the characters
// between 'start' and 'end' inclusive.
static char *stringify(const char *start, const char *end)
{
char *str;
size_t len = end - start + 1;
if ((str = malloc(len+1)) != NULL) {
memcpy(str, start, len);
str[len] = '\0';
}
return str;
}
// Search the specified buffer for the outermost JSON object: e.g.
//
// {"user':"John Doe","age":"35","gender":"male"}
//
int jsonFindObject(const char *data, size_t dataLen, JsonObject *pObj)
{
// Locate the left curly brace
if ((pObj->start = strchr(data, '{')) != NULL) {
int level = 0;
const char *pEnd = data + dataLen;
// Locate the matching right curly brace which
// terminates the JSON object.
for (char *p = pObj->start; p != pEnd; p++) {
if (*p == '{') {
level++;
} else if (*p == '}') {
level--;
}
if (level == 0) {
pObj->end = p;
return 0;
}
}
}
return -1;
}
static void dumpText(const char *data, size_t dataLen)
{
const char *pEnd = data + dataLen;
for (const char *p = data; p <= pEnd; p++) {
fputc(*p, stdout);
}
fputc('\n', stdout);
fflush(stdout);
}
// Dump the JSON object
void jsonDumpObject(const JsonObject *pObj)
{
dumpText(pObj->start, (pObj->end - pObj->start));
}
// Locate the specified tag within the given JSON object and
// return a pointer to its value: e.g. given the following
// JSON object:
//
// { ..., "username" : "mmourier", ... }
//
// the call:
//
// jsonFindTag(pObj, "username");
//
// would return a pointer to the following string:
//
// |
// V
// { ..., "username" : "mmourier", ... }
//
const char *jsonFindTag(const JsonObject *pObj, const char *tag)
{
char label[256];
size_t len;
snprintf(label, sizeof (label), "\"%s\"", tag);
len = strlen(label);
for (const char *p = (pObj->start + 1); p < pObj->end; p++) {
if (memcmp(p, label, len) == 0) {
for (p += len; p < pObj->end; p++) {
int c = *p;
if (isspace(c) || (c == ':'))
continue;
return p;
}
}
}
return NULL;
}
// Format is: "<tag>":"<val>" where the value is a string in
// double quotes.
char *jsonGetTagValue(const JsonObject *pObj, const char *tag)
{
const char *val;
if ((val = jsonFindTag(pObj, tag)) != NULL) {
const char *openQuotes = strchr(val, '"');
if (openQuotes != NULL) {
const char *endQuotes = strchr((openQuotes+1), '"');
if (endQuotes != NULL) {
return stringify((openQuotes+1), (endQuotes - 1));
}
}
}
return NULL;
}