CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Data/Format/JSONReader.cpp
Views: 1401
1
#include "Common/Data/Format/JSONReader.h"
2
#include "Common/File/VFS/VFS.h"
3
#include "Common/File/Path.h"
4
#include "Common/File/FileUtil.h"
5
#include "Common/Log.h"
6
7
namespace json {
8
9
JsonReader::JsonReader(const std::string &filename) {
10
size_t buf_size;
11
buffer_ = (char *)g_VFS.ReadFile(filename.c_str(), &buf_size);
12
if (buffer_) {
13
parse();
14
} else {
15
// Okay, try to read on the local file system
16
buffer_ = (char *)File::ReadLocalFile(Path(filename), &buf_size);
17
if (buffer_) {
18
parse();
19
} else {
20
ERROR_LOG(Log::IO, "Failed to read json file '%s'", filename.c_str());
21
}
22
}
23
}
24
25
bool JsonReader::parse() {
26
char *error_pos;
27
int status = jsonParse(buffer_, &error_pos, &root_, alloc_);
28
if (status != JSON_OK) {
29
ERROR_LOG(Log::IO, "Error at (%i): %s\n%s\n\n", (int)(error_pos - buffer_), jsonStrError(status), error_pos);
30
return false;
31
}
32
ok_ = true;
33
return true;
34
}
35
36
int JsonGet::numChildren() const {
37
int count = 0;
38
if (value_.getTag() == JSON_OBJECT || value_.getTag() == JSON_ARRAY) {
39
for (auto it : value_) {
40
(void)it;
41
count++;
42
}
43
}
44
return count;
45
}
46
47
const JsonNode *JsonGet::get(const char *child_name) const {
48
if (!child_name) {
49
ERROR_LOG(Log::IO, "JSON: Cannot get from null child name");
50
return nullptr;
51
}
52
if (value_.getTag() != JSON_OBJECT) {
53
return nullptr;
54
}
55
for (auto it : value_) {
56
if (!strcmp(it->key, child_name)) {
57
return it;
58
}
59
}
60
return nullptr;
61
}
62
63
const JsonNode *JsonGet::get(const char *child_name, JsonTag type) const {
64
const JsonNode *v = get(child_name);
65
if (v && type == v->value.getTag())
66
return v;
67
return nullptr;
68
}
69
70
const char *JsonGet::getStringOrNull(const char *child_name) const {
71
const JsonNode *val = get(child_name, JSON_STRING);
72
if (val)
73
return val->value.toString();
74
ERROR_LOG(Log::IO, "String '%s' missing from node", child_name);
75
return nullptr;
76
}
77
78
bool JsonGet::getString(const char *child_name, std::string *output) const {
79
const JsonNode *val = get(child_name, JSON_STRING);
80
if (!val) {
81
return false;
82
}
83
*output = val->value.toString();
84
return true;
85
}
86
87
const char *JsonGet::getStringOr(const char *child_name, const char *default_value) const {
88
const JsonNode *val = get(child_name, JSON_STRING);
89
if (!val)
90
return default_value;
91
return val->value.toString();
92
}
93
94
bool JsonGet::getStringVector(std::vector<std::string> *vec) const {
95
vec->clear();
96
if (value_.getTag() == JSON_ARRAY) {
97
for (auto it : value_) {
98
if (it->value.getTag() == JSON_STRING) {
99
vec->push_back(it->value.toString());
100
}
101
}
102
return true;
103
} else {
104
return false;
105
}
106
}
107
108
double JsonGet::getFloat(const char *child_name) const {
109
return get(child_name, JSON_NUMBER)->value.toNumber();
110
}
111
112
double JsonGet::getFloat(const char *child_name, double default_value) const {
113
const JsonNode *val = get(child_name, JSON_NUMBER);
114
if (!val)
115
return default_value;
116
return val->value.toNumber();
117
}
118
119
int JsonGet::getInt(const char *child_name) const {
120
return (int)get(child_name, JSON_NUMBER)->value.toNumber();
121
}
122
123
int JsonGet::getInt(const char *child_name, int default_value) const {
124
const JsonNode *val = get(child_name, JSON_NUMBER);
125
if (!val)
126
return default_value;
127
return (int)val->value.toNumber();
128
}
129
130
bool JsonGet::getBool(const char *child_name) const {
131
return get(child_name)->value.getTag() == JSON_TRUE;
132
}
133
134
bool JsonGet::getBool(const char *child_name, bool default_value) const {
135
const JsonNode *val = get(child_name);
136
if (val) {
137
JsonTag tag = val->value.getTag();
138
if (tag == JSON_TRUE)
139
return true;
140
if (tag == JSON_FALSE)
141
return false;
142
}
143
return default_value;
144
}
145
146
} // namespace json
147
148