MIDAS
Loading...
Searching...
No Matches
odbxx.h
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: odbxx.cxx
4 Created by: Stefan Ritt
5
6 Contents: Object oriented interface to ODB
7
8 This file provides a very object-oriented approach to interacting with the
9 midas ODB. You can think of it like a "magic" map/dictionary that
10 automatically sends changes you make to the ODB, and receives updates that
11 others have made.
12
13 Documentation is at https://midas.triumf.ca/MidasWiki/index.php/Odbxx
14
15\********************************************************************/
16
17#ifndef _ODBXX_HXX
18#define _ODBXX_HXX
19
20#include <string>
21#include <iostream>
22#include <sstream>
23#include <stdexcept>
24#include <initializer_list>
25#include <cstring>
26#include <bitset>
27#include <functional>
28#include <fstream>
29
30#include "midas.h"
31#include "mexcept.h"
32#include "mxml.h"
33#include "mjson.h"
34// #include "mleak.h" // un-comment for memory leak debugging
35
36
37/*------------------------------------------------------------------*/
38
39namespace midas {
40
41 class odb;
42
43 //================================================================
44 // u_odb class is a union to hold one ODB value, either a basic
45 // type, a std::string or a pointer to an odb object
46 //================================================================
47
48 class u_odb {
49 private:
50 // union to hold data
51 union {
52 uint8_t m_uint8;
53 int8_t m_int8;
54 uint16_t m_uint16;
55 int16_t m_int16;
56 uint32_t m_uint32;
57 int32_t m_int32;
58 uint64_t m_uint64;
59 int64_t m_int64;
60 bool m_bool;
61 float m_float;
62 double m_double;
63 std::string *m_string;
65 };
66
67 int m_tid;
69
70 public:
71 u_odb() : m_string{}, m_tid{}, m_parent_odb{nullptr} {};
72
73 // for shorter values, first set m_string to nullptr to initialize higher bytes to zero
74 u_odb(uint8_t v) : m_tid{TID_UINT8}, m_parent_odb{nullptr} {m_string = nullptr; m_uint8 = v;};
75
76 u_odb(int8_t v) : m_tid{TID_INT8}, m_parent_odb{nullptr} {m_string = nullptr; m_int8 = v;};
77
78 u_odb(uint16_t v) : m_tid{TID_UINT16}, m_parent_odb{nullptr} {m_string = nullptr; m_uint16 = v;};
79
80 u_odb(int16_t v) : m_tid{TID_INT16}, m_parent_odb{nullptr} {m_string = nullptr; m_int16 = v;};
81
82 u_odb(uint32_t v) : m_tid{TID_UINT32}, m_parent_odb{nullptr} {m_string = nullptr; m_uint32 = v;};
83
84 u_odb(int32_t v) : m_tid{TID_INT32}, m_parent_odb{nullptr} {m_string = nullptr; m_int32 = v;};
85
86 u_odb(uint64_t v) : m_tid{TID_UINT64}, m_parent_odb{nullptr} {m_string = nullptr; m_uint64 = v;};
87
88 u_odb(int64_t v) : m_tid{TID_INT64}, m_parent_odb{nullptr} {m_string = nullptr; m_int64 = v;};
89
90 u_odb(bool v) : m_tid{TID_BOOL}, m_parent_odb{nullptr} {m_string = nullptr; m_bool = v;};
91
92 u_odb(float v) : m_float{v}, m_tid{TID_FLOAT}, m_parent_odb{nullptr} {m_string = nullptr; m_float = v;};
93
94 u_odb(double v) : m_double{v}, m_tid{TID_DOUBLE}, m_parent_odb{nullptr} {m_string = nullptr; m_double = v;};
95
96 u_odb(std::string *v) : m_string{v}, m_tid{TID_STRING}, m_parent_odb{nullptr} {};
97
98 // Destructor
99 ~u_odb();
100
101 // Setters and getters
102 void set_parent(odb *o) { m_parent_odb = o; }
104
105 void set_tid(int tid) { m_tid = tid; }
106
107 int get_tid() { return m_tid; }
108
109 // Overload the Assignment Operators
110 uint8_t operator=(uint8_t v);
111 int8_t operator=(int8_t v);
112 uint16_t operator=(uint16_t v);
113 int16_t operator=(int16_t v);
114 uint32_t operator=(uint32_t v);
115 int32_t operator=(int32_t v);
116 uint64_t operator=(uint64_t v);
117 int64_t operator=(int64_t v);
118 bool operator=(bool v);
119 float operator=(float v);
120 double operator=(double v);
121 const char *operator=(const char *v);
122 std::string *operator=(std::string * v);
123 std::string operator=(std::string v);
124
125 // Overload the Conversion Operators
126 operator uint8_t();
127 operator int8_t();
128 operator uint16_t();
129 operator int16_t();
130 operator uint32_t();
131 operator int32_t();
132 operator uint64_t();
133 operator int64_t();
134 operator bool();
135 operator float();
136 operator double();
137 operator std::string();
138 operator const char *();
139 operator midas::odb &();
140
141 template<typename T>
142 void set(T v) {
143 if (m_tid == TID_UINT8)
144 m_uint8 = v;
145 else if (m_tid == TID_INT8)
146 m_int8 = v;
147 else if (m_tid == TID_UINT16)
148 m_uint16 = v;
149 else if (m_tid == TID_INT16)
150 m_int16 = v;
151 else if (m_tid == TID_UINT32)
152 m_uint32 = v;
153 else if (m_tid == TID_INT32)
154 m_int32 = v;
155 else if (m_tid == TID_UINT64)
156 m_uint64 = v;
157 else if (m_tid == TID_INT64)
158 m_int64 = v;
159 else if (m_tid == TID_BOOL)
160 m_bool = v;
161 else if (m_tid == TID_FLOAT)
162 m_float = v;
163 else if (m_tid == TID_DOUBLE)
164 m_double = v;
165 else if (m_tid == TID_STRING) {
166 delete m_string;
167 m_string = new std::string(std::to_string(v));
168 } else
169 mthrow("Invalid type ID " + std::to_string(m_tid));
170 }
171
172 void set_string(std::string s) {
173 delete m_string;
174 m_string = new std::string(s);
175 }
176
177 void set_string_size(std::string s, int size);
178
179 void set_string_ptr(std::string *s) {
180 m_string = s;
181 }
182
183 void set(odb *v) {
184 if (m_tid != TID_KEY)
185 mthrow("Subkey can only be assigned to ODB key");
186 m_odb = v;
187 }
188
189 void set_odb(odb *v) {
190 if (m_tid != TID_KEY)
191 mthrow("Subkey can only be assigned to ODB key");
192 m_odb = v;
193 }
194
195 void set(std::string v) {
196 if (m_tid == TID_UINT8)
197 m_uint8 = std::stoi(v, nullptr, 0); // stoi convertx 0x automatically
198 else if (m_tid == TID_INT8)
199 m_int8 = std::stoi(v, nullptr, 0);
200 else if (m_tid == TID_UINT16)
201 m_uint16 = std::stoi(v, nullptr, 0);
202 else if (m_tid == TID_INT16)
203 m_int16 = std::stoi(v, nullptr, 0);
204 else if (m_tid == TID_UINT32)
205 m_uint32 = std::stoul(v, nullptr, 0);
206 else if (m_tid == TID_INT32)
207 m_int32 = std::stoul(v, nullptr, 0);
208 else if (m_tid == TID_UINT64)
209 m_uint64 = std::stoul(v, nullptr, 0);
210 else if (m_tid == TID_INT64)
211 m_int64 = std::stoul(v, nullptr, 0);
212 else if (m_tid == TID_BOOL)
213 m_bool = std::stoi(v, nullptr, 0);
214 else if (m_tid == TID_FLOAT)
215 m_float = std::stod(v);
216 else if (m_tid == TID_DOUBLE)
217 m_double = std::stod(v);
218 else if (m_tid == TID_STRING) {
219 delete m_string;
220 m_string = new std::string(v);
221 } else if (m_tid == TID_LINK) {
222 delete m_string;
223 m_string = new std::string(v);
224 } else
225 mthrow("Invalid type ID " + std::to_string(m_tid));
226 }
227
228 void set(const char *v) {
229 set(std::string(v));
230 }
231
232 void set(char *v) {
233 set(std::string(v));
234 }
235
236
237 void add(double inc, bool push = true);
238
239 void mult(double f, bool push = true);
240
241 // overload arithmetic operators
243 add(1);
244 return *this;
245 }
246
248 add(1);
249 return *this;
250 }
251
253 add(-1);
254 return *this;
255 }
256
258 add(-1);
259 return *this;
260 }
261
262 u_odb &operator+=(double d) {
263 add(d);
264 return *this;
265 }
266
267 u_odb &operator-=(double d) {
268 add(-d);
269 return *this;
270 }
271
272 u_odb &operator*=(double d) {
273 mult(d);
274 return *this;
275 }
276
277 u_odb &operator/=(double d) {
278 if (d == 0)
279 mthrow("Division by zero");
280 mult(1 / d);
281 return *this;
282 }
283
284 template<typename T>
286 double d = *this;
287 d += v;
288 set(v);
289 return *this;
290 }
291
292 template<typename T>
294 double d = *this;
295 d -= v;
296 set(v);
297 return *this;
298 }
299
300 template<typename T>
302 double d = *this;
303 d *= v;
304 set(v);
305 return *this;
306 }
307
308 template<typename T>
310 double d = *this;
311 d /= v;
312 set(v);
313 return *this;
314 }
315
316 // get function for basic type
317 template<typename T>
318 T get() {
319 if (m_tid == TID_UINT8)
320 return (T) m_uint8;
321 else if (m_tid == TID_INT8)
322 return (T) m_int8;
323 else if (m_tid == TID_UINT16)
324 return (T) m_uint16;
325 else if (m_tid == TID_INT16)
326 return (T) m_int16;
327 else if (m_tid == TID_UINT32)
328 return (T) m_uint32;
329 else if (m_tid == TID_INT32)
330 return (T) m_int32;
331 else if (m_tid == TID_UINT64)
332 return (T) m_uint64;
333 else if (m_tid == TID_INT64)
334 return (T) m_int64;
335 else if (m_tid == TID_BOOL)
336 return (T) m_bool;
337 else if (m_tid == TID_FLOAT)
338 return (T) m_float;
339 else if (m_tid == TID_DOUBLE)
340 return (T) m_double;
341 else if (m_tid == 0)
342 mthrow("Subkey not found");
343 else
344 mthrow("Invalid type ID " + std::to_string(m_tid));
345 }
346
347 // get function for string
348 std::string get() {
349 std::string s;
350 get(s);
351 return s;
352 }
353
354 std::string get_value() {
355 std::string s;
356 get(s);
357 return s;
358 }
359
360 // shortcut to above
361 std::string s() {
362 return get();
363 }
364
365 // get function for strings
366 void get(std::string &s);
367
368 // get_function for keys
370 if (m_tid != TID_KEY)
371 mthrow("odb_get() called for non-key object");
372 return m_odb;
373 }
374
376 if (m_tid != TID_KEY)
377 mthrow("odb_get() called for non-key object");
378 return *m_odb;
379 }
380
381 // overload stream out operator
382 friend std::ostream &operator<<(std::ostream &output, u_odb &o) {
383 std::string s = o;
384 output << s;
385 return output;
386 };
387
388 };
389
390 //-----------------------------------------------
391
392 // bit in odb::m_flags
404
405 //================================================================
406 // the odb object holds an ODB entry with name, type,
407 // hKey and array of u_odb values
408 //================================================================
409
410 class odb {
411 public:
412 // data source
418
419 class iterator {
420 public:
421 iterator(u_odb *pu) : pu_odb(pu) {}
422
423 // Pre-increment
425 ++pu_odb;
426 return *this;
427 }
428
429 // Post-increment
431 iterator ret = *this;
432 this->operator++();
433 return ret;
434 }
435
436 bool operator!=(const iterator &other) const { return pu_odb != other.pu_odb; }
437
438 u_odb &operator*() { return *pu_odb; }
439
440 private:
442 };
443
444 private:
445
446 // source of ODB, same for all instances
447 thread_local static odb_source s_odb_source;
448 thread_local static std::string s_odb_source_str; // string or filename
449 // odb object holding whole ODB for FILE and STRING sources
450 thread_local static odb *s_odb;
451 // handle to ODB, same for all instances
452 static HNDLE s_hDB;
453 // global debug flag for all instances
454 static bool s_debug;
455 // global flag indicating that we are connected to the ODB
456 static bool s_connected_odb;
457 // global list of ODB keys used by odb::watch
458 static std::vector<midas::odb> m_watch;
459
460 // various parameters defined in odb_flags
461 std::bitset<9> m_flags;
462 // type of this object, one of TID_xxx
463 int m_tid;
464 // vector containing data for this object
466 // name of ODB entry
467 std::string m_name;
468 // number of values of ODB entry
470 // last index accessed, needed for o[i] = x
472 // ODB handle for this key
474 // callback for watch funciton
475 std::function<void(midas::odb &)> m_watch_callback;
476 // parent ODB key
478
479 //-------------------------------------------------------------
480
481 // static functions
482 static void init_hdb();
483 static midas::odb *search_hkey(midas::odb *po, int hKey);
484 static void watch_callback(int hDB, int hKey, int index, void *info);
485 static void unwatch_all();
486
487 //-------------------------------------------------------------
488
489 void set_flags_recursively(uint32_t f);
490 void resize_mdata(int size);
491
492 // get function for basic types
493 template<typename T>
494 T get() {
495 if (m_num_values > 1)
496 mthrow("ODB key \"" + get_full_path() +
497 "[0..." + std::to_string(m_num_values - 1) +
498 "]\" contains array. Please assign to std::vector.");
500 read();
501 return (T) m_data[0];
502 }
503
504 // get function for basic types as a parameter
505 template<typename T>
506 void get(T &v) {
507 if (m_num_values > 1)
508 mthrow("ODB key \"" + get_full_path() + "\" contains array. Please assign to std::vector.");
510 read();
511 v = (T) m_data[0];
512 }
513
514 // get function for strings
515 void get(std::string &s, bool quotes = false, bool refresh = true);
516
517 // return internal data
518 u_odb &get_mdata(int index = 0) { return m_data[index]; }
519
520 odb &get_subkey(std::string str);
521 int get_subkeys(std::vector<std::string> &name);
522 bool read_key(const std::string &path);
523 bool write_key(std::string &path, bool write_defaults);
524
526
527 void set_flags(uint32_t f) { m_flags = f; }
528 uint32_t get_flags() { return static_cast<uint32_t>(m_flags.to_ulong()); }
529
530 bool is_deleted() const { return m_flags[odb_flags::DELETED]; }
532
533 void set_tid(int tid) { m_tid = tid; }
535
536 void set_name(std::string s) { m_name = s; }
537
540
541 public:
542
543 // Default constructor
544 odb() :
548 (1 << odb_flags::AUTO_CREATE) |
549 (1 << odb_flags::TRIGGER_HOTLINK)},
550 m_tid{0},
551 m_data{nullptr},
552 m_name{},
553 m_num_values{0},
554 m_last_index{-1},
555 m_hKey{},
556 m_parent{} {}
557
558 // Destructor
560 delete[] m_data;
561 }
562
563 // Deep copy constructor
564 odb(const odb &o);
565
566 // Delete shallow assignment operator
567 odb operator=(odb &&o) = delete;
568
569 // Constructor for single basic types
570 template<typename T>
571 odb(T v):odb() {
572 m_num_values = 1;
573 m_data = new u_odb[1]{v};
574 m_tid = m_data[0].get_tid();
575 m_data[0].set_parent(this);
576 }
577
578 // Constructor with std::initializer_list
579 odb(std::initializer_list<std::pair<const char *, midas::odb>> list) : odb() {
580 m_tid = TID_KEY;
581 m_num_values = list.size();
583 int i = 0;
584 for (auto &element: list) {
585 // check if name exists already
586 for (int j=0 ; j<i ; j++) {
587 if (strcasecmp(element.first, m_data[j].get_odb().get_name().c_str()) == 0) {
588 if (element.first == m_data[j].get_odb().get_name().c_str()) {
589 mthrow("ODB key with name \"" + m_data[j].get_odb().get_name() + "\" exists already");
590 } else {
591 mthrow("ODB key \"" + std::string(element.first) + "\" exists already as \"" +
592 m_data[j].get_odb().get_name() + "\" (only case differs)");
593 }
594 }
595 }
596 auto o = new midas::odb(element.second);
597 o->set_name(element.first);
598 o->set_parent(this);
600 m_data[i].set_parent(this);
601 m_data[i].set(o);
602 i++;
603 }
604 }
605
606 // Constructor with basic type array
607 template<typename T>
608 odb(std::initializer_list<T> list) : odb() {
609 m_num_values = list.size();
610 m_data = new u_odb[m_num_values]{};
611 int i = 0;
612 for (auto &element : list) {
613 u_odb u(element);
614 m_data[i].set_tid(u.get_tid());
615 m_data[i].set_parent(this);
617 i++;
618 }
619 m_tid = m_data[0].get_tid();
620 }
621
622 // Constructor with basic explicit array
623 template<typename T, size_t SIZE>
624 odb(const std::array<T, SIZE> &arr) : odb() {
626 m_data = new u_odb[m_num_values]{};
627 for (int i = 0; i < (int)SIZE; i++) {
628 u_odb u(arr[i]);
629 m_data[i].set_tid(u.get_tid());
630 m_data[i].set_parent(this);
631 m_data[i].set(arr[i]);
632 }
633 m_tid = m_data[0].get_tid();
634 }
635
636 // Constructor with explicit array of std::string
637 template<size_t SIZE>
638 odb(const std::array<std::string, SIZE> &arr) : odb() {
640 m_data = new u_odb[m_num_values]{};
641 for (int i = 0; i < (int)SIZE; i++) {
642 std::string * mystring = new std::string(arr[i]);
643 u_odb u(mystring);
644 m_data[i].set_tid(u.get_tid());
645 m_data[i].set_parent(this);
646 m_data[i].set(arr[i]);
647 }
648 m_tid = m_data[0].get_tid();
649 }
650
651 // Constructor for std::string
652 odb(const std::string &path, bool init_via_xml = false) : odb() {
653 if (path[0] == '/') {
654 // ODB path
655 if (s_odb_source == ONLINE) {
656 if (init_via_xml) {
657 if (!exists(path))
658 odb::create(path.c_str(), TID_KEY);
660 } else {
661 if (!read_key(path))
662 // create subdir if key does not exist
663 odb::create(path.c_str(), TID_KEY);
664
665 if (!read_key(path))
666 mthrow("ODB key \"" + path + "\" not found in ODB");
667
668 if (m_tid != TID_KEY)
669 read();
670 }
671 } else if (s_odb_source == STRING || s_odb_source == FILE) {
672
673 // split path
674 std::stringstream ss(path.substr(1));
675 std::string item;
676 std::vector<std::string> arr;
677 while (std::getline(ss, item, '/'))
678 arr.push_back(item);
679
680 // extract subkey from root odb
681 odb *o = s_odb;
682 for (size_t i = 0; i < arr.size(); i++)
683 o = &(*o)[arr[i]];
684
685 // do a deep copy from "o" to "this"
686 m_tid = o->m_tid;
687 m_tid = o->m_tid;
688 m_name = o->m_name;
690 m_hKey = o->m_hKey;
693 for (int i = 0; i < m_num_values; i++) {
695 m_data[i].set_parent(this);
696 if (m_tid == TID_STRING || m_tid == TID_LINK) {
697 // set_string() creates a copy of our string
698 m_data[i].set_string(o->m_data[i]);
699 } else if (m_tid == TID_KEY) {
700 // recursive call to create a copy of the odb object
701 auto *po= o->m_data[i].get_podb();
702 auto *pc = new midas::odb(*po);
703 pc->set_parent(this);
704 m_data[i].set(pc);
705 } else {
706 // simply pass basic types
707 m_data[i] = o->m_data[i];
708 m_data[i].set_parent(this);
709 }
710 }
711
712 } else
713 mthrow("Unknown ODB source: " + std::to_string(s_odb_source));
714
715 } else {
716 // simple string
717
718 // Construct object from initializer_list
719 m_num_values = 1;
720 m_data = new u_odb[1]{new std::string{path}};
721 m_tid = m_data[0].get_tid();
722 m_data[0].set_parent(this);
723 }
724 }
725
726 // Constructor for C string
727 odb(const char *s) : odb(std::string(s)) {
728 }
729
730 // Constructor with const char * array
731 odb(std::initializer_list<const char *> list) : odb() {
732 m_num_values = list.size();
733 m_data = new u_odb[m_num_values]{};
734 int i = 0;
735 for (auto &element : list) {
737 m_data[i].set_parent(this);
739 i++;
740 }
741 m_tid = m_data[0].get_tid();
742 }
743
744 template<typename T>
745 int detect_type(const T &) {
746 if (std::is_same<T, uint8_t>::value)
747 return TID_UINT8;
748 else if (std::is_same<T, int8_t>::value)
749 return TID_INT8;
750 else if (std::is_same<T, uint16_t>::value)
751 return TID_UINT16;
752 else if (std::is_same<T, int16_t>::value)
753 return TID_INT16;
754 else if (std::is_same<T, uint32_t>::value)
755 return TID_UINT32;
756 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
757 return TID_UINT32;
758 else if (std::is_same<T, int32_t>::value)
759 return TID_INT32;
760 else if (std::is_same<T, long>::value && sizeof(long) == 4)
761 return TID_INT32;
762 else if (std::is_same<T, uint64_t>::value)
763 return TID_UINT64;
764 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
765 return TID_UINT64;
766 else if (std::is_same<T, int64_t>::value)
767 return TID_INT64;
768 else if (std::is_same<T, long>::value && sizeof(long) == 8)
769 return TID_INT64;
770 else if (std::is_same<T, bool>::value)
771 return TID_BOOL;
772 else if (std::is_same<T, float>::value)
773 return TID_FLOAT;
774 else if (std::is_same<T, double>::value)
775 return TID_DOUBLE;
776 else
777 return TID_STRING;
778 }
779
780 // Overload the Assignment Operators
781 template<typename T>
782 const T &operator=(const T &v) {
783
784 if (this->is_write_protect())
785 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
786
787 if (m_num_values == 0) {
788 // initialize this
789 m_num_values = 1;
790 m_tid = detect_type(v);
791 m_data = new u_odb[1]{};
792 m_data[0].set_tid(m_tid);
793 m_data[0].set_parent(this);
794 m_data[0].set(v);
795 if (this->is_auto_refresh_write())
796 write();
797 } else {
798 for (int i = 0; i < m_num_values; i++)
799 m_data[i].set(v);
800
801 if (this->is_auto_refresh_write())
802 write();
803 }
804 return v;
805 }
806
807 // Overload the Assignment Operators for std::vector
808 template<typename T>
809 const std::vector<T> &operator=(const std::vector<T> &v) {
810
811 if (this->is_write_protect())
812 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
813
814 if (m_num_values == 0) {
815 // initialize this
816 m_num_values = v.size();
817 if (std::is_same<T, bool>::value) {
818 // Special logic for vector<bool>, which may not be a true
819 // container: it's often optimized to be a bitfield, with
820 // references to elements being masked bits rather than bools.
821 // So T is a bool here, but typeof(v[0]) may not be bool!
822 // "Fake container optimization" only applies to vector<bool>,
823 // not array<bool> or any other vector<T>.
824 m_tid = TID_BOOL;
825 } else {
826 // Every other type can be detected using ref to first element.
827 m_tid = detect_type(v[0]);
828 }
829
830 m_data = new u_odb[m_num_values]{};
831 for (int i = 0; i < m_num_values; i++) {
833 m_data[i].set_parent(this);
834 }
835
836 } else {
837
838 // resize internal array if different
839 if ((int)v.size() != m_num_values) {
840 resize_mdata(v.size());
841 }
842 }
843
844 for (int i = 0; i < m_num_values; i++)
845 m_data[i].set(v[i]);
846
847 if (this->is_auto_refresh_write())
848 write();
849
850 return v;
851 }
852
853 // Overload the Assignment Operators for std::array
854 template<typename T, size_t SIZE>
855 const std::array<T, SIZE> &operator=(const std::array<T, SIZE> &arr) {
856
857 if (this->is_write_protect())
858 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
859
860 if (m_num_values == 0) {
861 // initialize this
863 m_tid = detect_type(arr[0]);
864 m_data = new u_odb[m_num_values]{};
865 for (int i = 0; i < m_num_values; i++) {
867 m_data[i].set_parent(this);
868 }
869
870 } else {
871
872 // resize internal array if different
873 if (SIZE != m_num_values) {
875 }
876 }
877
878 for (int i = 0; i < m_num_values; i++)
879 m_data[i].set(arr[i]);
880
881 if (this->is_auto_refresh_write())
882 write();
883 return arr;
884 }
885
886 // overload conversion operator for std::string
887 operator std::string() {
888 std::string s;
889 if (m_tid == TID_KEY)
890 print(s, 0);
891 else
892 get(s); // forward to get(std::string)
893 return s;
894 }
895
896 // overload conversion operator for std::vector<T>
897 template<typename T>
898 operator std::vector<T>() {
900 read();
901 std::vector<T> v(m_num_values);
902 for (int i = 0; i < m_num_values; i++)
903 v[i] = m_data[i];
904 return v;
905 }
906
907 operator std::vector<std::string>() {
909 read();
910 std::vector<std::string> v(m_num_values);
911 for (int i = 0; i < m_num_values; i++)
912 v[i] = m_data[i].get();
913 return v;
914 }
915
916 // overload all other conversion operators
917 template<typename T, typename std::enable_if<
918 std::is_same<T, uint8_t>::value ||
919 std::is_same<T, int8_t>::value ||
920 std::is_same<T, uint16_t>::value ||
921 std::is_same<T, int16_t>::value ||
922 std::is_same<T, uint32_t>::value ||
923 std::is_same<T, int32_t>::value ||
924 std::is_same<T, uint64_t>::value ||
925 std::is_same<T, int64_t>::value ||
926 std::is_same<T, bool>::value ||
927 std::is_same<T, float>::value ||
928 std::is_same<T, double>::value, T>::type * = nullptr>
929 operator T() {
930 if (m_tid == 0)
931 mthrow("Element \"" + m_name + "\" not found");
932 return get<T>(); // forward to get<T>()
933 }
934
935 // overload stream out operator
936 friend std::ostream &operator<<(std::ostream &output, odb &o) {
937 std::string s;
938 if (o.m_tid == TID_KEY)
939 o.print(s, 0);
940 else
941 o.get(s);
942 output << s;
943 return output;
944 };
945
946 // overload index operator for arrays
948 if (this->is_write_protect())
949 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
950
951 if (index < 0)
952 throw std::out_of_range("Index \"" + std::to_string(index) + "\" out of range for ODB key \"" + get_full_path() + "[0..." + std::to_string(m_num_values - 1) + "]\"");
953
954 if (index == 0 && m_num_values == 0) {
955 // initialize this
956 m_num_values = 1;
957 m_tid = 0;
958 m_data = new u_odb[1]{};
959 m_data[0].set_tid(m_tid);
960 m_data[0].set_parent(this);
961 m_last_index = 0;
962 return m_data[0];
963 } else if (index >= m_num_values) {
964 if (is_auto_enlarge_array()) {
966 if (this->is_auto_refresh_write())
967 write(index, 0);
968 } else {
969 throw std::out_of_range("Index \"" + std::to_string(index) + "\" out of range for ODB key \"" + get_full_path() + "[0..." + std::to_string(m_num_values - 1) + "]\", please consider set_auto_enlarge_array(true)");
970 }
971 }
972
974 read(index);
975
977 return m_data[index];
978 }
979
980 // overload index operator for subkeys
981 odb &operator[](std::string str) {
982 return get_subkey(str);
983 }
984
985 odb &operator[](const char *str) {
986 return get_subkey(std::string(str));
987 }
988
989 // overload the call operator
990 template <typename T>
992 if (m_tid == 0) {
993 if (m_num_values == 0) {
994 // initialize this
995 m_num_values = 1;
996 m_tid = detect_type(v);
997 m_data = new u_odb[1]{};
998 m_data[0].set_tid(m_tid);
999 m_data[0].set_parent(this);
1000 m_data[0].set(v);
1001 if (this->is_auto_refresh_write())
1002 write();
1003 } else {
1004 for (int i = 0; i < m_num_values; i++)
1005 m_data[i].set(v);
1006 if (this->is_auto_refresh_write())
1007 write();
1008 }
1009 }
1010 return *this;
1011 }
1012
1013 // indexed access, internal use only
1015 void set_last_index(int i) { m_last_index = i; }
1016
1017 // iterator support
1018 iterator begin() const { return iterator(m_data); }
1019 iterator end() const { return iterator(m_data + m_num_values); }
1020
1021 // overload arithmetic operators
1022 template<typename T>
1024 if (m_num_values > 1)
1025 mthrow("ODB key \"" + get_full_path() +
1026 "\" contains array which cannot be used in basic arithmetic operation.");
1027 if (std::is_same<T, midas::odb>::value) {
1028 if (is_auto_refresh_read()) {
1029 read();
1030 i.read();
1031 }
1032 // adding two midas::odb objects is best done in double
1033 double s1 = static_cast<double>(m_data[0]);
1034 double s2 = static_cast<double>(i.m_data[0]);
1035 return s1 + s2;
1036 } else {
1038 read();
1039 T s = (T) m_data[0];
1040 return s + i;
1041 }
1042 }
1043
1044 template<typename T>
1046 if (m_num_values > 1)
1047 mthrow("ODB key \"" + get_full_path() +
1048 "\" contains array which cannot be used in basic arithmetic operation.");
1049 if (std::is_same<T, midas::odb>::value) {
1050 if (is_auto_refresh_read()) {
1051 read();
1052 i.read();
1053 }
1054 // subtracting two midas::odb objects is best done in double
1055 double s1 = static_cast<double>(m_data[0]);
1056 double s2 = static_cast<double>(i.m_data[0]);
1057 return s1 - s2;
1058 } else {
1060 read();
1061 T s = (T) m_data[0];
1062 return s - i;
1063 }
1064 }
1065
1066 template<typename T>
1067 T operator*(const T i) {
1068 if (m_num_values > 1)
1069 mthrow("ODB key \"" + get_full_path() +
1070 "\" contains array which cannot be used in basic arithmetic operation.");
1072 read();
1073 T s = (T) m_data[0];
1074 return s * i;
1075 }
1076
1077 template<typename T>
1078 T operator/(const T i) {
1079 if (m_num_values > 1)
1080 mthrow("ODB key \"" + get_full_path() +
1081 "\" contains array which cannot be used in basic arithmetic operation.");
1083 read();
1084 T s = (T) m_data[0];
1085 return s / i;
1086 }
1087
1090 read();
1091 for (int i = 0; i < m_num_values; i++)
1092 m_data[i].add(1, false);
1093 if (this->is_auto_refresh_write())
1094 write();
1095 return *this;
1096 }
1097
1099 // create temporary object
1100 odb o(this);
1102 read();
1103 for (int i = 0; i < m_num_values; i++)
1104 m_data[i].add(1, false);
1105 if (this->is_auto_refresh_write())
1106 write();
1107 return o;
1108 }
1109
1112 read();
1113 for (int i = 0; i < m_num_values; i++)
1114 m_data[i].add(-1, false);
1115 if (this->is_auto_refresh_write())
1116 write();
1117 return *this;
1118 }
1119
1121 // create temporary object
1122 odb o(this);
1124 read();
1125 for (int i = 0; i < m_num_values; i++)
1126 m_data[i].add(-1, false);
1127 if (this->is_auto_refresh_write())
1128 write();
1129 return o;
1130 }
1131
1132 odb &operator+=(double d) {
1134 read();
1135 for (int i = 0; i < m_num_values; i++)
1136 m_data[i].add(d, false);
1137 if (this->is_auto_refresh_write())
1138 write();
1139 return *this;
1140 }
1141
1142 odb &operator-=(double d) {
1144 read();
1145 for (int i = 0; i < m_num_values; i++)
1146 m_data[i].add(-d, false);
1147 if (this->is_auto_refresh_write())
1148 write();
1149 return *this;
1150 }
1151
1152 odb &operator*=(double d) {
1154 read();
1155 for (int i = 0; i < m_num_values; i++)
1156 m_data[i].mult(d, false);
1157 if (this->is_auto_refresh_write())
1158 write();
1159 return *this;
1160 }
1161
1162 odb &operator/=(double d) {
1164 read();
1165 if (d == 0)
1166 mthrow("Division by zero");
1167 for (int i = 0; i < m_num_values; i++)
1168 m_data[i].mult(1 / d, false);
1169 if (this->is_auto_refresh_write())
1170 write();
1171 return *this;
1172 }
1173
1174 // overload comparison operators
1175 template<typename T>
1176 friend bool operator==(const midas::odb &o, const T &d);
1177 template<typename T>
1178 friend bool operator==(const T &d, const midas::odb &o);
1179 template<typename T>
1180 friend bool operator!=(const midas::odb &o, const T &d);
1181 template<typename T>
1182 friend bool operator!=(const T &d, const midas::odb &o);
1183 template<typename T>
1184 friend bool operator<(const midas::odb &o, const T &d);
1185 template<typename T>
1186 friend bool operator<(const T &d, const midas::odb &o);
1187 template<typename T>
1188 friend bool operator<=(const midas::odb &o, const T &d);
1189 template<typename T>
1190 friend bool operator<=(const T &d, const midas::odb &o);
1191 template<typename T>
1192 friend bool operator>(const midas::odb &o, const T &d);
1193 template<typename T>
1194 friend bool operator>(const T &d, const midas::odb &o);
1195 template<typename T>
1196 friend bool operator>=(const midas::odb &o, const T &d);
1197 template<typename T>
1198 friend bool operator>=(const T &d, const midas::odb &o);
1199
1200 // create midas::odb object form MXML node
1201 static midas::odb *odb_from_xml(PMXML_NODE node, odb *o) {
1202 std::string type(mxml_get_name(node));
1203
1204 unsigned int tid = 0;
1205 if (type == "dir" || type == "odb")
1206 tid = TID_KEY;
1207 else {
1208 for (tid = 0; tid < TID_LAST; tid++) {
1209 if (equal_ustring(rpc_tid_name(tid), mxml_get_attribute(node, "type")))
1210 break;
1211 }
1212 }
1213 if (tid == TID_LAST)
1214 mthrow("Wrong key type in XML file");
1215
1216 if (o == nullptr)
1217 o = new midas::odb();
1218 o->set_tid(tid);
1219 if (type == "odb") {
1220 o->set_name("root");
1221 o->set_hkey(0);
1222 } else {
1223 o->set_name(mxml_get_attribute(node, "name"));
1224 if (mxml_get_attribute(node, "handle") == nullptr)
1225 mthrow("No \"handle\" attribute found in XML data");
1226 o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1227 }
1228
1229 if (type == "key") {
1230 std::string value(mxml_get_value(node));
1231 o->set(value);
1232 } else if (type == "keyarray") {
1233 int n = std::atoi(mxml_get_attribute(node, "num_values"));
1234 o->set_num_values(n);
1235 for (int i=0 ; i<n ; i++) {
1236 std::string value(mxml_get_value(mxml_subnode(node, i)));
1237 o->set(value, i);
1238 }
1239 } else if (type == "dir" || type == "odb") {
1240 int n = mxml_get_number_of_children(node);
1241 o->set_num_values(n);
1242 for (int i = 0; i < n; i++) {
1243 midas::odb *os = odb_from_xml(mxml_subnode(node, i), nullptr);
1244 os->set_parent(o);
1245 o->set_odb(os, i);
1246 }
1247 } else
1248 mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1249
1250 return o;
1251 };
1252
1253 // set midas::odb object form a non-array MJsonNode
1254 static std::string node_to_string(const MJsonNode* node) {
1255 std::string value;
1256
1257 switch (node->GetType()) {
1258 case MJSON_STRING:
1259 value = node->GetString();
1260 break;
1261 case MJSON_INT:
1262 value = std::to_string(node->GetInt());
1263 break;
1264 case MJSON_NUMBER:
1265 value = std::to_string(node->GetDouble());
1266 break;
1267 case MJSON_BOOL:
1268 value = std::to_string(node->GetBool());
1269 break;
1270 default:
1271 mthrow("Invalid MJSON type \"" + std::to_string(node->GetType()) + "\"");
1272 }
1273
1274 return value;
1275 };
1276
1277 // create midas::odb object form MJsonNode
1278 static midas::odb *odb_from_json(const MJsonNode* node, std::string name, int tid, odb *o) {
1279 int type = node->GetType();
1280
1281 if (type == MJSON_OBJECT) { // subdir
1282 const MJsonStringVector* names = node->GetObjectNames();
1283 const MJsonNodeVector* nodes = node->GetObjectNodes();
1284 if (names == nullptr || nodes==nullptr || names->size() != nodes->size())
1285 mthrow("Invalid JSON format");
1286
1287 if (o == nullptr)
1288 o = new midas::odb();
1289 o->set_tid(TID_KEY);
1290 o->set_name(name);
1291 o->set_hkey(0);
1292
1293 // count subkeys
1294 int n=0;
1295 for (int i=0 ; i<(int)names->size() ; i++) {
1296 const char *name = (*names)[i].c_str();
1297
1298 if (strchr(name, '/'))// skip special entries
1299 continue;
1300 n++;
1301 }
1302 o->set_num_values(n);
1303
1304 for (int i=n=0 ; i<(int)names->size() ; i++) {
1305 const char *name = (*names)[i].c_str();
1306
1307 if (strchr(name, '/'))// skip special entries
1308 continue;
1309
1310 int t = 0;
1311 auto key = node->FindObjectNode((std::string(name) + "/key").c_str());
1312 if (key)
1313 t = key->FindObjectNode("type")->GetInt();
1314 else
1315 t = TID_KEY;
1316
1317 midas::odb *os = odb_from_json((*nodes)[i], (*names)[i].c_str(), t, nullptr);
1318 os->set_parent(o);
1319 o->set_odb(os, n);
1320 n++;
1321 }
1322
1323 o->set_num_values(n);
1324
1325 } else { // key
1326
1327 if (o == nullptr)
1328 o = new midas::odb();
1329
1330 o->set_name(name);
1331 o->set_tid(tid);
1332 o->set_hkey(0);
1333
1334 if (node->GetType() == MJSON_ARRAY) {
1335 const MJsonNodeVector* a = node->GetArray();
1336 o->set_num_values(a->size());
1337 for (int i=0 ; i<(int)a->size() ; i++) {
1338 MJsonNode *n = (*a)[i];
1339 auto value = node_to_string(n);
1340 o->set(value, i);
1341 }
1342 } else {
1343 auto value = node_to_string(node);
1344 o->set(value);
1345 }
1346 }
1347
1348 return o;
1349 };
1350
1351 // Deep copy
1352 void deep_copy(odb &d, const odb &s);
1353
1354 // Setters and Getters
1360
1366
1372
1373 bool is_dirty() const { return m_flags[odb_flags::DIRTY]; }
1374 void set_dirty(bool f) { m_flags[odb_flags::DIRTY] = f; }
1375
1381
1387
1393
1399
1400 // Static functions
1401 static void set_debug(bool flag) { s_debug = flag; }
1402 static bool get_debug() { return s_debug; }
1403 static int create(const char *name, int type = TID_KEY);
1404 static bool exists(const std::string &name);
1405 static int delete_key(const std::string &name);
1406 static void load(const std::string &filename, const std::string &odb_path);
1407
1408 void odb_from_xml_remote(const std::string &str);
1409 void odb_from_xml_string(const std::string &str, const std::string &subkey);
1410 void odb_from_json_string(const std::string &str, const std::string &subkey);
1411 void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults = false);
1412 void connect(std::string str, bool write_defaults = false, bool delete_keys_not_in_defaults = false);
1413 void connect_and_fix_structure(std::string path);
1414
1417 if (s == STRING)
1418 mthrow1("ODB source STRING requires a string");
1419 if (s == FILE)
1420 mthrow1("ODB source FILE requires a filename");
1421 s_odb_source = s;
1422 }
1423
1424 static void set_odb_source(odb::odb_source s, std::string str);
1425 static void odb_from_xml_string(const std::string &str);
1426 static void odb_from_json_string(const std::string &str);
1427
1428 static bool is_connected_odb() { return s_connected_odb; }
1429
1430 void read();
1431 void read(int index);
1432 void write(int str_size = 0);
1433 void write(int index, int str_size);
1434 std::string print();
1435 std::string dump();
1436 void print(std::string &s, int indent=0);
1437 void dump(std::string &s, int indent=0);
1438 void save(const std::string &filename);
1439 void delete_key();
1440 int size();
1441 void resize(int size);
1442 void resize(int size, bool b);
1443 void watch(std::function<void(midas::odb &)> f);
1444 void unwatch();
1445 void set(std::string str);
1446 void set(std::string s, int i);
1447 void set_odb(odb *o, int i);
1448 void set_string_size(std::string s, int size);
1449
1450 bool is_subkey(std::string str);
1451 HNDLE get_hkey() { return m_hKey; }
1452 std::string get_full_path();
1453 std::string get_parent_path();
1454 int get_tid() { return m_tid; }
1456 std::string get_name() { return m_name; }
1457 odb& items() { return *this; }
1458
1459 std::string s() {
1460 std::string s;
1461 get(s);
1462 return s;
1463 }
1464
1465 void fix_order(std::vector<std::string> target_subkey_order);
1466
1467 void set_mode(int mode);
1468 int get_mode();
1469
1470 unsigned int get_last_written();
1471 };
1472
1473 //---- midas::odb friend functions -------------------------------
1474
1475 // overload comparison operators
1476 template<typename T>
1477 bool operator==(const midas::odb &o, const T &d) {
1478 // the operator needs a "const midas::odb" reference,
1479 // so we have to make a non-const copy
1480 T v;
1481 midas::odb oc(o);
1482 oc.get(v);
1483 return v == d;
1484 }
1485
1486 template<typename T>
1487 bool operator==(const T &d, const midas::odb &o) {
1488 T v;
1489 midas::odb oc(o);
1490 oc.get(v);
1491 return d == v;
1492 }
1493
1494 template<typename T>
1495 bool operator!=(const midas::odb &o, const T &d) {
1496 T v;
1497 midas::odb oc(o);
1498 oc.get(v);
1499 return v != d;
1500 }
1501
1502 template<typename T>
1503 bool operator!=(const T &d, const midas::odb &o) {
1504 T v;
1505 midas::odb oc(o);
1506 oc.get(v);
1507 return d != v;
1508 }
1509
1510 template<typename T>
1511 bool operator<(const midas::odb &o, const T &d) {
1512 T v;
1513 midas::odb oc(o);
1514 oc.get(v);
1515 return v < d;
1516 }
1517
1518 template<typename T>
1519 bool operator<(const T &d, const midas::odb &o) {
1520 T v;
1521 midas::odb oc(o);
1522 oc.get(v);
1523 return d < v;
1524 }
1525
1526 template<typename T>
1527 bool operator<=(const midas::odb &o, const T &d) {
1528 T v;
1529 midas::odb oc(o);
1530 oc.get(v);
1531 return v <= d;
1532 }
1533
1534 template<typename T>
1535 bool operator<=(const T &d, const midas::odb &o) {
1536 T v;
1537 midas::odb oc(o);
1538 oc.get(v);
1539 return d <= v;
1540 }
1541
1542 template<typename T>
1543 bool operator>(const midas::odb &o, const T &d) {
1544 T v;
1545 midas::odb oc(o);
1546 oc.get(v);
1547 return v > d;
1548 }
1549
1550 template<typename T>
1551 bool operator>(const T &d, const midas::odb &o) {
1552 T v;
1553 midas::odb oc(o);
1554 oc.get(v);
1555 return d > v;
1556 }
1557
1558 template<typename T>
1559 bool operator>=(const midas::odb &o, const T &d) {
1560 T v;
1561 midas::odb oc(o);
1562 oc.get(v);
1563 return v >= d;
1564 }
1565
1566 template<typename T>
1567 bool operator>=(const T &d, const midas::odb &o) {
1568 T v;
1569 midas::odb oc(o);
1570 oc.get(v);
1571 return d >= v;
1572 }
1573
1574} // namespace midas
1575
1576
1577#endif // _ODBXX_HXX
iterator operator++()
Definition odbxx.h:424
iterator operator++(int)
Definition odbxx.h:430
iterator(u_odb *pu)
Definition odbxx.h:421
u_odb & operator*()
Definition odbxx.h:438
bool operator!=(const iterator &other) const
Definition odbxx.h:436
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1614
std::string get_parent_path()
Definition odbxx.cxx:378
odb operator=(odb &&o)=delete
odb(std::initializer_list< T > list)
Definition odbxx.h:608
odb & operator*=(double d)
Definition odbxx.h:1152
std::string get_full_path()
Definition odbxx.cxx:362
void set(std::string str)
Definition odbxx.cxx:1584
static std::string node_to_string(const MJsonNode *node)
Definition odbxx.h:1254
int m_num_values
Definition odbxx.h:469
iterator end() const
Definition odbxx.h:1019
static bool exists(const std::string &name)
Definition odbxx.cxx:76
midas::odb * get_parent()
Definition odbxx.h:539
odb & operator+=(double d)
Definition odbxx.h:1132
std::string get_name()
Definition odbxx.h:1456
int m_tid
Definition odbxx.h:463
void set_mode(int mode)
Definition odbxx.cxx:1502
void set_auto_refresh_read(bool f)
Definition odbxx.h:1362
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1383
odb(const std::array< T, SIZE > &arr)
Definition odbxx.h:624
void delete_key()
Definition odbxx.cxx:1473
void set_odb(odb *o, int i)
Definition odbxx.cxx:1628
u_odb * m_data
Definition odbxx.h:465
void deep_copy(odb &d, const odb &s)
Definition odbxx.cxx:334
bool is_deleted() const
Definition odbxx.h:530
static void set_debug(bool flag)
Definition odbxx.h:1401
static midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
Definition odbxx.h:1201
odb & operator++()
Definition odbxx.h:1088
bool is_auto_refresh_read() const
Definition odbxx.h:1361
static void unwatch_all()
Definition odbxx.cxx:1575
static HNDLE s_hDB
Definition odbxx.h:452
HNDLE get_hkey()
Definition odbxx.h:1451
static void set_odb_source(odb::odb_source s)
Definition odbxx.h:1416
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:475
bool is_auto_create() const
Definition odbxx.h:1376
bool is_preserve_string_size() const
Definition odbxx.h:1355
static void watch_callback(int hDB, int hKey, int index, void *info)
Definition odbxx.cxx:124
odb(const std::array< std::string, SIZE > &arr)
Definition odbxx.h:638
void unwatch()
Definition odbxx.cxx:1563
T operator+(T i)
Definition odbxx.h:1023
u_odb & operator[](int index)
Definition odbxx.h:947
T get()
Definition odbxx.h:494
odb(std::initializer_list< std::pair< const char *, midas::odb > > list)
Definition odbxx.h:579
int get_tid()
Definition odbxx.h:1454
static midas::odb * odb_from_json(const MJsonNode *node, std::string name, int tid, odb *o)
Definition odbxx.h:1278
static bool get_debug()
Definition odbxx.h:1402
bool is_auto_refresh_write() const
Definition odbxx.h:1367
u_odb & get_mdata(int index=0)
Definition odbxx.h:518
friend bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1477
void set_tid(int tid)
Definition odbxx.h:533
odb & operator[](const char *str)
Definition odbxx.h:985
bool read_key(const std::string &path)
Definition odbxx.cxx:657
friend bool operator>=(const midas::odb &o, const T &d)
Definition odbxx.h:1559
friend bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1527
friend bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1511
void resize(int size)
Definition odbxx.cxx:391
T operator/(const T i)
Definition odbxx.h:1078
void set_preserve_string_size(bool f)
Definition odbxx.h:1356
static thread_local odb_source s_odb_source
Definition odbxx.h:447
void set_trigger_hotlink(bool f)
Definition odbxx.h:1395
odb(T v)
Definition odbxx.h:571
int size()
Definition odbxx.cxx:386
void set_flags(uint32_t f)
Definition odbxx.h:527
void set_auto_refresh_write(bool f)
Definition odbxx.h:1368
int get_mode()
Definition odbxx.cxx:1519
odb & operator--()
Definition odbxx.h:1110
void odb_from_xml_remote(const std::string &str)
Definition odbxx.cxx:160
void set_auto_create(bool f)
Definition odbxx.h:1377
static thread_local std::string s_odb_source_str
Definition odbxx.h:448
void odb_from_xml_string(const std::string &str, const std::string &subkey)
void read()
Definition odbxx.cxx:802
void resize_mdata(int size)
Definition odbxx.cxx:261
static odb::odb_source get_odb_source()
Definition odbxx.h:1415
friend bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1543
bool is_dirty() const
Definition odbxx.h:1373
const std::vector< T > & operator=(const std::vector< T > &v)
Definition odbxx.h:809
iterator begin() const
Definition odbxx.h:1018
const T & operator=(const T &v)
Definition odbxx.h:782
odb & get_subkey(std::string str)
Definition odbxx.cxx:568
odb & operator()(T v)
Definition odbxx.h:991
void set_hkey(HNDLE hKey)
Definition odbxx.h:525
odb & operator/=(double d)
Definition odbxx.h:1162
void odb_from_json_string(const std::string &str, const std::string &subkey)
void set_flags_recursively(uint32_t f)
Definition odbxx.cxx:152
unsigned int get_last_written()
Definition odbxx.cxx:1533
odb operator--(int)
Definition odbxx.h:1120
void set_name(std::string s)
Definition odbxx.h:536
int get_subkeys(std::vector< std::string > &name)
Definition odbxx.cxx:632
void watch(std::function< void(midas::odb &)> f)
Definition odbxx.cxx:1547
static thread_local odb * s_odb
Definition odbxx.h:450
odb(const char *s)
Definition odbxx.h:727
int get_last_index()
Definition odbxx.h:1014
std::string s()
Definition odbxx.h:1459
friend std::ostream & operator<<(std::ostream &output, odb &o)
Definition odbxx.h:936
bool is_auto_enlarge_array() const
Definition odbxx.h:1382
friend bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1495
int detect_type(const T &)
Definition odbxx.h:745
void save(const std::string &filename)
Definition odbxx.cxx:518
void set_last_index(int i)
Definition odbxx.h:1015
static int create(const char *name, int type=TID_KEY)
Definition odbxx.cxx:140
bool is_subkey(std::string str)
Definition odbxx.cxx:544
static bool s_debug
Definition odbxx.h:454
void fix_order(std::vector< std::string > target_subkey_order)
Definition odbxx.cxx:1314
odb(const std::string &path, bool init_via_xml=false)
Definition odbxx.h:652
std::string dump()
Definition odbxx.cxx:427
int m_last_index
Definition odbxx.h:471
odb operator++(int)
Definition odbxx.h:1098
void connect_and_fix_structure(std::string path)
Definition odbxx.cxx:1459
static bool s_connected_odb
Definition odbxx.h:456
const std::array< T, SIZE > & operator=(const std::array< T, SIZE > &arr)
Definition odbxx.h:855
static void init_hdb()
Definition odbxx.cxx:50
int get_num_values()
Definition odbxx.h:1455
operator std::string()
Definition odbxx.h:887
odb & operator-=(double d)
Definition odbxx.h:1142
void set_num_values(int n)
Definition odbxx.h:534
uint32_t get_flags()
Definition odbxx.h:528
bool is_trigger_hotlink() const
Definition odbxx.h:1394
bool write_key(std::string &path, bool write_defaults)
Definition odbxx.cxx:743
std::string print()
Definition odbxx.cxx:419
static midas::odb * search_hkey(midas::odb *po, int hKey)
Definition odbxx.cxx:62
static bool is_connected_odb()
Definition odbxx.h:1428
odb(std::initializer_list< const char * > list)
Definition odbxx.h:731
std::bitset< 9 > m_flags
Definition odbxx.h:461
static std::vector< midas::odb > m_watch
Definition odbxx.h:458
odb & operator[](std::string str)
Definition odbxx.h:981
void set_deleted(bool f)
Definition odbxx.h:531
static void load(const std::string &filename, const std::string &odb_path)
Definition odbxx.cxx:102
void set_parent(midas::odb *p)
Definition odbxx.h:538
HNDLE m_hKey
Definition odbxx.h:473
T operator-(T i)
Definition odbxx.h:1045
void set_write_protect(bool f)
Definition odbxx.h:1389
std::string m_name
Definition odbxx.h:467
void get(T &v)
Definition odbxx.h:506
bool is_write_protect() const
Definition odbxx.h:1388
T operator*(const T i)
Definition odbxx.h:1067
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
Definition odbxx.cxx:1377
odb & items()
Definition odbxx.h:1457
void set_dirty(bool f)
Definition odbxx.h:1374
midas::odb * m_parent
Definition odbxx.h:477
void set(const char *v)
Definition odbxx.h:228
u_odb & operator/=(double d)
Definition odbxx.h:277
uint8_t m_uint8
Definition odbxx.h:52
bool m_bool
Definition odbxx.h:60
uint8_t operator=(uint8_t v)
Definition odbxx.cxx:1739
void set_tid(int tid)
Definition odbxx.h:105
void mult(double f, bool push=true)
Definition odbxx.cxx:1964
void set_string(std::string s)
Definition odbxx.h:172
u_odb(uint8_t v)
Definition odbxx.h:74
u_odb(int8_t v)
Definition odbxx.h:76
u_odb & operator+(T v)
Definition odbxx.h:285
int8_t m_int8
Definition odbxx.h:53
u_odb(double v)
Definition odbxx.h:94
uint64_t m_uint64
Definition odbxx.h:58
u_odb & operator--(int)
Definition odbxx.h:252
u_odb & operator+=(double d)
Definition odbxx.h:262
int32_t m_int32
Definition odbxx.h:57
u_odb(float v)
Definition odbxx.h:92
int64_t m_int64
Definition odbxx.h:59
void set(T v)
Definition odbxx.h:142
double m_double
Definition odbxx.h:62
u_odb & operator/(T v)
Definition odbxx.h:309
odb * m_parent_odb
Definition odbxx.h:68
u_odb & operator*=(double d)
Definition odbxx.h:272
u_odb & operator++()
Definition odbxx.h:247
void set_odb(odb *v)
Definition odbxx.h:189
u_odb(std::string *v)
Definition odbxx.h:96
int m_tid
Definition odbxx.h:67
void set_parent(odb *o)
Definition odbxx.h:102
void set(std::string v)
Definition odbxx.h:195
u_odb & operator++(int)
Definition odbxx.h:242
void set(odb *v)
Definition odbxx.h:183
friend std::ostream & operator<<(std::ostream &output, u_odb &o)
Definition odbxx.h:382
u_odb(int16_t v)
Definition odbxx.h:80
u_odb & operator-(T v)
Definition odbxx.h:293
u_odb(uint32_t v)
Definition odbxx.h:82
uint16_t m_uint16
Definition odbxx.h:54
odb * get_podb()
Definition odbxx.h:369
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1854
int16_t m_int16
Definition odbxx.h:55
u_odb & operator--()
Definition odbxx.h:257
odb & get_odb()
Definition odbxx.h:375
u_odb & operator-=(double d)
Definition odbxx.h:267
std::string s()
Definition odbxx.h:361
u_odb(int64_t v)
Definition odbxx.h:88
u_odb(uint64_t v)
Definition odbxx.h:86
u_odb(int32_t v)
Definition odbxx.h:84
std::string * m_string
Definition odbxx.h:63
void set_string_ptr(std::string *s)
Definition odbxx.h:179
std::string get()
Definition odbxx.h:348
u_odb(uint16_t v)
Definition odbxx.h:78
odb * get_parent()
Definition odbxx.h:103
u_odb & operator*(T v)
Definition odbxx.h:301
odb * m_odb
Definition odbxx.h:64
float m_float
Definition odbxx.h:61
uint32_t m_uint32
Definition odbxx.h:56
u_odb(bool v)
Definition odbxx.h:90
void set(char *v)
Definition odbxx.h:232
std::string get_value()
Definition odbxx.h:354
int get_tid()
Definition odbxx.h:107
#define SIZE
#define TID_DOUBLE
Definition midas.h:343
#define TID_KEY
Definition midas.h:349
#define TID_BOOL
Definition midas.h:340
#define TID_UINT64
Definition midas.h:352
#define TID_INT64
Definition midas.h:351
#define TID_INT32
Definition midas.h:339
#define TID_UINT8
Definition midas.h:328
#define TID_LINK
Definition midas.h:350
#define TID_STRING
Definition midas.h:346
#define TID_INT8
Definition midas.h:330
#define TID_UINT32
Definition midas.h:337
#define TID_UINT16
Definition midas.h:333
#define TID_INT16
Definition midas.h:335
#define TID_FLOAT
Definition midas.h:341
#define TID_LAST
Definition midas.h:354
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3285
const char * rpc_tid_name(INT id)
Definition midas.cxx:11895
void ** info
Definition fesimdaq.cxx:41
HNDLE hKey
DWORD n[4]
Definition mana.cxx:247
INT index
Definition mana.cxx:271
INT type
Definition mana.cxx:269
HNDLE hDB
main ODB handle
Definition mana.cxx:207
BOOL create
Definition mchart.cxx:39
INT element
Definition mchart.cxx:40
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
#define mthrow1(arg)
Definition mexcept.h:27
#define mthrow(arg)
Definition mexcept.h:24
static void output(code_int code)
Definition mgd.cxx:1647
INT HNDLE
Definition midas.h:132
#define write(n, a, f, d)
#define name(x)
Definition midas_macro.h:24
#define set(var, value)
static std::string indent(int x, const char *p=" ")
static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf, int64_t len)
bool operator>=(const midas::odb &o, const T &d)
Definition odbxx.h:1559
bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1543
bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1477
bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1511
odb_flags
Definition odbxx.h:393
@ AUTO_REFRESH_WRITE
Definition odbxx.h:395
@ DIRTY
Definition odbxx.h:399
@ TRIGGER_HOTLINK
Definition odbxx.h:402
@ AUTO_REFRESH_READ
Definition odbxx.h:394
@ WRITE_PROTECT
Definition odbxx.h:401
@ AUTO_ENLARGE_ARRAY
Definition odbxx.h:398
@ AUTO_CREATE
Definition odbxx.h:397
@ PRESERVE_STRING_SIZE
Definition odbxx.h:396
@ DELETED
Definition odbxx.h:400
bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1527
bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1495
INT j
Definition odbhist.cxx:40
double value[100]
Definition odbhist.cxx:42
char str[256]
Definition odbhist.cxx:33
INT add
Definition odbhist.cxx:40
double d
Definition system.cxx:1313
static te_expr * list(state *s)
Definition tinyexpr.c:567