-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjson.c
More file actions
134 lines (118 loc) · 3.05 KB
/
json.c
File metadata and controls
134 lines (118 loc) · 3.05 KB
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
129
130
131
132
133
134
#include "utils.h"
#include "json.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIGIT_MIN 48
#define DIGIT_MAX 57
void formatLineAsJson(Line *lin) {
// Return early if already formatted
if (lin->vlen > 0) return;
// Initialize key and val strings
String key;
String val;
initString(&key);
initString(&val);
// Set flags
int k = 1; // parsing key, initialize as true
int colon = 0; // colon encountered
// Iterate over each char of the line text
for (int i = 0; i < lin->len; i++) {
char c = lin->text[i];
if (k) {
// Handle colons
if (c == COLN) {
// First colon
if (!colon) {
colon = 1;
// double colon means base64 (::)
if (i + 1 < lin->len && lin->text[i + 1] == COLN) {
i++;
}
// optional space after colon(s)
if (i + 1 < lin->len && lin->text[i + 1] == SP) {
i++;
}
k = 0; // switch to value
} else {
appendString(&key, c); // stray colon inside key (unlikely)
}
} else {
appendString(&key, c);
}
} else {
appendString(&val, c);
}
}
// Assign key and value to line
assignKey(lin, &key);
int valIsString = 0;
for (int i = 0; i < val.len; i++) {
if (val.text[i] < DIGIT_MIN || val.text[i] > DIGIT_MAX) {
valIsString = 1;
break;
}
}
if (valIsString) {
prependString(&val, '"');
appendString(&val, '"');
}
appendVal(lin, &val);
// Cleanup temporary strings
freeString(&key);
freeString(&val);
}
void printJSON(Document *doc) {
// Output JSON array start
printf("[\n");
// Iterate over each entry in document
for (int i = 0; i < doc->elen; i++) {
printf(IDNT2);
printf("{\n");
// Iterate over each line in entry
for (int j = 0; j < doc->entries[i]->len; j++) {
char *closing;
if (j == doc->entries[i]->len - 1) {
closing = "\n";
} else {
closing = ",\n";
}
printf(IDNT4);
printf("\"%s\": ", doc->entries[i]->lines[j]->key->text);
// Check if line has multiple values
if (doc->entries[i]->lines[j]->vlen > 1) {
printf("[\n");
// Iterate over each value in line
for (int k = 0; k < doc->entries[i]->lines[j]->vlen; k++) {
char *closing;
if (k == doc->entries[i]->lines[j]->vlen - 1) {
closing = "\n";
} else {
closing = ",\n";
}
printf(IDNT6);
printf("%s%s", doc->entries[i]->lines[j]->vals[k]->text, closing);
}
printf(IDNT4);
char *closing;
if (j == doc->entries[i]->len - 1) {
closing = "]\n";
} else {
closing = "],\n";
}
printf("%s", closing);
} else {
printf("%s%s", doc->entries[i]->lines[j]->vals[0]->text, closing);
}
}
char *closing;
if (i == doc->elen - 1) {
closing = "}\n";
} else {
closing = "},\n";
}
printf(IDNT2);
printf("%s", closing);
}
printf("]\n");
}