20 FILE*
fp = fopen(filename,
"r");
22 cm_msg(
MERROR,
"db_load_json",
"file \"%s\" not found", filename);
30 int rd =
read(fileno(
fp), buf,
sizeof(buf)-1);
35 cm_msg(
MERROR,
"db_load_json",
"file \"%s\" read error %d (%s)", filename, errno, strerror(errno));
40 buf[
sizeof(buf)-1] = 0;
49 const char* jptr = strchr(
data.c_str(),
'{');
52 cm_msg(
MERROR,
"db_load_json",
"file \"%s\" does not look like JSON data", filename);
59 cm_msg(
MERROR,
"db_load_json",
"error loading JSON data from file \"%s\"", filename);
70 const MJsonNode*
n =
key->FindObjectNode(
"type");
73 int tid =
n->GetInt();
83 const MJsonNode*
n =
key->FindObjectNode(
"item_size");
86 int item_size =
n->GetInt();
94 switch (node->GetType()) {
95 case MJSON_ARRAY: {
const MJsonNodeVector* a = node->GetArray();
if (a && a->size()>0)
return guess_tid((*a)[0]);
else return 0; }
96 case MJSON_OBJECT:
return TID_KEY;
98 std::string v = node->GetString();
101 else if (v ==
"Infinity")
103 else if (v ==
"-Infinity")
105 else if (v[0]==
'0' && v[1]==
'x' && isxdigit(v[2]) && v.length() > 10)
107 else if (v[0]==
'0' && v[1]==
'x' && isxdigit(v[2]))
112 case MJSON_INT:
return TID_INT;
124 const MJsonNodeVector* a = node->GetArray();
127 cm_msg(
MERROR,
"db_paste_json",
"invalid array at \"%s\"", path);
131 if (string_length == 0) {
136 slength = string_length;
142 cm_msg(
MERROR,
"db_paste_json",
"cannot get odb key at \"%s\", status %d", path,
status);
149 cm_msg(
MERROR,
"db_paste_json",
"cannot resize key \"%s\", status = %d", path,
status);
154 bool is_array = (a->size() > 1);
155 for (
unsigned i=a->size(); ;) {
159 MJsonNode*
n = (*a)[
i];
164 cm_msg(
MERROR,
"db_paste_json",
"skipping write-protected array \"%s\"", path);
180 const MJsonStringVector* names = objnode->GetObjectNames();
181 const MJsonNodeVector* nodes = objnode->GetObjectNodes();
182 if (names==NULL||nodes==NULL||names->size()!=nodes->size()) {
183 cm_msg(
MERROR,
"db_paste_json",
"invalid object at \"%s\"", path);
186 for(
unsigned i=0;
i<names->size();
i++) {
187 const char*
name = (*names)[
i].c_str();
188 const MJsonNode* node = (*nodes)[
i];
189 const MJsonNode*
key = NULL;
190 if (strchr(
name,
'/'))
193 if (node->GetType() == MJSON_OBJECT)
196 key = objnode->FindObjectNode((std::string(
name) +
"/key").c_str());
211 cm_msg(
MERROR,
"db_paste_json",
"key exists, but cannot find it \"%s\" of type %d in \"%s\", db_find_link() status %d",
name, tid, path,
status);
217 cm_msg(
MERROR,
"db_paste_json",
"cannot create \"%s\" of type %d in \"%s\", db_create_key() status %d",
name, tid, path,
status);
226 cm_msg(
MERROR,
"db_paste_json",
"cannot overwrite existing item \"%s\" of type %d in \"%s\" with new tid %d",
name,
key.
type, path, tid);
232 cm_msg(
MERROR,
"db_paste_json",
"cannot create \"%s\" of type %d in \"%s\", db_create_key() status %d",
name, tid, path,
status);
239 cm_msg(
MERROR,
"db_paste_json",
"cannot find \"%s\" of type %d in \"%s\", db_find_link() status %d",
name, tid, path,
status);
243 std::string node_name;
244 if (strcmp(path,
"/") != 0) {
252 cm_msg(
MERROR,
"db_paste_json",
"skipping write-protected node \"%s\"", node_name.c_str());
254 cm_msg(
MERROR,
"db_paste_json",
"paste of \"%s\" is incomplete", node_name.c_str());
266 int size =
sizeof(
value);
269 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_BOOL value for \"%s\", db_set_data_index() status %d", path,
status);
277 switch (node->GetType()) {
279 cm_msg(
MERROR,
"db_paste_json",
"GetDWORD: unexpected node type %d at \"%s\"", node->GetType(), path);
283 *dw = node->GetInt();
286 *dw = (
DWORD)node->GetDouble();
289 std::string s = node->GetString();
291 if (s[0] ==
'0' && s[1] ==
'x') {
292 *dw = strtoul(s.c_str(), NULL, 16);
293 }
else if (s.back() ==
'b') {
294 *dw = strtoul(s.c_str(), NULL, 2);
295 }
else if (isdigit(s[0]) || (s[0]==
'-' && isdigit(s[1]))) {
296 *dw = strtoul(s.c_str(), NULL, 0);
298 cm_msg(
MERROR,
"db_paste_json",
"GetDWORD: MJSON_STRING node invalid numeric value \'%s\' at \"%s\"", s.c_str(), path);
303 cm_msg(
MERROR,
"db_paste_json",
"GetDWORD: MJSON_STRING node invalid numeric value \'%s\', strtoul() errno %d (%s) at \"%s\"", s.c_str(), errno, strerror(errno), path);
314 switch (node->GetType()) {
316 cm_msg(
MERROR,
"db_paste_json",
"GetQWORD: unexpected node type %d at \"%s\"", node->GetType(), path);
323 *qw = node->GetDouble();
326 std::string s = node->GetString();
328 if (s[0] ==
'0' && s[1] ==
'x') {
329 *qw = strtoull(s.c_str(), NULL, 16);
330 }
else if (s.back() ==
'b') {
331 *qw = strtoull(s.c_str(), NULL, 2);
332 }
else if (isdigit(s[0]) || (s[0]==
'-' && isdigit(s[1]))) {
333 *qw = strtoull(s.c_str(), NULL, 0);
335 cm_msg(
MERROR,
"db_paste_json",
"GetQWORD: MJSON_STRING node invalid numeric value \'%s\' at \"%s\"", s.c_str(), path);
340 cm_msg(
MERROR,
"db_paste_json",
"GetQWORD: MJSON_STRING node invalid numeric value \'%s\', strtoul() errno %d (%s) at \"%s\"", s.c_str(), errno, strerror(errno), path);
349static int GetDOUBLE(
const MJsonNode* node,
const char* path,
double* dw)
351 switch (node->GetType()) {
353 cm_msg(
MERROR,
"db_paste_json",
"GetDOUBLE: unexpected node type %d at \"%s\"", node->GetType(), path);
357 *dw = node->GetInt();
360 *dw = node->GetDouble();
363 std::string s = node->GetString();
365 if (s ==
"NaN" || s ==
"Infinity" || s ==
"-Infinity") {
366 *dw = node->GetDouble();
367 }
else if (s[0] ==
'0' && s[1] ==
'x') {
368 *dw = strtoul(s.c_str(), NULL, 16);
369 }
else if (isdigit(s[0]) || (s[0]==
'-' && isdigit(s[1]))) {
370 *dw = strtod(s.c_str(), NULL);
372 cm_msg(
MERROR,
"db_paste_json",
"GetDOUBLE: MJSON_STRING node invalid numeric value \'%s\' at \"%s\"", s.c_str(), path);
377 cm_msg(
MERROR,
"db_paste_json",
"GetDOUBLE: MJSON_STRING node invalid numeric value \'%s\', strtoul() errno %d (%s) at \"%s\"", s.c_str(), errno, strerror(errno), path);
393 cm_msg(
MERROR,
"db_paste_json",
"do not know what to do with tid %d at \"%s\"", tid, path);
397 cm_msg(
MERROR,
"db_paste_json",
"paste of TID_ARRAY is not implemented at \"%s\"", path);
400 cm_msg(
MERROR,
"db_paste_json",
"paste of TID_STRUCT is not implemented at \"%s\"", path);
403 cm_msg(
MERROR,
"db_paste_json",
"paste of TID_BITFIELD is not implemented at \"%s\"", path);
406 const std::string
value = node->GetString();
410 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_CHAR value for \"%s\", db_set_data_index() status %d", path,
status);
417 if (node->GetType() == MJSON_STRING && node->GetString() ==
"true") {
419 }
else if (node->GetType() == MJSON_STRING && node->GetString() ==
"false") {
421 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'y') {
423 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'n') {
425 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'Y') {
427 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'N') {
429 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
't') {
431 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'f') {
433 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'T') {
435 }
else if (node->GetType() == MJSON_STRING && node->GetString()[0] ==
'F') {
445 int size =
sizeof(v);
448 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_BOOL value for \"%s\", db_set_data_index() status %d", path,
status);
460 int size =
sizeof(b);
463 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_BYTE/TID_SBYTE value for \"%s\", db_set_data_index() status %d", path,
status);
475 int size =
sizeof(v);
478 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_WORD/TID_SHORT value for \"%s\", db_set_data_index() status %d", path,
status);
488 int size =
sizeof(v);
491 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_DWORD value for \"%s\", db_set_data_index() status %d", path,
status);
498 switch (node->GetType()) {
500 cm_msg(
MERROR,
"db_paste_json",
"unexpected node type %d at \"%s\"", node->GetType(), path);
507 double dv = node->GetDouble();
508 if (dv > INT_MAX || dv < INT_MIN) {
509 cm_msg(
MERROR,
"db_paste_json",
"numeric value %f out of range at \"%s\"", dv, path);
522 int size =
sizeof(v);
525 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_INT value for \"%s\", db_set_data_index() status %d", path,
status);
536 int size =
sizeof(v);
539 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_UINT64 value for \"%s\", db_set_data_index() status %d", path,
status);
550 int size =
sizeof(v);
553 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_INT64 value for \"%s\", db_set_data_index() status %d", path,
status);
565 int size =
sizeof(v);
568 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_FLOAT value for \"%s\", db_set_data_index() status %d", path,
status);
578 int size =
sizeof(v);
581 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_DOUBLE value for \"%s\", db_set_data_index() status %d", path,
status);
588 const char* ptr = NULL;
590 const std::string
value = node->GetString();
591 if (string_length == 0)
595 buf =
new char[string_length];
596 mstrlcpy(buf,
value.c_str(), string_length);
598 size = string_length;
601 size = strlen(ptr) + 1;
608 cm_msg(
MERROR,
"db_paste_json",
"cannot get key of string array for \"%s\", db_get_key() status %d", path,
status);
615 cm_msg(
MERROR,
"db_paste_json",
"cannot change array string length from %d to %d for \"%s\", db_resize_string() status %d",
key.
item_size, size, path,
status);
623 if (string_length > 0) {
629 }
else if (
index != 0) {
630 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_STRING value for \"%s\" index %d, it is not an array", path,
index);
640 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_STRING value for \"%s\", db_set_data_index() status %d", path,
status);
647 std::string value_string = node->GetString();
648 const char*
value = value_string.c_str();
649 int size = strlen(
value) + 1;
654 cm_msg(
MERROR,
"db_paste_json",
"cannot set TID_LINK value for \"%s\", db_set_data() status %d", path,
status);
667 switch (node->GetType()) {
675 cm_msg(
MERROR,
"db_paste_json",
"JSON parse error: \"%s\" at \"%s\"", node->GetError().c_str(), path);
678 cm_msg(
MERROR,
"db_paste_json",
"unexpected JSON null value at \"%s\"", path);
681 cm_msg(
MERROR,
"db_paste_json",
"unexpected JSON node type %d (%s) at \"%s\"", node->GetType(), MJsonNode::TypeToString(node->GetType()), path);
693 MJsonNode* node = MJsonNode::Parse(buffer);
712 int string_length = 0;
717 string_length = node->GetString().length()+1;
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
BOOL equal_ustring(const char *str1, const char *str2)
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
INT EXPRT db_paste_json(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
INT EXPRT db_resize_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int num_values, int max_string_length)
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
INT EXPRT db_load_json(HNDLE hDB, HNDLE hKey, const char *filename)
INT EXPRT db_paste_json_node(HNDLE hDB, HNDLE hKeyRoot, int index, const MJsonNode *node)
static int GetDOUBLE(const MJsonNode *node, const char *path, double *dw)
static int paste_value(HNDLE hDB, HNDLE hKey, const char *path, bool is_array, int index, const MJsonNode *node, int tid, int string_length, const MJsonNode *key)
static int paste_bool(HNDLE hDB, HNDLE hKey, const char *path, int index, const MJsonNode *node)
static int paste_array(HNDLE hDB, HNDLE hKey, const char *path, const MJsonNode *node, int tid, int string_length, const MJsonNode *key)
static int paste_object(HNDLE hDB, HNDLE hKey, const char *path, const MJsonNode *objnode)
static int GetDWORD(const MJsonNode *node, const char *path, DWORD *dw)
static int guess_tid(const MJsonNode *node)
static int paste_node(HNDLE hDB, HNDLE hKey, const char *path, bool is_array, int index, const MJsonNode *node, int tid, int string_length, const MJsonNode *key)
static int GetQWORD(const MJsonNode *node, const char *path, UINT64 *qw)
static int item_size_from_key(const MJsonNode *key)
static int tid_from_key(const MJsonNode *key)
unsigned long long UINT64