-
Notifications
You must be signed in to change notification settings - Fork 338
Expand file tree
/
Copy pathjsonParser.cpp
More file actions
185 lines (162 loc) · 5.9 KB
/
jsonParser.cpp
File metadata and controls
185 lines (162 loc) · 5.9 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
Usage:
char value[];
String json = http.getString();
const char* var = "find";
getJsonValue(json.c_str(), var, value, 2);
// 'value' contains returned value associated with variable
s60sc 2026
*/
#include "appGlobals.h"
static std::string extractNestedValue(const std::string& jsonObject, const std::string& nestedKey);
static void skipWhitespace(const std::string& json, size_t& pos) {
while (pos < json.length() && std::isspace(json[pos])) pos++;
}
static std::string parseString(const std::string& json, size_t& pos) {
if (json[pos] != '"') return "";
pos++; // Skip opening quote
size_t start = pos;
while (pos < json.length()) {
if (json[pos] == '\\') pos += 2; // Skip escaped character
else if (json[pos] == '"') {
std::string result = json.substr(start, pos - start);
pos++; // Skip closing quote
return result;
} else pos++;
}
return "";
}
static void skipValue(const std::string& json, size_t& pos) {
if (json[pos] == '"') parseString(json, pos);
else if (json[pos] == '{') {
int depth = 1;
pos++;
while (pos < json.length() && depth > 0) {
if (json[pos] == '"') parseString(json, pos);
else if (json[pos] == '{') {
depth++;
pos++;
} else if (json[pos] == '}') {
depth--;
pos++;
} else pos++;
}
} else if (json[pos] == '[') {
int depth = 1;
pos++;
while (pos < json.length() && depth > 0) {
if (json[pos] == '"') parseString(json, pos);
else if (json[pos] == '[') {
depth++;
pos++;
} else if (json[pos] == ']') {
depth--;
pos++;
} else pos++;
}
} else {
// Number, boolean, null
while (pos < json.length() &&
json[pos] != ',' &&
json[pos] != '}' &&
json[pos] != ']') {
pos++;
}
}
}
static std::string parseValue(const std::string& json, size_t& pos) {
size_t start = pos;
if (json[pos] == '"') return parseString(json, pos);
else if (json[pos] == '{' || json[pos] == '[') {
skipValue(json, pos);
return json.substr(start, pos - start);
} else {
// Number, boolean, null - trim whitespace
while (pos < json.length() && json[pos] != ','
&& json[pos] != '}' && json[pos] != ']' && !std::isspace(json[pos])) pos++;
}
std::string result = json.substr(start, pos - start);
// Trim trailing whitespace
size_t end = result.find_last_not_of(" \t\n\r");
return (end != std::string::npos) ? result.substr(0, end + 1) : result;
}
// Recursively search through entire JSON structure for nth occurrence
static std::string findNthOccurrence(const std::string& json, size_t& pos, const std::string& key, int& occurrence, int targetOccurrence, bool extractNested = false, const std::string& nestedKey = "") {
skipWhitespace(json, pos);
if (pos >= json.length()) return "";
if (json[pos] == '{') {
pos++;
while (pos < json.length()) {
skipWhitespace(json, pos);
if (json[pos] == '}') {
pos++;
break;
}
// Parse key
std::string currentKey = parseString(json, pos);
skipWhitespace(json, pos);
if (pos >= json.length() || json[pos] != ':') return "";
pos++;
skipWhitespace(json, pos);
// Check if this is our key
if (currentKey == key) {
occurrence++;
if (occurrence == targetOccurrence) {
std::string value = parseValue(json, pos);
// If we need to extract a nested value from the object
if (extractNested && !nestedKey.empty() && !value.empty() && value[0] == '{') {
return extractNestedValue(value, nestedKey);
}
return value;
} else skipValue(json, pos);
} else {
// Recursively search in nested structures
if (json[pos] == '{' || json[pos] == '[') {
std::string result = findNthOccurrence(json, pos, key, occurrence, targetOccurrence, extractNested, nestedKey);
if (!result.empty()) return result;
} else skipValue(json, pos);
}
skipWhitespace(json, pos);
if (pos < json.length() && json[pos] == ',') pos++;
}
} else if (json[pos] == '[') {
pos++;
while (pos < json.length()) {
skipWhitespace(json, pos);
if (json[pos] == ']') {
pos++;
break;
}
// Recursively search array elements
if (json[pos] == '{' || json[pos] == '[') {
std::string result = findNthOccurrence(json, pos, key, occurrence, targetOccurrence, extractNested, nestedKey);
if (!result.empty()) return result;
} else skipValue(json, pos);
skipWhitespace(json, pos);
if (pos < json.length() && json[pos] == ',') pos++;
}
}
return "";
}
// New helper function to extract a nested value
static std::string extractNestedValue(const std::string& jsonObject, const std::string& nestedKey) {
size_t pos = 0;
int count = 0;
return findNthOccurrence(jsonObject, pos, nestedKey, count, 1);
}
// Updated function signatures
bool getJsonValue(const char* json, const char* key, char* value, const char* nestedKey, int occurrence) {
// Returns nth occurrence (1-indexed, default is 1)
// If nestedKey is provided, extracts that field from the object value
std::string jsonStr = json;
std::string keyStr = key;
if (occurrence < 1) occurrence = 1;
size_t pos = 0;
int count = 0;
bool extractNested = (nestedKey != nullptr && strlen(nestedKey) > 0);
std::string nestedKeyStr = extractNested ? nestedKey : "";
std::string retvalue = findNthOccurrence(jsonStr, pos, keyStr, count, occurrence, extractNested, nestedKeyStr);
strncpy(value, retvalue.c_str(), FILE_NAME_LEN - 1);
value[FILE_NAME_LEN - 1] = '\0';
return retvalue.length() ? true : false;
}