Line data Source code
1 : //
2 : // ALPHA ROOT analyzer
3 : //
4 : // Access to ODB stored in XML odb save file or ODB XML dump in MIDAS data file.
5 : //
6 : // Name: mxmlodb.cxx
7 : // Author: K.Olchanski, 11-July-2006
8 : // Author: K.Olchanski, 16-May-2019
9 : //
10 :
11 : #include <stdio.h>
12 : #include <assert.h>
13 : #include <stdlib.h>
14 : #include <string.h> // memset()
15 :
16 : #include "mvodb.h"
17 : #include "mxml.h"
18 :
19 0 : static std::string toString(int i)
20 : {
21 : char buf[256];
22 0 : snprintf(buf, sizeof(buf), "%d", i);
23 0 : return buf;
24 : }
25 :
26 0 : static PMXML_NODE FindNode(PMXML_NODE dir, const char* name)
27 : {
28 0 : for (int i=0; i<dir->n_children; i++) {
29 0 : PMXML_NODE node = dir->child + i;
30 : //printf("node name: \"%s\"\n",node->GetNodeName());
31 0 : if (strcmp(node->name, name) == 0)
32 0 : return node;
33 :
34 0 : if (node->n_children > 0) {
35 0 : PMXML_NODE found = FindNode(node, name);
36 0 : if (found)
37 0 : return found;
38 : }
39 : }
40 :
41 0 : return NULL;
42 : }
43 :
44 : /// Return the name of the indexed attribute
45 0 : static const char* GetAttrName(PMXML_NODE node, int i)
46 : {
47 0 : assert(i>=0);
48 0 : assert(i<node->n_attributes);
49 0 : return node->attribute_name + i*MXML_NAME_LENGTH;
50 : }
51 :
52 : /// Return the value of the indexed attribute
53 0 : static const char* GetAttrValue(PMXML_NODE node, int i)
54 : {
55 0 : assert(i>=0);
56 0 : assert(i<node->n_attributes);
57 0 : return node->attribute_value[i];
58 : }
59 :
60 : /// Return the value of the named attribute
61 0 : static const char* GetAttr(PMXML_NODE node, const char* attrName)
62 : {
63 0 : for (int i=0; i<node->n_attributes; i++) {
64 : //printf("attribute name: \"%s\", value: \"%s\"\n",attr->GetName(),attr->GetValue());
65 :
66 0 : if (strcmp(GetAttrName(node, i), attrName) == 0)
67 0 : return GetAttrValue(node, i);
68 : }
69 0 : return NULL;
70 : }
71 :
72 : #if 0
73 : /// Print out the contents of the ODB tree
74 : static void DumpTree(PMXML_NODE node, int level = 0)
75 : {
76 : assert(node);
77 :
78 : for (int k=0; k<level; k++)
79 : printf(" ");
80 : printf("node name: \"%s\"\n", node->name);
81 : for (int i=0; i<node->n_attributes; i++) {
82 : for (int k=0; k<level; k++)
83 : printf(" ");
84 : printf("attribute name: \"%s\", value: \"%s\"\n", GetAttrName(node, i), GetAttrValue(node, i));
85 : }
86 : if (node->value) {
87 : for (int k=0; k<level; k++)
88 : printf(" ");
89 : printf("node text: \"%s\"\n", node->value);
90 : }
91 : for (int i=0; i<node->n_children; i++)
92 : DumpTree(node->child + i, level + 1);
93 : }
94 :
95 : /// Print out the directory structure of the ODB tree
96 : static void DumpDirTree(PMXML_NODE node, int level = 0)
97 : {
98 : assert(node);
99 :
100 : const char* name = node->name;
101 :
102 : if (strcmp(name,"dir") != 0)
103 : return;
104 :
105 : for (int k=0; k<level; k++)
106 : printf(" ");
107 : printf("node name: \"%s\"\n", node->name);
108 :
109 : for (int i=0; i<node->n_attributes; i++) {
110 : for (int k=0; k<level; k++)
111 : printf(" ");
112 : printf("attribute name: \"%s\", value: \"%s\"\n", GetAttrName(node, i), GetAttrValue(node, i));
113 : }
114 :
115 : for (int i=0; i<node->n_children; i++) {
116 : DumpDirTree(node->child + i, level + 1);
117 : }
118 : }
119 : #endif
120 :
121 : template <typename T>
122 : static T GetXmlValue(const char* text);
123 :
124 : template<>
125 0 : int GetXmlValue<int>(const char* text)
126 : {
127 0 : return atoi(text);
128 : }
129 :
130 : template<>
131 0 : double GetXmlValue<double>(const char* text)
132 : {
133 0 : return atof(text);
134 : }
135 :
136 : template<>
137 0 : float GetXmlValue<float>(const char* text)
138 : {
139 0 : return atof(text);
140 : }
141 :
142 : template<>
143 0 : bool GetXmlValue<bool>(const char* text)
144 : {
145 0 : if (*text == 'n')
146 0 : return false;
147 : else
148 0 : return true;
149 : }
150 :
151 : template<>
152 0 : uint16_t GetXmlValue<uint16_t>(const char* text)
153 : {
154 0 : return 0xFFFF & strtoul(text, NULL, 0);
155 : }
156 :
157 : template<>
158 0 : uint32_t GetXmlValue<uint32_t>(const char* text)
159 : {
160 0 : return strtoul(text, NULL, 0);
161 : }
162 :
163 : template<>
164 0 : std::string GetXmlValue<std::string>(const char* text)
165 : {
166 0 : return text;
167 : }
168 :
169 : /// Access to ODB saved in XML format inside midas .mid files
170 :
171 : class XmlOdb : public MVOdb
172 : {
173 : public:
174 : PMXML_NODE fRoot; // root of XML document
175 : PMXML_NODE fDir; // current ODB directory
176 : std::string fPath; // path to correct ODB directory
177 : bool fPrintError;
178 :
179 : public:
180 0 : XmlOdb(PMXML_NODE root, PMXML_NODE dir, MVOdbError* error) // ctor
181 0 : {
182 0 : fPrintError = false;
183 0 : fRoot = root;
184 0 : fDir = dir;
185 0 : fPath = "";
186 :
187 : //DumpTree(fRoot);
188 : //DumpTree(fDir);
189 :
190 0 : SetOk(error);
191 0 : }
192 :
193 0 : ~XmlOdb() // dtor
194 0 : {
195 0 : if (fRoot) {
196 0 : mxml_free_tree(fRoot);
197 0 : fRoot = NULL;
198 : }
199 0 : fDir = NULL;
200 0 : }
201 :
202 : public:
203 0 : void SetPrintError(bool v)
204 : {
205 0 : fPrintError = true;
206 0 : }
207 :
208 0 : bool GetPrintError() const
209 : {
210 0 : return fPrintError;
211 : }
212 :
213 0 : void SetNotFound(MVOdbError* error, const char* varname)
214 : {
215 0 : std::string path;
216 0 : path += fPath;
217 0 : path += "/";
218 0 : path += varname;
219 0 : std::string msg;
220 0 : msg += "Cannot find ";
221 0 : msg += "\"";
222 0 : msg += path;
223 0 : msg += "\"";
224 0 : SetError(error, fPrintError, path, msg);
225 0 : }
226 :
227 0 : void SetNullValue(MVOdbError* error, const char* varname)
228 : {
229 0 : std::string path;
230 0 : path += fPath;
231 0 : path += "/";
232 0 : path += varname;
233 0 : std::string msg;
234 0 : msg += "XML node for ";
235 0 : msg += "\"";
236 0 : msg += path;
237 0 : msg += "\"";
238 0 : msg += " is NULL";
239 0 : SetError(error, fPrintError, path, msg);
240 0 : }
241 :
242 0 : bool IsReadOnly() const
243 : {
244 0 : return true;
245 : }
246 :
247 : /// Follow the ODB path through the XML DOM tree
248 0 : static PMXML_NODE FindPath(PMXML_NODE dir, const char* path)
249 : {
250 0 : assert(dir);
251 :
252 : while (1) {
253 : // skip leading slashes
254 0 : while (*path == '/')
255 0 : path++;
256 :
257 0 : if (*path == 0)
258 0 : return dir;
259 :
260 0 : std::string elem;
261 :
262 : // copy the next path element into "elem"-
263 : // copy "path" until we hit "/" or end of string
264 : while (1) {
265 0 : if (*path==0 || *path=='/')
266 : break;
267 0 : elem += *path++;
268 : }
269 :
270 : //printf("looking for \"%s\" more \"%s\"\n", elem.c_str(), path);
271 :
272 0 : PMXML_NODE found = NULL;
273 :
274 0 : for (int i=0; i<dir->n_children; i++) {
275 0 : PMXML_NODE node = dir->child + i;
276 :
277 0 : const char* nodename = node->name;
278 0 : const char* namevalue = GetAttr(node, "name");
279 :
280 : //printf("node name: \"%s\", \"name\" value: \"%s\"\n", node->name, namevalue);
281 :
282 0 : bool isDir = strcmp(nodename, "dir") == 0;
283 0 : bool isKey = strcmp(nodename, "key") == 0;
284 0 : bool isKeyArray = strcmp(nodename, "keyarray") == 0;
285 :
286 0 : if (!isKey && !isDir && !isKeyArray)
287 0 : continue;
288 :
289 : //
290 : // compare directory names
291 : //
292 :
293 0 : if (strcasecmp(elem.c_str(), namevalue) == 0) {
294 0 : if (isDir) {
295 : // found the right subdirectory, descend into it
296 0 : found = node;
297 0 : break;
298 0 : } else if (isKey || isKeyArray) {
299 0 : return node;
300 : }
301 : }
302 : }
303 :
304 0 : if (!found)
305 0 : return NULL;
306 0 : dir = found;
307 0 : }
308 : }
309 :
310 0 : MVOdb* Chdir(const char* subdir, bool create, MVOdbError* error)
311 : {
312 0 : PMXML_NODE node = FindPath(fDir, subdir);
313 0 : if (!node) {
314 0 : SetNotFound(error, subdir);
315 0 : if (create) {
316 0 : return MakeNullOdb();
317 : } else {
318 0 : return NULL;
319 : }
320 : }
321 :
322 0 : if (strcmp(node->name, "dir") != 0) {
323 0 : std::string msg;
324 0 : msg += "\"";
325 0 : msg += subdir;
326 0 : msg += "\"";
327 0 : msg += " XML node is ";
328 0 : msg += "\"";
329 0 : msg += node->name;
330 0 : msg += "\"";
331 0 : msg += " instead of \"dir\"";
332 0 : SetError(error, fPrintError, fPath, msg);
333 0 : if (create)
334 0 : return MakeNullOdb();
335 : else
336 0 : return NULL;
337 0 : }
338 :
339 : //printf("Found subdir [%s]\n", subdir);
340 : //DumpTree(node);
341 :
342 0 : XmlOdb* x = new XmlOdb(NULL, node, error);
343 0 : x->fPath = fPath + "/" + subdir;
344 :
345 0 : SetOk(error);
346 0 : return x;
347 : }
348 :
349 0 : void ReadKey(const char* varname, int *tid, int *num_values, int *total_size, int *item_size, MVOdbError* error)
350 : {
351 0 : if (tid) *tid = 0;
352 0 : if (num_values) *num_values = 0;
353 0 : if (total_size) *total_size = 0;
354 0 : if (item_size) *item_size = 0;
355 : // FIXME: not implemented
356 0 : SetOk(error);
357 0 : }
358 :
359 0 : void ReadKeyLastWritten(const char* varname, int *last_written, MVOdbError* error)
360 : {
361 0 : if (last_written) *last_written = 0;
362 : // FIXME: not implemented
363 0 : SetOk(error);
364 0 : }
365 :
366 0 : void ReadDir(std::vector<std::string>* varname, std::vector<int> *tid, std::vector<int> *num_values, std::vector<int> *total_size, std::vector<int> *item_size, MVOdbError* error)
367 : {
368 : // FIXME: not implemented
369 0 : SetOk(error);
370 0 : }
371 :
372 0 : void RB(const char* varname, bool *value, bool create, MVOdbError* error)
373 : {
374 0 : RBAI(varname, 0, value, error);
375 0 : };
376 :
377 0 : void RI(const char* varname, int *value, bool create, MVOdbError* error)
378 : {
379 0 : RIAI(varname, 0, value, error);
380 0 : };
381 :
382 0 : void RD(const char* varname, double *value, bool create, MVOdbError* error)
383 : {
384 0 : RDAI(varname, 0, value, error);
385 0 : };
386 :
387 0 : void RF(const char* varname, float *value, bool create, MVOdbError* error)
388 : {
389 0 : RFAI(varname, 0, value, error);
390 0 : };
391 :
392 0 : void RS(const char* varname, std::string *value, bool create, int create_string_length, MVOdbError* error)
393 : {
394 0 : RSAI(varname, 0, value, error);
395 0 : };
396 :
397 0 : void RU16(const char* varname, uint16_t *value, bool create, MVOdbError* error)
398 : {
399 0 : RU16AI(varname, 0, value, error);
400 0 : };
401 :
402 0 : void RU32(const char* varname, uint32_t *value, bool create, MVOdbError* error)
403 : {
404 0 : RU32AI(varname, 0, value, error);
405 0 : };
406 :
407 0 : PMXML_NODE FindXmlNode(PMXML_NODE dir, const char* varname, const char* type1, const char* type2, MVOdbError* error)
408 : {
409 0 : PMXML_NODE node = FindPath(dir, varname);
410 0 : if (!node) {
411 0 : SetNotFound(error, varname);
412 0 : return NULL;
413 : }
414 :
415 0 : const char* attr_type = GetAttr(node, "type");
416 :
417 0 : if (!attr_type) {
418 0 : fprintf(stderr, "XmlOdb::FindXmlNode: Error: no type attribute in varname \"%s\"!\n", varname);
419 0 : SetNullValue(error, varname);
420 0 : return NULL;
421 : }
422 :
423 0 : if (strcmp(attr_type, type1) != 0) {
424 0 : if (strcmp(attr_type, type2) != 0) {
425 0 : fprintf(stderr, "XmlOdb::FindXmlNode: Error: type mismatch, wanted \"%s\" or \"%s\", got \"%s\"!\n", type1, type2, attr_type);
426 0 : SetNullValue(error, varname);
427 0 : return NULL;
428 : }
429 : }
430 :
431 0 : return node;
432 : }
433 :
434 : template <typename T>
435 0 : void RXA(const char* varname, const char* type1, const char* type2, std::vector<T> *value, MVOdbError* error)
436 : {
437 0 : if (!value) {
438 0 : SetOk(error);
439 0 : return;
440 : }
441 :
442 0 : PMXML_NODE node = FindXmlNode(fDir, varname, type1, type2, error);
443 0 : if (!node)
444 0 : return;
445 :
446 : //DumpTree(node);
447 :
448 0 : if (strcmp(node->name, "keyarray") == 0) {
449 0 : const char* num_values_text = GetAttr(node, "num_values");
450 0 : if (!num_values_text) {
451 0 : fprintf(stderr, "no num_values!\n");
452 0 : SetNullValue(error, varname);
453 0 : return;
454 : }
455 :
456 0 : int num_values = atoi(num_values_text);
457 :
458 0 : if (num_values != node->n_children) {
459 0 : fprintf(stderr, "num_values mismatch %d vs %d children!\n", num_values, node->n_children);
460 0 : SetNullValue(error, varname);
461 0 : return;
462 : }
463 :
464 0 : value->clear();
465 :
466 0 : for (int i=0; i<node->n_children; i++) {
467 0 : PMXML_NODE elem = node->child+i;
468 0 : const char* text = elem->value;
469 0 : if (!text) {
470 0 : SetNullValue(error, varname);
471 0 : return;
472 : }
473 0 : T v = GetXmlValue<T>(text);
474 0 : value->push_back(v);
475 : }
476 :
477 0 : SetOk(error);
478 0 : return;
479 0 : } else if (strcmp(node->name, "key") == 0) {
480 0 : const char* text = node->value;
481 0 : if (!text) {
482 0 : SetNullValue(error, varname);
483 0 : return;
484 : }
485 0 : value->clear();
486 0 : T v = GetXmlValue<T>(text);
487 0 : value->push_back(v);
488 0 : SetOk(error);
489 0 : return;
490 0 : } else {
491 0 : fprintf(stderr, "unexpected node %s\n", node->name);
492 0 : SetNullValue(error, varname);
493 0 : return;
494 : }
495 : };
496 :
497 0 : void RBA(const char* varname, std::vector<bool> *value, bool create, int create_size, MVOdbError* error)
498 : {
499 0 : RXA(varname, "BOOL", "BOOL", value, error);
500 0 : }
501 :
502 0 : void RIA(const char* varname, std::vector<int> *value, bool create, int create_size, MVOdbError* error)
503 : {
504 0 : RXA(varname, "INT", "INT32", value, error);
505 0 : }
506 :
507 0 : void RDA(const char* varname, std::vector<double> *value, bool create, int create_size, MVOdbError* error)
508 : {
509 0 : RXA(varname, "DOUBLE", "DOUBLE", value, error);
510 0 : }
511 :
512 0 : void RFA(const char* varname, std::vector<float> *value, bool create, int create_size, MVOdbError* error)
513 : {
514 0 : RXA(varname, "FLOAT", "FLOAT", value, error);
515 0 : }
516 :
517 0 : void RSA(const char* varname, std::vector<std::string> *value, bool create, int create_size, int create_string_length, MVOdbError* error)
518 : {
519 0 : RXA(varname, "STRING", "STIRNG", value, error);
520 0 : }
521 :
522 0 : void RU16A(const char* varname, std::vector<uint16_t> *value, bool create, int create_size, MVOdbError* error)
523 : {
524 0 : RXA(varname, "WORD", "UINT16", value, error);
525 0 : }
526 :
527 0 : void RU32A(const char* varname, std::vector<uint32_t> *value, bool create, int create_size, MVOdbError* error)
528 : {
529 0 : RXA(varname, "DWORD", "UINT32", value, error);
530 0 : }
531 :
532 : template <typename T>
533 0 : void RXAI(const char* varname, int index, const char* type1, const char* type2, T* value, MVOdbError* error)
534 : {
535 0 : if (!value) {
536 0 : SetOk(error);
537 0 : return;
538 : }
539 :
540 0 : PMXML_NODE node = FindXmlNode(fDir, varname, type1, type2, error);
541 0 : if (!node)
542 0 : return;
543 :
544 : //DumpTree(node);
545 :
546 0 : if (strcmp(node->name, "keyarray") == 0) {
547 0 : const char* num_values_text = GetAttr(node, "num_values");
548 0 : if (!num_values_text) {
549 0 : fprintf(stderr, "no num_values!\n");
550 0 : SetNullValue(error, varname);
551 0 : return;
552 : }
553 :
554 0 : int num_values = atoi(num_values_text);
555 :
556 0 : if (num_values != node->n_children) {
557 0 : fprintf(stderr, "num_values mismatch %d vs %d children!\n", num_values, node->n_children);
558 0 : SetNullValue(error, varname);
559 0 : return;
560 : }
561 :
562 0 : if (index < 0) {
563 0 : fprintf(stderr, "bad index %d, num_values %d!\n", index, num_values);
564 0 : SetNullValue(error, varname);
565 0 : return;
566 : }
567 :
568 0 : if (index >= num_values) {
569 0 : fprintf(stderr, "bad index %d, num_values %d!\n", index, num_values);
570 0 : SetNullValue(error, varname);
571 0 : return;
572 : }
573 :
574 0 : PMXML_NODE elem = node->child+index;
575 0 : const char* text = elem->value;
576 0 : if (!text) {
577 0 : SetNullValue(error, varname);
578 0 : return;
579 : }
580 :
581 0 : *value = GetXmlValue<T>(text);
582 :
583 0 : SetOk(error);
584 0 : return;
585 0 : } else if (strcmp(node->name, "key") == 0) {
586 :
587 0 : if (index != 0) {
588 0 : fprintf(stderr, "non-zero index %d for non-array!\n", index);
589 0 : SetNullValue(error, varname);
590 0 : return;
591 : }
592 :
593 0 : const char* text = node->value;
594 0 : if (!text) {
595 0 : SetNullValue(error, varname);
596 0 : return;
597 : }
598 :
599 0 : *value = GetXmlValue<T>(text);
600 :
601 0 : SetOk(error);
602 0 : return;
603 : } else {
604 0 : fprintf(stderr, "unexpected node %s\n", node->name);
605 0 : SetNullValue(error, varname);
606 0 : return;
607 : }
608 : }
609 :
610 0 : void RBAI(const char* varname, int index, bool *value, MVOdbError* error)
611 : {
612 0 : RXAI(varname, index, "BOOL", "BOOL", value, error);
613 0 : }
614 :
615 0 : void RIAI(const char* varname, int index, int *value, MVOdbError* error)
616 : {
617 0 : RXAI(varname, index, "INT", "INT32", value, error);
618 0 : }
619 :
620 0 : void RDAI(const char* varname, int index, double *value, MVOdbError* error)
621 : {
622 0 : RXAI(varname, index, "DOUBLE", "DOUBLE", value, error);
623 0 : }
624 :
625 0 : void RFAI(const char* varname, int index, float *value, MVOdbError* error)
626 : {
627 0 : RXAI(varname, index, "FLOAT", "FLOAT", value, error);
628 0 : }
629 :
630 0 : void RSAI(const char* varname, int index, std::string *value, MVOdbError* error)
631 : {
632 0 : RXAI(varname, index, "STRING", "STRING", value, error);
633 0 : }
634 :
635 0 : void RU16AI(const char* varname, int index, uint16_t *value, MVOdbError* error)
636 : {
637 0 : RXAI(varname, index, "WORD", "UINT16", value, error);
638 0 : }
639 :
640 0 : void RU32AI(const char* varname, int index, uint32_t *value, MVOdbError* error)
641 : {
642 0 : RXAI(varname, index, "DWORD", "UINT32", value, error);
643 0 : }
644 :
645 : // write functions do nothing
646 :
647 0 : void WB(const char* varname, bool v, MVOdbError* error) { SetOk(error); };
648 0 : void WI(const char* varname, int v, MVOdbError* error) { SetOk(error); };
649 0 : void WD(const char* varname, double v, MVOdbError* error) { SetOk(error); };
650 0 : void WF(const char* varname, float v, MVOdbError* error) { SetOk(error); };
651 0 : void WS(const char* varname, const char* v, int string_length, MVOdbError* error) { SetOk(error); };
652 0 : void WU16(const char* varname, uint16_t v, MVOdbError* error) { SetOk(error); };
653 0 : void WU32(const char* varname, uint32_t v, MVOdbError* error) { SetOk(error); };
654 :
655 0 : void WBA(const char* varname, const std::vector<bool>& v, MVOdbError* error) { SetOk(error); };
656 0 : void WIA(const char* varname, const std::vector<int>& v, MVOdbError* error) { SetOk(error); };
657 0 : void WDA(const char* varname, const std::vector<double>& v, MVOdbError* error) { SetOk(error); };
658 0 : void WFA(const char* varname, const std::vector<float>& v, MVOdbError* error) { SetOk(error); };
659 0 : void WSA(const char* varname, const std::vector<std::string>& data, int odb_string_length, MVOdbError* error) { SetOk(error); };
660 0 : void WU16A(const char* varname, const std::vector<uint16_t>& v, MVOdbError* error) { SetOk(error); };
661 0 : void WU32A(const char* varname, const std::vector<uint32_t>& v, MVOdbError* error) { SetOk(error); };
662 :
663 0 : void WBAI(const char* varname, int index, bool v, MVOdbError* error) { SetOk(error); };
664 0 : void WIAI(const char* varname, int index, int v, MVOdbError* error) { SetOk(error); };
665 0 : void WDAI(const char* varname, int index, double v, MVOdbError* error) { SetOk(error); };
666 0 : void WFAI(const char* varname, int index, float v, MVOdbError* error) { SetOk(error); };
667 0 : void WSAI(const char* varname, int index, const char* v, MVOdbError* error) { SetOk(error); };
668 0 : void WU16AI(const char* varname, int index, uint16_t v, MVOdbError* error) { SetOk(error); };
669 0 : void WU32AI(const char* varname, int index, uint32_t v, MVOdbError* error) { SetOk(error); };
670 :
671 : // delete function does nothing
672 :
673 0 : void Delete(const char* odbname, MVOdbError* error) { SetOk(error); };
674 : };
675 :
676 : #if 0
677 : int XmlOdb::odbReadArraySize(const char*name)
678 : {
679 : PMXML_NODE node = FindPath(NULL, name);
680 : if (!node)
681 : return 0;
682 : const char* num_values = GetAttr(node, "num_values");
683 : if (!num_values)
684 : return 1;
685 : return atoi(num_values);
686 : }
687 : #endif
688 :
689 0 : MVOdb* MakeXmlFileOdb(const char* filename, MVOdbError* error)
690 : {
691 : char err[256];
692 0 : int err_line = 0;
693 0 : PMXML_NODE node = mxml_parse_file(filename, err, sizeof(err), &err_line);
694 0 : if (!node) {
695 0 : std::string msg;
696 0 : msg += "mxml_parse_file() error ";
697 0 : msg += "\"";
698 0 : msg += err;
699 0 : msg += "\"";
700 0 : msg += " file ";
701 0 : msg += filename;
702 0 : msg += " line ";
703 0 : msg += toString(err_line);
704 0 : SetError(error, true, filename, msg);
705 0 : return MakeNullOdb();
706 0 : }
707 :
708 0 : PMXML_NODE odb_node = FindNode(node, "odb");
709 :
710 0 : if (!odb_node) {
711 0 : std::string msg;
712 0 : msg += "invalid XML tree: no ODB tag";
713 0 : SetError(error, true, filename, msg);
714 0 : return MakeNullOdb();
715 0 : }
716 :
717 0 : return new XmlOdb(node, odb_node, error);
718 : }
719 :
720 0 : MVOdb* MakeXmlBufferOdb(const char* buf, int bufsize, MVOdbError* error)
721 : {
722 : #if 0
723 : // note: this code was in the old XmlOdb.cxx file
724 : // probably needed to clean up strange characters
725 : // that upset the ROOT/libxml XML parser. Stefan's mxml
726 : // XML parser probably does not need it, but if we see
727 : // reports of XML parser failure where the old XmlOdb
728 : // used to work, then we should put this code back. K.O.
729 :
730 : char*buf = (char*)malloc(bufLength);
731 : memcpy(buf, xbuf, bufLength);
732 : for (int i=0; i<bufLength; i++)
733 : if (!isascii(buf[i])) {
734 : buf[i] = 'X';
735 : } else if (buf[i]=='\n') {
736 : } else if (buf[i]=='\r') {
737 : } else if (!isprint(buf[i])) {
738 : buf[i] = 'X';
739 : } else if (buf[i] == 0x1D) {
740 : buf[i] = 'X';
741 : }
742 :
743 : char* xend = strstr(buf,"odb>");
744 : if (xend)
745 : xend[4] = 0;
746 : #endif
747 :
748 : char err[256];
749 0 : int err_line = 0;
750 0 : PMXML_NODE node = mxml_parse_buffer(buf, err, sizeof(err), &err_line);
751 0 : if (!node) {
752 0 : std::string msg;
753 0 : msg += "mxml_parse_buffer() error ";
754 0 : msg += "\"";
755 0 : msg += err;
756 0 : msg += "\"";
757 0 : msg += " line ";
758 0 : msg += toString(err_line);
759 0 : SetError(error, true, "buffer", msg);
760 0 : return MakeNullOdb();
761 0 : }
762 :
763 0 : PMXML_NODE odb_node = FindNode(node, "odb");
764 :
765 0 : if (!odb_node) {
766 0 : std::string msg;
767 0 : msg += "invalid XML tree: no ODB tag";
768 0 : SetError(error, true, "buffer", msg);
769 0 : return MakeNullOdb();
770 0 : }
771 :
772 0 : return new XmlOdb(node, odb_node, error);
773 : }
774 :
775 : /* emacs
776 : * Local Variables:
777 : * tab-width: 8
778 : * c-basic-offset: 3
779 : * indent-tabs-mode: nil
780 : * End:
781 : */
|