MIDAS
Loading...
Searching...
No Matches
json_paste.cxx
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: json_paste.cxx
4 Created by: Konstantin Olchanski
5
6 Contents: JSON decoder for ODB
7
8\********************************************************************/
9
10#include "midas.h"
11#include "msystem.h"
12#include "mjson.h"
13#include "mstrlcpy.h"
14
15INT EXPRT db_load_json(HNDLE hDB, HNDLE hKey, const char *filename)
16{
17 int status;
18 //printf("db_load_json: filename [%s], handle %d\n", filename, hKey);
19
20 FILE* fp = fopen(filename, "r");
21 if (!fp) {
22 cm_msg(MERROR, "db_load_json", "file \"%s\" not found", filename);
23 return DB_FILE_ERROR;
24 }
25
26 std::string data;
27
28 while (1) {
29 char buf[102400];
30 int rd = read(fileno(fp), buf, sizeof(buf)-1);
31 if (rd == 0)
32 break; // end of file
33 if (rd < 0) {
34 // error
35 cm_msg(MERROR, "db_load_json", "file \"%s\" read error %d (%s)", filename, errno, strerror(errno));
36 fclose(fp);
37 return DB_FILE_ERROR;
38 }
39 // make sure string is nul terminated
40 buf[sizeof(buf)-1] = 0;
41 data += buf;
42 }
43
44 fclose(fp);
45 fp = NULL;
46
47 //printf("file contents: [%s]\n", data.c_str());
48
49 const char* jptr = strchr(data.c_str(), '{');
50
51 if (!jptr) {
52 cm_msg(MERROR, "db_load_json", "file \"%s\" does not look like JSON data", filename);
53 return DB_FILE_ERROR;
54 }
55
57
58 if (status != DB_SUCCESS) {
59 cm_msg(MERROR, "db_load_json", "error loading JSON data from file \"%s\"", filename);
60 return status;
61 }
62
63 return status;
64}
65
66static int tid_from_key(const MJsonNode* key)
67{
68 if (!key)
69 return 0;
70 const MJsonNode* n = key->FindObjectNode("type");
71 if (!n)
72 return 0;
73 int tid = n->GetInt();
74 if (tid > 0)
75 return tid;
76 return 0;
77}
78
79static int item_size_from_key(const MJsonNode* key)
80{
81 if (!key)
82 return 0;
83 const MJsonNode* n = key->FindObjectNode("item_size");
84 if (!n)
85 return 0;
86 int item_size = n->GetInt();
87 if (item_size > 0)
88 return item_size;
89 return 0;
90}
91
92static int guess_tid(const MJsonNode* node)
93{
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;
97 case MJSON_STRING: {
98 std::string v = node->GetString();
99 if (v == "NaN")
100 return TID_DOUBLE;
101 else if (v == "Infinity")
102 return TID_DOUBLE;
103 else if (v == "-Infinity")
104 return TID_DOUBLE;
105 else if (v[0]=='0' && v[1]=='x' && isxdigit(v[2]) && v.length() > 10)
106 return TID_UINT64;
107 else if (v[0]=='0' && v[1]=='x' && isxdigit(v[2]))
108 return TID_DWORD;
109 else
110 return TID_STRING;
111 }
112 case MJSON_INT: return TID_INT;
113 case MJSON_NUMBER: return TID_DOUBLE;
114 case MJSON_BOOL: return TID_BOOL;
115 default: return 0;
116 }
117}
118
119static 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);
120
121static int paste_array(HNDLE hDB, HNDLE hKey, const char* path, const MJsonNode* node, int tid, int string_length, const MJsonNode* key)
122{
123 int status, slength = 0;
124 const MJsonNodeVector* a = node->GetArray();
125
126 if (a==NULL) {
127 cm_msg(MERROR, "db_paste_json", "invalid array at \"%s\"", path);
128 return DB_FILE_ERROR;
129 }
130
131 if (string_length == 0) {
133 if (slength == 0)
135 } else {
137 }
138
139 KEY odbkey;
141 if (status != DB_SUCCESS) {
142 cm_msg(MERROR, "db_paste_json", "cannot get odb key at \"%s\", status %d", path, status);
143 return DB_FILE_ERROR;
144 }
145
146 if (odbkey.item_size > 0 && (INT) a->size() != odbkey.num_values) {
147 status = db_set_num_values(hDB, hKey, a->size());
148 if (status != DB_SUCCESS) {
149 cm_msg(MERROR, "db_paste_json", "cannot resize key \"%s\", status = %d", path, status);
150 return status;
151 }
152 }
153
154 bool is_array = (a->size() > 1);
155 for (unsigned i=a->size(); ;) {
156 if (i==0)
157 break;
158 i--;
159 MJsonNode* n = (*a)[i];
160 if (!n)
161 continue;
162 status = paste_node(hDB, hKey, path, is_array, i, n, tid, slength, key);
163 if (status == DB_NO_ACCESS) {
164 cm_msg(MERROR, "db_paste_json", "skipping write-protected array \"%s\"", path);
165 return DB_SUCCESS;
166 } else if (status != DB_SUCCESS)
167 return status;
168 }
169
170 return DB_SUCCESS;
171}
172
173static int paste_object(HNDLE hDB, HNDLE hKey, const char* path, const MJsonNode* objnode)
174{
175 if (equal_ustring(path, "/system/clients")) {
176 // do not reload ODB /system/clients
177 return DB_SUCCESS;
178 }
179 int status;
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);
184 return DB_FILE_ERROR;
185 }
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, '/')) // skip special entries
191 continue;
192 int tid = 0;
193 if (node->GetType() == MJSON_OBJECT)
194 tid = TID_KEY;
195 else {
196 key = objnode->FindObjectNode((std::string(name) + "/key").c_str());
197 if (key)
198 tid = tid_from_key(key);
199 if (!tid)
200 tid = guess_tid(node);
201 //printf("entry [%s] type %s, tid %d\n", name, MJsonNode::TypeToString(node->GetType()), tid);
202 }
203
204 status = db_create_key(hDB, hKey, name, tid);
205
206 if (status == DB_KEY_EXIST) {
208 KEY key;
210 if (status != DB_SUCCESS) {
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);
212 return status;
213 }
214
216 if (status != DB_SUCCESS) {
217 cm_msg(MERROR, "db_paste_json", "cannot create \"%s\" of type %d in \"%s\", db_create_key() status %d", name, tid, path, status);
218 return status;
219 }
220
221 if ((int)key.type == tid) {
222 // existing item is of the same type, continue with overwriting it
224 } else {
225 // FIXME: delete wrong item, create item with correct tid
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);
227 return status;
228 }
229 }
230
231 if (status != DB_SUCCESS) {
232 cm_msg(MERROR, "db_paste_json", "cannot create \"%s\" of type %d in \"%s\", db_create_key() status %d", name, tid, path, status);
233 return status;
234 }
235
238 if (status != DB_SUCCESS) {
239 cm_msg(MERROR, "db_paste_json", "cannot find \"%s\" of type %d in \"%s\", db_find_link() status %d", name, tid, path, status);
240 return status;
241 }
242
243 std::string node_name;
244 if (strcmp(path, "/") != 0) {
245 node_name += path;
246 }
247 node_name += "/";
248 node_name += name;
249
250 status = paste_node(hDB, hSubkey, node_name.c_str(), false, 0, node, tid, 0, key);
251 if (status == DB_NO_ACCESS) {
252 cm_msg(MERROR, "db_paste_json", "skipping write-protected node \"%s\"", node_name.c_str());
253 } else if (status != DB_SUCCESS) {
254 cm_msg(MERROR, "db_paste_json", "paste of \"%s\" is incomplete", node_name.c_str());
255 //cm_msg(MERROR, "db_paste_json", "cannot..."); // paste_node() reports it's own failures
256 return status;
257 }
258 }
259 return DB_SUCCESS;
260}
261
262static int paste_bool(HNDLE hDB, HNDLE hKey, const char* path, int index, const MJsonNode* node)
263{
264 int status;
265 BOOL value = node->GetBool();
266 int size = sizeof(value);
268 if (status != DB_SUCCESS) {
269 cm_msg(MERROR, "db_paste_json", "cannot set TID_BOOL value for \"%s\", db_set_data_index() status %d", path, status);
270 return status;
271 }
272 return DB_SUCCESS;
273}
274
275static int GetDWORD(const MJsonNode* node, const char* path, DWORD* dw)
276{
277 switch (node->GetType()) {
278 default:
279 cm_msg(MERROR, "db_paste_json", "GetDWORD: unexpected node type %d at \"%s\"", node->GetType(), path);
280 *dw = 0;
281 return DB_FILE_ERROR;
282 case MJSON_INT:
283 *dw = node->GetInt();
284 return SUCCESS;
285 case MJSON_NUMBER:
286 *dw = (DWORD)node->GetDouble();
287 return SUCCESS;
288 case MJSON_STRING:
289 std::string s = node->GetString();
290 errno = 0;
291 if (s[0] == '0' && s[1] == 'x') { // hex encoded number
292 *dw = strtoul(s.c_str(), NULL, 16);
293 } else if (s.back() == 'b') { // binary number
294 *dw = strtoul(s.c_str(), NULL, 2);
295 } else if (isdigit(s[0]) || (s[0]=='-' && isdigit(s[1]))) { // probably a number
296 *dw = strtoul(s.c_str(), NULL, 0);
297 } else {
298 cm_msg(MERROR, "db_paste_json", "GetDWORD: MJSON_STRING node invalid numeric value \'%s\' at \"%s\"", s.c_str(), path);
299 *dw = 0;
300 return DB_FILE_ERROR;
301 }
302 if (errno != 0) {
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);
304 *dw = 0;
305 return DB_FILE_ERROR;
306 }
307 return SUCCESS;
308 }
309 // NOT REACHED
310}
311
312static int GetQWORD(const MJsonNode* node, const char* path, UINT64* qw)
313{
314 switch (node->GetType()) {
315 default:
316 cm_msg(MERROR, "db_paste_json", "GetQWORD: unexpected node type %d at \"%s\"", node->GetType(), path);
317 *qw = 0;
318 return DB_FILE_ERROR;
319 case MJSON_INT:
320 *qw = node->GetLL();
321 return SUCCESS;
322 case MJSON_NUMBER:
323 *qw = node->GetDouble();
324 return SUCCESS;
325 case MJSON_STRING:
326 std::string s = node->GetString();
327 errno = 0;
328 if (s[0] == '0' && s[1] == 'x') { // hex encoded number
329 *qw = strtoull(s.c_str(), NULL, 16);
330 } else if (s.back() == 'b') { // binary number
331 *qw = strtoull(s.c_str(), NULL, 2);
332 } else if (isdigit(s[0]) || (s[0]=='-' && isdigit(s[1]))) { // probably a number
333 *qw = strtoull(s.c_str(), NULL, 0);
334 } else {
335 cm_msg(MERROR, "db_paste_json", "GetQWORD: MJSON_STRING node invalid numeric value \'%s\' at \"%s\"", s.c_str(), path);
336 *qw = 0;
337 return DB_FILE_ERROR;
338 }
339 if (errno != 0) {
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);
341 *qw = 0;
342 return DB_FILE_ERROR;
343 }
344 return SUCCESS;
345 }
346 // NOT REACHED
347}
348
349static int GetDOUBLE(const MJsonNode* node, const char* path, double* dw)
350{
351 switch (node->GetType()) {
352 default:
353 cm_msg(MERROR, "db_paste_json", "GetDOUBLE: unexpected node type %d at \"%s\"", node->GetType(), path);
354 *dw = 0;
355 return DB_FILE_ERROR;
356 case MJSON_INT:
357 *dw = node->GetInt();
358 return SUCCESS;
359 case MJSON_NUMBER:
360 *dw = node->GetDouble();
361 return SUCCESS;
362 case MJSON_STRING:
363 std::string s = node->GetString();
364 errno = 0;
365 if (s == "NaN" || s == "Infinity" || s == "-Infinity") {
366 *dw = node->GetDouble();
367 } else if (s[0] == '0' && s[1] == 'x') { // hex encoded number
368 *dw = strtoul(s.c_str(), NULL, 16);
369 } else if (isdigit(s[0]) || (s[0]=='-' && isdigit(s[1]))) { // probably a number
370 *dw = strtod(s.c_str(), NULL);
371 } else {
372 cm_msg(MERROR, "db_paste_json", "GetDOUBLE: MJSON_STRING node invalid numeric value \'%s\' at \"%s\"", s.c_str(), path);
373 *dw = 0;
374 return DB_FILE_ERROR;
375 }
376 if (errno != 0) {
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);
378 *dw = 0;
379 return DB_FILE_ERROR;
380 }
381 return SUCCESS;
382 }
383 // NOT REACHED
384}
385
386static 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)
387{
388 int status;
389 //printf("paste_value: path [%s], index %d, tid %d, slength %d, key %p\n", path, index, tid, string_length, key);
390
391 switch (tid) {
392 default:
393 cm_msg(MERROR, "db_paste_json", "do not know what to do with tid %d at \"%s\"", tid, path);
394 // keep loading remaining data, ignore this error return DB_FILE_ERROR;
395 return DB_SUCCESS;
396 case TID_ARRAY:
397 cm_msg(MERROR, "db_paste_json", "paste of TID_ARRAY is not implemented at \"%s\"", path);
398 return DB_SUCCESS;
399 case TID_STRUCT:
400 cm_msg(MERROR, "db_paste_json", "paste of TID_STRUCT is not implemented at \"%s\"", path);
401 return DB_SUCCESS;
402 case TID_BITFIELD:
403 cm_msg(MERROR, "db_paste_json", "paste of TID_BITFIELD is not implemented at \"%s\"", path);
404 return DB_SUCCESS;
405 case TID_CHAR: {
406 const std::string value = node->GetString();
407 int size = 1;
408 status = db_set_data_index(hDB, hKey, value.c_str(), size, index, TID_CHAR);
409 if (status != DB_SUCCESS) {
410 cm_msg(MERROR, "db_paste_json", "cannot set TID_CHAR value for \"%s\", db_set_data_index() status %d", path, status);
411 return status;
412 }
413 return DB_SUCCESS;
414 }
415 case TID_BOOL: {
416 BOOL v;
417 if (node->GetType() == MJSON_STRING && node->GetString() == "true") {
418 v = true;
419 } else if (node->GetType() == MJSON_STRING && node->GetString() == "false") {
420 v = false;
421 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'y') {
422 v = true;
423 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'n') {
424 v = false;
425 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'Y') {
426 v = true;
427 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'N') {
428 v = false;
429 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 't') {
430 v = true;
431 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'f') {
432 v = false;
433 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'T') {
434 v = true;
435 } else if (node->GetType() == MJSON_STRING && node->GetString()[0] == 'F') {
436 v = false;
437 } else {
438 DWORD dw;
439 status = GetDWORD(node, path, &dw);
440 if (status != SUCCESS)
441 return status;
442 if (dw) v = TRUE;
443 else v = FALSE;
444 }
445 int size = sizeof(v);
447 if (status != DB_SUCCESS) {
448 cm_msg(MERROR, "db_paste_json", "cannot set TID_BOOL value for \"%s\", db_set_data_index() status %d", path, status);
449 return status;
450 }
451 return DB_SUCCESS;
452 }
453 case TID_BYTE:
454 case TID_SBYTE: {
455 DWORD dw;
456 status = GetDWORD(node, path, &dw);
457 if (status != SUCCESS)
458 return status;
459 BYTE b = (BYTE)dw;
460 int size = sizeof(b);
461 status = db_set_data_index(hDB, hKey, &b, size, index, tid);
462 if (status != DB_SUCCESS) {
463 cm_msg(MERROR, "db_paste_json", "cannot set TID_BYTE/TID_SBYTE value for \"%s\", db_set_data_index() status %d", path, status);
464 return status;
465 }
466 return DB_SUCCESS;
467 }
468 case TID_WORD:
469 case TID_SHORT: {
470 DWORD dw;
471 status = GetDWORD(node, path, &dw);
472 if (status != SUCCESS)
473 return status;
474 WORD v = (WORD)dw;
475 int size = sizeof(v);
476 status = db_set_data_index(hDB, hKey, &v, size, index, tid);
477 if (status != DB_SUCCESS) {
478 cm_msg(MERROR, "db_paste_json", "cannot set TID_WORD/TID_SHORT value for \"%s\", db_set_data_index() status %d", path, status);
479 return status;
480 }
481 return DB_SUCCESS;
482 }
483 case TID_DWORD: {
484 DWORD v;
485 status = GetDWORD(node, path, &v);
486 if (status != SUCCESS)
487 return status;
488 int size = sizeof(v);
490 if (status != DB_SUCCESS) {
491 cm_msg(MERROR, "db_paste_json", "cannot set TID_DWORD value for \"%s\", db_set_data_index() status %d", path, status);
492 return status;
493 }
494 return DB_SUCCESS;
495 }
496 case TID_INT: {
497 int v = 0;
498 switch (node->GetType()) {
499 default:
500 cm_msg(MERROR, "db_paste_json", "unexpected node type %d at \"%s\"", node->GetType(), path);
501 return DB_FILE_ERROR;
502 case MJSON_INT: {
503 v = node->GetInt();
504 break;
505 }
506 case MJSON_NUMBER: {
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);
510 return DB_FILE_ERROR;
511 }
512 v = (int)dv;
513 break;
514 }
515 case MJSON_STRING: {
516 status = GetDWORD(node, path, (DWORD*)&v);
517 if (status != SUCCESS)
518 return status;
519 break;
520 }
521 }
522 int size = sizeof(v);
524 if (status != DB_SUCCESS) {
525 cm_msg(MERROR, "db_paste_json", "cannot set TID_INT value for \"%s\", db_set_data_index() status %d", path, status);
526 return status;
527 }
528 return DB_SUCCESS;
529 }
530
531 case TID_UINT64: {
532 UINT64 v;
533 status = GetQWORD(node, path, &v);
534 if (status != SUCCESS)
535 return status;
536 int size = sizeof(v);
538 if (status != DB_SUCCESS) {
539 cm_msg(MERROR, "db_paste_json", "cannot set TID_UINT64 value for \"%s\", db_set_data_index() status %d", path, status);
540 return status;
541 }
542 return DB_SUCCESS;
543 }
544
545 case TID_INT64: {
546 INT64 v;
547 status = GetQWORD(node, path, (UINT64 *)&v);
548 if (status != SUCCESS)
549 return status;
550 int size = sizeof(v);
552 if (status != DB_SUCCESS) {
553 cm_msg(MERROR, "db_paste_json", "cannot set TID_INT64 value for \"%s\", db_set_data_index() status %d", path, status);
554 return status;
555 }
556 return DB_SUCCESS;
557 }
558
559 case TID_FLOAT: {
560 double dv;
561 status = GetDOUBLE(node, path, &dv);
562 if (status != SUCCESS)
563 return status;
564 float v = dv;
565 int size = sizeof(v);
567 if (status != DB_SUCCESS) {
568 cm_msg(MERROR, "db_paste_json", "cannot set TID_FLOAT value for \"%s\", db_set_data_index() status %d", path, status);
569 return status;
570 }
571 return DB_SUCCESS;
572 }
573 case TID_DOUBLE: {
574 double v;
575 status = GetDOUBLE(node, path, &v);
576 if (status != SUCCESS)
577 return status;
578 int size = sizeof(v);
580 if (status != DB_SUCCESS) {
581 cm_msg(MERROR, "db_paste_json", "cannot set TID_DOUBLE value for \"%s\", db_set_data_index() status %d", path, status);
582 return status;
583 }
584 return DB_SUCCESS;
585 }
586 case TID_STRING: {
587 char* buf = NULL;
588 const char* ptr = NULL;
589 int size = 0;
590 const std::string value = node->GetString();
591 if (string_length == 0)
593 //printf("string_length %d\n", string_length);
594 if (string_length) {
595 buf = new char[string_length];
596 mstrlcpy(buf, value.c_str(), string_length);
597 ptr = buf;
598 size = string_length;
599 } else {
600 ptr = value.c_str();
601 size = strlen(ptr) + 1;
602 }
603
604 if (is_array) {
605 KEY key;
607 if (status != DB_SUCCESS) {
608 cm_msg(MERROR, "db_paste_json", "cannot get key of string array for \"%s\", db_get_key() status %d", path, status);
609 return status;
610 }
611
612 if (key.item_size < size) {
614 if (status != DB_SUCCESS) {
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);
616 return status;
617 }
618 }
619 }
620
621 //printf("set_data_index index %d, size %d\n", index, size);
622
623 if (string_length > 0) {
624 if (is_array) {
626 } else {
627 status = db_set_data(hDB, hKey, ptr, size, 1, TID_STRING);
628 }
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);
632 } else {
633 status = db_set_data(hDB, hKey, ptr, size, 1, TID_STRING);
634 }
635
636 if (buf)
637 delete[] buf;
638
639 if (status != DB_SUCCESS) {
640 cm_msg(MERROR, "db_paste_json", "cannot set TID_STRING value for \"%s\", db_set_data_index() status %d", path, status);
641 return status;
642 }
643
644 return DB_SUCCESS;
645 }
646 case TID_LINK: {
647 std::string value_string = node->GetString();
648 const char* value = value_string.c_str();
649 int size = strlen(value) + 1;
650
651 status = db_set_data(hDB, hKey, value, size, 1, TID_LINK);
652
653 if (status != DB_SUCCESS) {
654 cm_msg(MERROR, "db_paste_json", "cannot set TID_LINK value for \"%s\", db_set_data() status %d", path, status);
655 return status;
656 }
657
658 return DB_SUCCESS;
659 }
660 }
661 // NOT REACHED
662}
663
664static 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)
665{
666 //node->Dump();
667 switch (node->GetType()) {
668 case MJSON_ARRAY: return paste_array(hDB, hKey, path, node, tid, string_length, key);
669 case MJSON_OBJECT: return paste_object(hDB, hKey, path, node);
670 case MJSON_STRING: return paste_value(hDB, hKey, path, is_array, index, node, tid, string_length, key);
671 case MJSON_INT: return paste_value(hDB, hKey, path, is_array, index, node, tid, 0, key);
672 case MJSON_NUMBER: return paste_value(hDB, hKey, path, is_array, index, node, tid, 0, key);
673 case MJSON_BOOL: return paste_bool(hDB, hKey, path, index, node);
674 case MJSON_ERROR:
675 cm_msg(MERROR, "db_paste_json", "JSON parse error: \"%s\" at \"%s\"", node->GetError().c_str(), path);
676 return DB_FILE_ERROR;
677 case MJSON_NULL:
678 cm_msg(MERROR, "db_paste_json", "unexpected JSON null value at \"%s\"", path);
679 return DB_FILE_ERROR;
680 default:
681 cm_msg(MERROR, "db_paste_json", "unexpected JSON node type %d (%s) at \"%s\"", node->GetType(), MJsonNode::TypeToString(node->GetType()), path);
682 return DB_FILE_ERROR;
683 }
684 // NOT REACHED
685}
686
688{
689 std::string path = db_get_path(hDB, hKeyRoot);
690
691 //printf("db_paste_json: handle %d, path [%s]\n", hKeyRoot, path.c_str());
692
693 MJsonNode* node = MJsonNode::Parse(buffer);
694 int status = paste_node(hDB, hKeyRoot, path.c_str(), false, 0, node, 0, 0, NULL);
695 delete node;
696
697 return status;
698}
699
701{
702 int status;
703 KEY key;
704
706 if (status != DB_SUCCESS)
707 return status;
708
709 std::string path = db_get_path(hDB, hKeyRoot);
710
711 int tid = key.type;
712 int string_length = 0;
713 bool is_array = (key.num_values > 1);
714 if (tid == TID_STRING) {
715 // do not truncate strings, only extend if necessary
716 if ((int)node->GetString().length()+1 > key.item_size)
717 string_length = node->GetString().length()+1;
718 else
720 }
721
722 status = paste_node(hDB, hKeyRoot, path.c_str(), is_array, index, node, tid, string_length, NULL);
723
724 return status;
725}
726
727/* emacs
728 * Local Variables:
729 * tab-width: 8
730 * c-basic-offset: 3
731 * indent-tabs-mode: nil
732 * End:
733 */
#define FALSE
Definition cfortran.h:309
#define EXPRT
Definition esone.h:28
#define DB_OUT_OF_RANGE
Definition midas.h:651
#define DB_KEY_EXIST
Definition midas.h:641
#define DB_FILE_ERROR
Definition midas.h:647
#define DB_NO_ACCESS
Definition midas.h:648
#define DB_SUCCESS
Definition midas.h:631
unsigned short int WORD
Definition mcstd.h:49
unsigned char BYTE
Definition mcstd.h:48
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TID_DOUBLE
Definition midas.h:343
#define TID_SBYTE
Definition midas.h:329
#define TID_KEY
Definition midas.h:349
#define TID_BOOL
Definition midas.h:340
#define TID_SHORT
Definition midas.h:334
#define TID_UINT64
Definition midas.h:352
#define TID_INT64
Definition midas.h:351
#define TID_WORD
Definition midas.h:332
#define TID_BYTE
Definition midas.h:327
#define TID_STRUCT
Definition midas.h:348
#define TID_LINK
Definition midas.h:350
#define TID_BITFIELD
Definition midas.h:345
#define TID_STRING
Definition midas.h:346
#define MERROR
Definition midas.h:559
#define TID_ARRAY
Definition midas.h:347
#define TID_CHAR
Definition midas.h:331
#define TID_INT
Definition midas.h:338
#define TID_FLOAT
Definition midas.h:341
#define TID_DWORD
Definition midas.h:336
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4274
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:4990
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3308
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7648
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7215
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)
Definition odb.cxx:14025
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:7502
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)
HNDLE hKey
DWORD n[4]
Definition mana.cxx:247
INT index
Definition mana.cxx:271
void * data
Definition mana.cxx:268
HNDLE hDB
main ODB handle
Definition mana.cxx:207
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
HNDLE hSubkey
Definition mdump.cxx:35
#define DWORD
Definition mhdump.cxx:31
INT HNDLE
Definition midas.h:132
DWORD BOOL
Definition midas.h:105
int INT
Definition midas.h:129
unsigned long long UINT64
Definition midas.h:142
long long INT64
Definition midas.h:143
#define TRUE
Definition midas.h:182
#define NAME_LENGTH
Definition midas.h:272
#define read(n, a, f)
#define name(x)
Definition midas_macro.h:24
static FILE * fp
double value[100]
Definition odbhist.cxx:42
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Definition midas.h:1026
INT num_values
Definition midas.h:1028
DWORD type
Definition midas.h:1027
INT item_size
Definition midas.h:1032