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 || m_tid == TID_CHAR)
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 || m_tid == TID_CHAR)
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 || m_tid == TID_CHAR)
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 size_t string_size() const {
361 if (m_tid != TID_STRING && m_tid != TID_LINK)
362 mthrow("Only ODB string keys support string_size()");
363 return m_string->size();
364 }
365
366 // shortcut to above
367 std::string s() {
368 return get();
369 }
370
371 // get function for strings
372 void get(std::string &s);
373
374 // get_function for keys
376 if (m_tid != TID_KEY)
377 mthrow("odb_get() called for non-key object");
378 return m_odb;
379 }
380
382 if (m_tid != TID_KEY)
383 mthrow("odb_get() called for non-key object");
384 return *m_odb;
385 }
386
387 // overload stream out operator
388 friend std::ostream &operator<<(std::ostream &output, u_odb &o) {
389 std::string s = o;
390 output << s;
391 return output;
392 };
393
394 };
395
396 //-----------------------------------------------
397
398 // bit in odb::m_flags
410
411 //================================================================
412 // the odb object holds an ODB entry with name, type,
413 // hKey and array of u_odb values
414 //================================================================
415
416 class odb {
417 public:
418 // data source
424
425 class iterator {
426 public:
427 iterator(u_odb *pu) : pu_odb(pu) {}
428
429 // Pre-increment
431 ++pu_odb;
432 return *this;
433 }
434
435 // Post-increment
437 iterator ret = *this;
438 this->operator++();
439 return ret;
440 }
441
442 bool operator!=(const iterator &other) const { return pu_odb != other.pu_odb; }
443
444 u_odb &operator*() { return *pu_odb; }
445
446 private:
448 };
449
450 private:
451
452 // source of ODB, same for all instances
453 thread_local static odb_source s_odb_source;
454 thread_local static std::string s_odb_source_str; // string or filename
455 // odb object holding whole ODB for FILE and STRING sources
456 thread_local static odb *s_odb;
457 // handle to ODB, same for all instances
458 static HNDLE s_hDB;
459 // global debug flag for all instances
460 static bool s_debug;
461 // global flag indicating that we are connected to the ODB
462 static bool s_connected_odb;
463 // global list of ODB keys used by odb::watch
464 static std::vector<midas::odb> m_watch;
465
466 // various parameters defined in odb_flags
467 std::bitset<9> m_flags;
468 // type of this object, one of TID_xxx
469 int m_tid;
470 // vector containing data for this object
472 // name of ODB entry
473 std::string m_name;
474 // number of values of ODB entry
476 // last index accessed, needed for o[i] = x
478 // ODB handle for this key
480 // callback for watch funciton
481 std::function<void(midas::odb &)> m_watch_callback;
482 // parent ODB key
484
485 //-------------------------------------------------------------
486
487 // static functions
488 static void init_hdb();
489 static midas::odb *search_hkey(midas::odb *po, int hKey);
490 static void watch_callback(int hDB, int hKey, int index, void *info);
491 static void unwatch_all();
492
493 //-------------------------------------------------------------
494
495 void set_flags_recursively(uint32_t f);
496 void resize_mdata(int size);
497 int write_string_array(int str_size);
498
499 // get function for basic types
500 template<typename T>
501 T get() {
502 if (m_num_values > 1)
503 mthrow("ODB key \"" + get_full_path() +
504 "[0..." + std::to_string(m_num_values - 1) +
505 "]\" contains array. Please assign to std::vector.");
507 read();
508 return (T) m_data[0];
509 }
510
511 // get function for basic types as a parameter
512 template<typename T>
513 void get(T &v) {
514 if (m_num_values > 1)
515 mthrow("ODB key \"" + get_full_path() + "\" contains array. Please assign to std::vector.");
517 read();
518 v = (T) m_data[0];
519 }
520
521 // get function for strings
522 void get(std::string &s, bool quotes = false, bool refresh = true);
523
524 // return internal data
525 u_odb &get_mdata(int index = 0) { return m_data[index]; }
526
527 odb &get_subkey(std::string str);
528 int get_subkeys(std::vector<std::string> &name);
529 bool read_key(const std::string &path);
530 bool write_key(std::string &path, bool write_defaults);
531
533
534 void set_flags(uint32_t f) { m_flags = f; }
535 uint32_t get_flags() { return static_cast<uint32_t>(m_flags.to_ulong()); }
536
537 bool is_deleted() const { return m_flags[odb_flags::DELETED]; }
539
540 void set_tid(int tid) { m_tid = tid; }
542
543 void set_name(std::string s) { m_name = s; }
544
547
548 public:
549
550 // Default constructor
551 odb() :
555 (1 << odb_flags::AUTO_CREATE) |
556 (1 << odb_flags::TRIGGER_HOTLINK)},
557 m_tid{0},
558 m_data{nullptr},
559 m_name{},
560 m_num_values{0},
561 m_last_index{-1},
562 m_hKey{},
563 m_parent{} {}
564
565 // Destructor
567 delete[] m_data;
568 }
569
570 // Deep copy constructor
571 odb(const odb &o);
572
573 // Delete shallow assignment operator
574 odb operator=(odb &&o) = delete;
575
576 // Constructor for single basic types
577 template<typename T>
578 odb(T v):odb() {
579 m_num_values = 1;
580 m_data = new u_odb[1]{v};
581 m_tid = m_data[0].get_tid();
582 m_data[0].set_parent(this);
583 }
584
585 // Constructor with std::initializer_list
586 odb(std::initializer_list<std::pair<const char *, midas::odb>> list) : odb() {
587 m_tid = TID_KEY;
588 m_num_values = list.size();
590 int i = 0;
591 for (auto &element: list) {
592 // check if name exists already
593 for (int j=0 ; j<i ; j++) {
594 if (strcasecmp(element.first, m_data[j].get_odb().get_name().c_str()) == 0) {
595 if (element.first == m_data[j].get_odb().get_name()) {
596 mthrow("ODB key with name \"" + m_data[j].get_odb().get_name() + "\" exists already");
597 } else {
598 mthrow("ODB key \"" + std::string(element.first) + "\" exists already as \"" +
599 m_data[j].get_odb().get_name() + "\" (only case differs)");
600 }
601 }
602 }
603 auto o = new midas::odb(element.second);
604 o->set_name(element.first);
605 o->set_parent(this);
607 m_data[i].set_parent(this);
608 m_data[i].set(o);
609 i++;
610 }
611 }
612
613 // Constructor with basic type array
614 template<typename T>
615 odb(std::initializer_list<T> list) : odb() {
616 m_num_values = list.size();
617 m_data = new u_odb[m_num_values]{};
618 int i = 0;
619 for (auto &element : list) {
620 u_odb u(element);
621 m_data[i].set_tid(u.get_tid());
622 m_data[i].set_parent(this);
624 i++;
625 }
626 m_tid = m_data[0].get_tid();
627 }
628
629 // Constructor with basic explicit array
630 template<typename T, size_t SIZE>
631 odb(const std::array<T, SIZE> &arr) : odb() {
633 m_data = new u_odb[m_num_values]{};
634 for (int i = 0; i < (int)SIZE; i++) {
635 u_odb u(arr[i]);
636 m_data[i].set_tid(u.get_tid());
637 m_data[i].set_parent(this);
638 m_data[i].set(arr[i]);
639 }
640 m_tid = m_data[0].get_tid();
641 }
642
643 // Constructor with explicit array of std::string
644 template<size_t SIZE>
645 odb(const std::array<std::string, SIZE> &arr) : odb() {
647 m_data = new u_odb[m_num_values]{};
648 for (int i = 0; i < (int)SIZE; i++) {
649 std::string * mystring = new std::string(arr[i]);
650 u_odb u(mystring);
651 m_data[i].set_tid(u.get_tid());
652 m_data[i].set_parent(this);
653 m_data[i].set(arr[i]);
654 }
655 m_tid = m_data[0].get_tid();
656 }
657
658 // Constructor for std::string
659 odb(const std::string &path, bool init_via_xml = false) : odb() {
660 if (path[0] == '/') {
661 // ODB path
662 if (s_odb_source == ONLINE) {
663 if (init_via_xml) {
664 if (!exists(path))
665 odb::create(path.c_str(), TID_KEY);
667 } else {
668 if (!read_key(path))
669 // create subdir if key does not exist
670 odb::create(path.c_str(), TID_KEY);
671
672 if (!read_key(path))
673 mthrow("ODB key \"" + path + "\" not found in ODB");
674
675 if (m_tid != TID_KEY)
676 read();
677 }
678 } else if (s_odb_source == STRING || s_odb_source == FILE) {
679
680 // split path
681 std::stringstream ss(path.substr(1));
682 std::string item;
683 std::vector<std::string> arr;
684 while (std::getline(ss, item, '/'))
685 arr.push_back(item);
686
687 // extract subkey from root odb
688 odb *o = s_odb;
689 for (size_t i = 0; i < arr.size(); i++)
690 o = &(*o)[arr[i]];
691
692 // do a deep copy from "o" to "this"
693 m_tid = o->m_tid;
694 m_tid = o->m_tid;
695 m_name = o->m_name;
697 m_hKey = o->m_hKey;
700 for (int i = 0; i < m_num_values; i++) {
702 m_data[i].set_parent(this);
703 if (m_tid == TID_STRING || m_tid == TID_LINK) {
704 // set_string() creates a copy of our string
705 m_data[i].set_string(o->m_data[i]);
706 } else if (m_tid == TID_KEY) {
707 // recursive call to create a copy of the odb object
708 auto *po= o->m_data[i].get_podb();
709 auto *pc = new midas::odb(*po);
710 pc->set_parent(this);
711 m_data[i].set(pc);
712 } else {
713 // simply pass basic types
714 m_data[i] = o->m_data[i];
715 m_data[i].set_parent(this);
716 }
717 }
718
719 } else
720 mthrow("Unknown ODB source: " + std::to_string(s_odb_source));
721
722 } else {
723 // simple string
724
725 // Construct object from initializer_list
726 m_num_values = 1;
727 m_data = new u_odb[1]{new std::string{path}};
728 m_tid = m_data[0].get_tid();
729 m_data[0].set_parent(this);
730 }
731 }
732
733 // Constructor for C string
734 odb(const char *s) : odb(std::string(s)) {
735 }
736
737 // Constructor with const char * array
738 odb(std::initializer_list<const char *> list) : odb() {
739 m_num_values = list.size();
740 m_data = new u_odb[m_num_values]{};
741 int i = 0;
742 for (auto &element : list) {
744 m_data[i].set_parent(this);
746 i++;
747 }
748 m_tid = m_data[0].get_tid();
749 }
750
751 template<typename T>
752 int detect_type(const T &) {
753 if (std::is_same<T, uint8_t>::value)
754 return TID_UINT8;
755 else if (std::is_same<T, int8_t>::value)
756 return TID_INT8;
757 else if (std::is_same<T, uint16_t>::value)
758 return TID_UINT16;
759 else if (std::is_same<T, int16_t>::value)
760 return TID_INT16;
761 else if (std::is_same<T, uint32_t>::value)
762 return TID_UINT32;
763 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
764 return TID_UINT32;
765 else if (std::is_same<T, int32_t>::value)
766 return TID_INT32;
767 else if (std::is_same<T, long>::value && sizeof(long) == 4)
768 return TID_INT32;
769 else if (std::is_same<T, uint64_t>::value)
770 return TID_UINT64;
771 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
772 return TID_UINT64;
773 else if (std::is_same<T, int64_t>::value)
774 return TID_INT64;
775 else if (std::is_same<T, long>::value && sizeof(long) == 8)
776 return TID_INT64;
777 else if (std::is_same<T, bool>::value)
778 return TID_BOOL;
779 else if (std::is_same<T, float>::value)
780 return TID_FLOAT;
781 else if (std::is_same<T, double>::value)
782 return TID_DOUBLE;
783 else
784 return TID_STRING;
785 }
786
787 // Overload the Assignment Operators
788 template<typename T>
789 const T &operator=(const T &v) {
790
791 if (this->is_write_protect())
792 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
793
794 if (m_num_values == 0) {
795 // initialize this
796 m_num_values = 1;
797 m_tid = detect_type(v);
798 m_data = new u_odb[1]{};
799 m_data[0].set_tid(m_tid);
800 m_data[0].set_parent(this);
801 m_data[0].set(v);
802 if (this->is_auto_refresh_write())
803 write();
804 } else {
805 for (int i = 0; i < m_num_values; i++)
806 m_data[i].set(v);
807
808 if (this->is_auto_refresh_write())
809 write();
810 }
811 return v;
812 }
813
814 // Overload the Assignment Operators for std::vector
815 template<typename T>
816 const std::vector<T> &operator=(const std::vector<T> &v) {
817
818 if (this->is_write_protect())
819 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
820
821 if (m_num_values == 0) {
822 // initialize this
823 m_num_values = v.size();
824 if (std::is_same<T, bool>::value) {
825 // Special logic for vector<bool>, which may not be a true
826 // container: it's often optimized to be a bitfield, with
827 // references to elements being masked bits rather than bools.
828 // So T is a bool here, but typeof(v[0]) may not be bool!
829 // "Fake container optimization" only applies to vector<bool>,
830 // not array<bool> or any other vector<T>.
831 m_tid = TID_BOOL;
832 } else {
833 // Every other type can be detected using ref to first element.
834 m_tid = detect_type(v[0]);
835 }
836
837 m_data = new u_odb[m_num_values]{};
838 for (int i = 0; i < m_num_values; i++) {
840 m_data[i].set_parent(this);
841 }
842
843 } else {
844
845 // resize internal array if different
846 if ((int)v.size() != m_num_values) {
847 resize_mdata(v.size());
848 }
849 }
850
851 for (int i = 0; i < m_num_values; i++)
852 m_data[i].set(v[i]);
853
854 if (this->is_auto_refresh_write())
855 write();
856
857 return v;
858 }
859
860 // Overload the Assignment Operators for std::array
861 template<typename T, size_t SIZE>
862 const std::array<T, SIZE> &operator=(const std::array<T, SIZE> &arr) {
863
864 if (this->is_write_protect())
865 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
866
867 if (m_num_values == 0) {
868 // initialize this
870 m_tid = detect_type(arr[0]);
871 m_data = new u_odb[m_num_values]{};
872 for (int i = 0; i < m_num_values; i++) {
874 m_data[i].set_parent(this);
875 }
876
877 } else {
878
879 // resize internal array if different
880 if (SIZE != m_num_values) {
882 }
883 }
884
885 for (int i = 0; i < m_num_values; i++)
886 m_data[i].set(arr[i]);
887
888 if (this->is_auto_refresh_write())
889 write();
890 return arr;
891 }
892
893 // overload conversion operator for std::string
894 operator std::string() {
895 std::string s;
896 if (m_tid == TID_KEY)
897 print(s, 0);
898 else
899 get(s); // forward to get(std::string)
900 return s;
901 }
902
903 // overload conversion operator for std::vector<T>
904 template<typename T>
905 operator std::vector<T>() {
907 read();
908 std::vector<T> v(m_num_values);
909 for (int i = 0; i < m_num_values; i++)
910 v[i] = m_data[i];
911 return v;
912 }
913
914 operator std::vector<std::string>() {
916 read();
917 std::vector<std::string> v(m_num_values);
918 for (int i = 0; i < m_num_values; i++)
919 v[i] = m_data[i].get();
920 return v;
921 }
922
923 // overload all other conversion operators
924 template<typename T, typename std::enable_if<
925 std::is_same<T, uint8_t>::value ||
926 std::is_same<T, int8_t>::value ||
927 std::is_same<T, uint16_t>::value ||
928 std::is_same<T, int16_t>::value ||
929 std::is_same<T, uint32_t>::value ||
930 std::is_same<T, int32_t>::value ||
931 std::is_same<T, uint64_t>::value ||
932 std::is_same<T, int64_t>::value ||
933 std::is_same<T, bool>::value ||
934 std::is_same<T, float>::value ||
935 std::is_same<T, double>::value, T>::type * = nullptr>
936 operator T() {
937 if (m_tid == 0)
938 mthrow("Element \"" + m_name + "\" not found");
939 return get<T>(); // forward to get<T>()
940 }
941
942 // overload stream out operator
943 friend std::ostream &operator<<(std::ostream &output, odb &o) {
944 std::string s;
945 if (o.m_tid == TID_KEY)
946 o.print(s, 0);
947 else
948 o.get(s);
949 output << s;
950 return output;
951 };
952
953 // overload index operator for arrays
955 if (this->is_write_protect())
956 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
957
958 if (index < 0)
959 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) + "]\"");
960
961 if (index == 0 && m_num_values == 0) {
962 // initialize this
963 m_num_values = 1;
964 m_tid = 0;
965 m_data = new u_odb[1]{};
966 m_data[0].set_tid(m_tid);
967 m_data[0].set_parent(this);
968 m_last_index = 0;
969 return m_data[0];
970 } else if (index >= m_num_values) {
971 if (is_auto_enlarge_array()) {
973 if (this->is_auto_refresh_write())
974 write(index, 0);
975 } else {
976 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)");
977 }
978 }
979
981 read(index);
982
984 return m_data[index];
985 }
986
987 // overload index operator for subkeys
988 odb &operator[](std::string str) {
989 return get_subkey(str);
990 }
991
992 odb &operator[](const char *str) {
993 return get_subkey(std::string(str));
994 }
995
996 // overload the call operator
997 template <typename T>
999 if (m_tid == 0) {
1000 if (m_num_values == 0) {
1001 // initialize this
1002 m_num_values = 1;
1003 m_tid = detect_type(v);
1004 m_data = new u_odb[1]{};
1005 m_data[0].set_tid(m_tid);
1006 m_data[0].set_parent(this);
1007 m_data[0].set(v);
1008 if (this->is_auto_refresh_write())
1009 write();
1010 } else {
1011 for (int i = 0; i < m_num_values; i++)
1012 m_data[i].set(v);
1013 if (this->is_auto_refresh_write())
1014 write();
1015 }
1016 }
1017 return *this;
1018 }
1019
1020 // indexed access, internal use only
1022 void set_last_index(int i) { m_last_index = i; }
1023
1024 // iterator support
1025 iterator begin() const { return iterator(m_data); }
1026 iterator end() const { return iterator(m_data + m_num_values); }
1027
1028 // overload arithmetic operators
1029 template<typename T>
1031 if (m_num_values > 1)
1032 mthrow("ODB key \"" + get_full_path() +
1033 "\" contains array which cannot be used in basic arithmetic operation.");
1034 if (std::is_same<T, midas::odb>::value) {
1035 if (is_auto_refresh_read()) {
1036 read();
1037 i.read();
1038 }
1039 // adding two midas::odb objects is best done in double
1040 double s1 = static_cast<double>(m_data[0]);
1041 double s2 = static_cast<double>(i.m_data[0]);
1042 return s1 + s2;
1043 } else {
1045 read();
1046 T s = (T) m_data[0];
1047 return s + i;
1048 }
1049 }
1050
1051 template<typename T>
1053 if (m_num_values > 1)
1054 mthrow("ODB key \"" + get_full_path() +
1055 "\" contains array which cannot be used in basic arithmetic operation.");
1056 if (std::is_same<T, midas::odb>::value) {
1057 if (is_auto_refresh_read()) {
1058 read();
1059 i.read();
1060 }
1061 // subtracting two midas::odb objects is best done in double
1062 double s1 = static_cast<double>(m_data[0]);
1063 double s2 = static_cast<double>(i.m_data[0]);
1064 return s1 - s2;
1065 } else {
1067 read();
1068 T s = (T) m_data[0];
1069 return s - i;
1070 }
1071 }
1072
1073 template<typename T>
1074 T operator*(const T i) {
1075 if (m_num_values > 1)
1076 mthrow("ODB key \"" + get_full_path() +
1077 "\" contains array which cannot be used in basic arithmetic operation.");
1079 read();
1080 T s = (T) m_data[0];
1081 return s * i;
1082 }
1083
1084 template<typename T>
1085 T operator/(const T i) {
1086 if (m_num_values > 1)
1087 mthrow("ODB key \"" + get_full_path() +
1088 "\" contains array which cannot be used in basic arithmetic operation.");
1090 read();
1091 T s = (T) m_data[0];
1092 return s / i;
1093 }
1094
1097 read();
1098 for (int i = 0; i < m_num_values; i++)
1099 m_data[i].add(1, false);
1100 if (this->is_auto_refresh_write())
1101 write();
1102 return *this;
1103 }
1104
1106 // create temporary object
1107 odb o(this);
1109 read();
1110 for (int i = 0; i < m_num_values; i++)
1111 m_data[i].add(1, false);
1112 if (this->is_auto_refresh_write())
1113 write();
1114 return o;
1115 }
1116
1119 read();
1120 for (int i = 0; i < m_num_values; i++)
1121 m_data[i].add(-1, false);
1122 if (this->is_auto_refresh_write())
1123 write();
1124 return *this;
1125 }
1126
1128 // create temporary object
1129 odb o(this);
1131 read();
1132 for (int i = 0; i < m_num_values; i++)
1133 m_data[i].add(-1, false);
1134 if (this->is_auto_refresh_write())
1135 write();
1136 return o;
1137 }
1138
1139 odb &operator+=(double d) {
1141 read();
1142 for (int i = 0; i < m_num_values; i++)
1143 m_data[i].add(d, false);
1144 if (this->is_auto_refresh_write())
1145 write();
1146 return *this;
1147 }
1148
1149 odb &operator-=(double d) {
1151 read();
1152 for (int i = 0; i < m_num_values; i++)
1153 m_data[i].add(-d, false);
1154 if (this->is_auto_refresh_write())
1155 write();
1156 return *this;
1157 }
1158
1159 odb &operator*=(double d) {
1161 read();
1162 for (int i = 0; i < m_num_values; i++)
1163 m_data[i].mult(d, false);
1164 if (this->is_auto_refresh_write())
1165 write();
1166 return *this;
1167 }
1168
1169 odb &operator/=(double d) {
1171 read();
1172 if (d == 0)
1173 mthrow("Division by zero");
1174 for (int i = 0; i < m_num_values; i++)
1175 m_data[i].mult(1 / d, false);
1176 if (this->is_auto_refresh_write())
1177 write();
1178 return *this;
1179 }
1180
1181 // overload comparison operators
1182 template<typename T>
1183 friend bool operator==(const midas::odb &o, const T &d);
1184 template<typename T>
1185 friend bool operator==(const T &d, const midas::odb &o);
1186 template<typename T>
1187 friend bool operator!=(const midas::odb &o, const T &d);
1188 template<typename T>
1189 friend bool operator!=(const T &d, const midas::odb &o);
1190 template<typename T>
1191 friend bool operator<(const midas::odb &o, const T &d);
1192 template<typename T>
1193 friend bool operator<(const T &d, const midas::odb &o);
1194 template<typename T>
1195 friend bool operator<=(const midas::odb &o, const T &d);
1196 template<typename T>
1197 friend bool operator<=(const T &d, const midas::odb &o);
1198 template<typename T>
1199 friend bool operator>(const midas::odb &o, const T &d);
1200 template<typename T>
1201 friend bool operator>(const T &d, const midas::odb &o);
1202 template<typename T>
1203 friend bool operator>=(const midas::odb &o, const T &d);
1204 template<typename T>
1205 friend bool operator>=(const T &d, const midas::odb &o);
1206
1207 // create midas::odb object form MXML node
1208 static midas::odb *odb_from_xml(PMXML_NODE node, odb *o) {
1209 std::string type(mxml_get_name(node));
1210
1211 unsigned int tid = 0;
1212 if (type == "dir" || type == "odb")
1213 tid = TID_KEY;
1214 else {
1215 for (tid = 0; tid < TID_LAST; tid++) {
1216 if (equal_ustring(rpc_tid_name(tid), mxml_get_attribute(node, "type")))
1217 break;
1218 }
1219 }
1220 if (tid == TID_LAST)
1221 mthrow("Wrong key type in XML file");
1222
1223 if (o == nullptr)
1224 o = new midas::odb();
1225 o->set_tid(tid);
1226 if (type == "odb") {
1227 o->set_name("root");
1228 o->set_hkey(0);
1229 } else {
1230 o->set_name(mxml_get_attribute(node, "name"));
1231 if (mxml_get_attribute(node, "handle") != nullptr)
1232 o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1233 }
1234
1235 if (type == "key") {
1236 std::string value(mxml_get_value(node));
1237 o->set(value);
1238 } else if (type == "keyarray") {
1239 int n = std::atoi(mxml_get_attribute(node, "num_values"));
1240 o->set_num_values(n);
1241 for (int i=0 ; i<n ; i++) {
1242 std::string value(mxml_get_value(mxml_subnode(node, i)));
1243 o->set(value, i);
1244 }
1245 } else if (type == "dir" || type == "odb") {
1246 int n = mxml_get_number_of_children(node);
1247 o->set_num_values(n);
1248 for (int i = 0; i < n; i++) {
1249 midas::odb *os = odb_from_xml(mxml_subnode(node, i), nullptr);
1250 os->set_parent(o);
1251 o->set_odb(os, i);
1252 }
1253 } else
1254 mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1255
1256 return o;
1257 };
1258
1259 // set midas::odb object form a non-array MJsonNode
1260 static std::string node_to_string(const MJsonNode* node) {
1261 std::string value;
1262
1263 switch (node->GetType()) {
1264 case MJSON_STRING:
1265 value = node->GetString();
1266 break;
1267 case MJSON_INT:
1268 value = std::to_string(node->GetInt());
1269 break;
1270 case MJSON_NUMBER:
1271 value = std::to_string(node->GetDouble());
1272 break;
1273 case MJSON_BOOL:
1274 value = std::to_string(node->GetBool());
1275 break;
1276 default:
1277 mthrow("Invalid MJSON type \"" + std::to_string(node->GetType()) + "\"");
1278 }
1279
1280 return value;
1281 };
1282
1283 // create midas::odb object form MJsonNode
1284 static midas::odb *odb_from_json(const MJsonNode* node, std::string name, int tid, odb *o) {
1285 int type = node->GetType();
1286
1287 if (type == MJSON_OBJECT) { // subdir
1288 const MJsonStringVector* names = node->GetObjectNames();
1289 const MJsonNodeVector* nodes = node->GetObjectNodes();
1290 if (names == nullptr || nodes==nullptr || names->size() != nodes->size())
1291 mthrow("Invalid JSON format");
1292
1293 if (o == nullptr)
1294 o = new midas::odb();
1295 o->set_tid(TID_KEY);
1296 o->set_name(name);
1297 o->set_hkey(0);
1298
1299 // count subkeys
1300 int n=0;
1301 for (int i=0 ; i<(int)names->size() ; i++) {
1302 const char *name = (*names)[i].c_str();
1303
1304 if (strchr(name, '/'))// skip special entries
1305 continue;
1306 n++;
1307 }
1308 o->set_num_values(n);
1309
1310 for (int i=n=0 ; i<(int)names->size() ; i++) {
1311 const char *name = (*names)[i].c_str();
1312
1313 if (strchr(name, '/'))// skip special entries
1314 continue;
1315
1316 int t = 0;
1317 auto key = node->FindObjectNode((std::string(name) + "/key").c_str());
1318 if (key)
1319 t = key->FindObjectNode("type")->GetInt();
1320 else
1321 t = TID_KEY;
1322
1323 midas::odb *os = odb_from_json((*nodes)[i], (*names)[i].c_str(), t, nullptr);
1324 os->set_parent(o);
1325 o->set_odb(os, n);
1326 n++;
1327 }
1328
1329 o->set_num_values(n);
1330
1331 } else { // key
1332
1333 if (o == nullptr)
1334 o = new midas::odb();
1335
1336 o->set_name(name);
1337 o->set_tid(tid);
1338 o->set_hkey(0);
1339
1340 if (node->GetType() == MJSON_ARRAY) {
1341 const MJsonNodeVector* a = node->GetArray();
1342 o->set_num_values(a->size());
1343 for (int i=0 ; i<(int)a->size() ; i++) {
1344 MJsonNode *n = (*a)[i];
1345 auto value = node_to_string(n);
1346 o->set(value, i);
1347 }
1348 } else {
1349 auto value = node_to_string(node);
1350 o->set(value);
1351 }
1352 }
1353
1354 return o;
1355 };
1356
1357 // Deep copy
1358 void deep_copy(odb &d, const odb &s);
1359
1360 // Setters and Getters
1366
1372
1378
1379 bool is_dirty() const { return m_flags[odb_flags::DIRTY]; }
1380 void set_dirty(bool f) { m_flags[odb_flags::DIRTY] = f; }
1381
1387
1393
1399
1405
1406 // Static functions
1407 static void set_debug(bool flag) { s_debug = flag; }
1408 static bool get_debug() { return s_debug; }
1409 static int create(const char *name, int type = TID_KEY);
1410 static bool exists(const std::string &name);
1411 static int delete_key(const std::string &name);
1412 static void load(const std::string &filename, const std::string &odb_path);
1413
1414 void odb_from_xml_remote(const std::string &str);
1415 void odb_from_xml_string(const std::string &str, const std::string &subkey);
1416 void odb_from_json_string(const std::string &str, const std::string &subkey);
1417 void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults = false);
1418 void connect(std::string str, bool write_defaults = false, bool delete_keys_not_in_defaults = false);
1419 void connect_and_fix_structure(std::string path);
1420
1423 if (s == STRING)
1424 mthrow1("ODB source STRING requires a string");
1425 if (s == FILE)
1426 mthrow1("ODB source FILE requires a filename");
1427 s_odb_source = s;
1428 }
1429
1430 static void set_odb_source(odb::odb_source s, std::string str);
1431 static void odb_from_xml_string(const std::string &str);
1432 static void odb_from_json_string(const std::string &str);
1433
1434 static bool is_connected_odb() { return s_connected_odb; }
1435
1436 void read();
1437 void read(int index);
1438 void write(int str_size = 0);
1439 void write(int index, int str_size);
1440 std::string print();
1441 std::string dump();
1442 void print(std::string &s, int indent=0);
1443 void dump(std::string &s, int indent=0);
1444 void save(const std::string &filename);
1445 void delete_key();
1446 int size();
1447 void resize(int size);
1448 void resize(int size, bool b);
1449 void watch(std::function<void(midas::odb &)> f);
1450 void unwatch();
1451 void set(std::string str);
1452 void set(std::string s, int i);
1453 void set_odb(odb *o, int i);
1454 void set_string_size(std::string s, int size);
1455
1456 bool is_subkey(std::string str);
1457 HNDLE get_hkey() { return m_hKey; }
1458 std::string get_full_path();
1459 std::string get_parent_path();
1460 int get_tid() { return m_tid; }
1462 std::string get_name() { return m_name; }
1463 odb& items() { return *this; }
1464
1465 std::string s() {
1466 std::string s;
1467 get(s);
1468 return s;
1469 }
1470
1471 void fix_order(std::vector<std::string> target_subkey_order);
1472
1473 void set_mode(int mode);
1474 int get_mode();
1475
1476 unsigned int get_last_written();
1477 };
1478
1479 //---- midas::odb friend functions -------------------------------
1480
1481 // overload comparison operators
1482 template<typename T>
1483 bool operator==(const midas::odb &o, const T &d) {
1484 // the operator needs a "const midas::odb" reference,
1485 // so we have to make a non-const copy
1486 T v;
1487 midas::odb oc(o);
1488 oc.get(v);
1489 return v == d;
1490 }
1491
1492 template<typename T>
1493 bool operator==(const T &d, const midas::odb &o) {
1494 T v;
1495 midas::odb oc(o);
1496 oc.get(v);
1497 return d == v;
1498 }
1499
1500 template<typename T>
1501 bool operator!=(const midas::odb &o, const T &d) {
1502 T v;
1503 midas::odb oc(o);
1504 oc.get(v);
1505 return v != d;
1506 }
1507
1508 template<typename T>
1509 bool operator!=(const T &d, const midas::odb &o) {
1510 T v;
1511 midas::odb oc(o);
1512 oc.get(v);
1513 return d != v;
1514 }
1515
1516 template<typename T>
1517 bool operator<(const midas::odb &o, const T &d) {
1518 T v;
1519 midas::odb oc(o);
1520 oc.get(v);
1521 return v < d;
1522 }
1523
1524 template<typename T>
1525 bool operator<(const T &d, const midas::odb &o) {
1526 T v;
1527 midas::odb oc(o);
1528 oc.get(v);
1529 return d < v;
1530 }
1531
1532 template<typename T>
1533 bool operator<=(const midas::odb &o, const T &d) {
1534 T v;
1535 midas::odb oc(o);
1536 oc.get(v);
1537 return v <= d;
1538 }
1539
1540 template<typename T>
1541 bool operator<=(const T &d, const midas::odb &o) {
1542 T v;
1543 midas::odb oc(o);
1544 oc.get(v);
1545 return d <= v;
1546 }
1547
1548 template<typename T>
1549 bool operator>(const midas::odb &o, const T &d) {
1550 T v;
1551 midas::odb oc(o);
1552 oc.get(v);
1553 return v > d;
1554 }
1555
1556 template<typename T>
1557 bool operator>(const T &d, const midas::odb &o) {
1558 T v;
1559 midas::odb oc(o);
1560 oc.get(v);
1561 return d > v;
1562 }
1563
1564 template<typename T>
1565 bool operator>=(const midas::odb &o, const T &d) {
1566 T v;
1567 midas::odb oc(o);
1568 oc.get(v);
1569 return v >= d;
1570 }
1571
1572 template<typename T>
1573 bool operator>=(const T &d, const midas::odb &o) {
1574 T v;
1575 midas::odb oc(o);
1576 oc.get(v);
1577 return d >= v;
1578 }
1579
1580} // namespace midas
1581
1582
1583#endif // _ODBXX_HXX
iterator operator++()
Definition odbxx.h:430
iterator operator++(int)
Definition odbxx.h:436
iterator(u_odb *pu)
Definition odbxx.h:427
u_odb & operator*()
Definition odbxx.h:444
bool operator!=(const iterator &other) const
Definition odbxx.h:442
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1627
std::string get_parent_path()
Definition odbxx.cxx:378
odb operator=(odb &&o)=delete
odb(std::initializer_list< T > list)
Definition odbxx.h:615
odb & operator*=(double d)
Definition odbxx.h:1159
std::string get_full_path()
Definition odbxx.cxx:362
void set(std::string str)
Definition odbxx.cxx:1597
static std::string node_to_string(const MJsonNode *node)
Definition odbxx.h:1260
int m_num_values
Definition odbxx.h:475
iterator end() const
Definition odbxx.h:1026
static bool exists(const std::string &name)
Definition odbxx.cxx:76
midas::odb * get_parent()
Definition odbxx.h:546
odb & operator+=(double d)
Definition odbxx.h:1139
std::string get_name()
Definition odbxx.h:1462
int m_tid
Definition odbxx.h:469
void set_mode(int mode)
Definition odbxx.cxx:1515
void set_auto_refresh_read(bool f)
Definition odbxx.h:1368
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1389
odb(const std::array< T, SIZE > &arr)
Definition odbxx.h:631
void delete_key()
Definition odbxx.cxx:1486
void set_odb(odb *o, int i)
Definition odbxx.cxx:1641
u_odb * m_data
Definition odbxx.h:471
void deep_copy(odb &d, const odb &s)
Definition odbxx.cxx:334
bool is_deleted() const
Definition odbxx.h:537
static void set_debug(bool flag)
Definition odbxx.h:1407
static midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
Definition odbxx.h:1208
odb & operator++()
Definition odbxx.h:1095
bool is_auto_refresh_read() const
Definition odbxx.h:1367
static void unwatch_all()
Definition odbxx.cxx:1588
static HNDLE s_hDB
Definition odbxx.h:458
HNDLE get_hkey()
Definition odbxx.h:1457
static void set_odb_source(odb::odb_source s)
Definition odbxx.h:1422
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:481
bool is_auto_create() const
Definition odbxx.h:1382
bool is_preserve_string_size() const
Definition odbxx.h:1361
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:645
void unwatch()
Definition odbxx.cxx:1576
T operator+(T i)
Definition odbxx.h:1030
u_odb & operator[](int index)
Definition odbxx.h:954
T get()
Definition odbxx.h:501
odb(std::initializer_list< std::pair< const char *, midas::odb > > list)
Definition odbxx.h:586
int get_tid()
Definition odbxx.h:1460
static midas::odb * odb_from_json(const MJsonNode *node, std::string name, int tid, odb *o)
Definition odbxx.h:1284
static bool get_debug()
Definition odbxx.h:1408
bool is_auto_refresh_write() const
Definition odbxx.h:1373
u_odb & get_mdata(int index=0)
Definition odbxx.h:525
friend bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1483
void set_tid(int tid)
Definition odbxx.h:540
odb & operator[](const char *str)
Definition odbxx.h:992
bool read_key(const std::string &path)
Definition odbxx.cxx:657
friend bool operator>=(const midas::odb &o, const T &d)
Definition odbxx.h:1565
friend bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1533
friend bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1517
void resize(int size)
Definition odbxx.cxx:391
T operator/(const T i)
Definition odbxx.h:1085
void set_preserve_string_size(bool f)
Definition odbxx.h:1362
static thread_local odb_source s_odb_source
Definition odbxx.h:453
void set_trigger_hotlink(bool f)
Definition odbxx.h:1401
odb(T v)
Definition odbxx.h:578
int size()
Definition odbxx.cxx:386
void set_flags(uint32_t f)
Definition odbxx.h:534
void set_auto_refresh_write(bool f)
Definition odbxx.h:1374
int get_mode()
Definition odbxx.cxx:1532
odb & operator--()
Definition odbxx.h:1117
void odb_from_xml_remote(const std::string &str)
Definition odbxx.cxx:160
void set_auto_create(bool f)
Definition odbxx.h:1383
static thread_local std::string s_odb_source_str
Definition odbxx.h:454
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:1421
friend bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1549
bool is_dirty() const
Definition odbxx.h:1379
const std::vector< T > & operator=(const std::vector< T > &v)
Definition odbxx.h:816
iterator begin() const
Definition odbxx.h:1025
const T & operator=(const T &v)
Definition odbxx.h:789
odb & get_subkey(std::string str)
Definition odbxx.cxx:568
odb & operator()(T v)
Definition odbxx.h:998
void set_hkey(HNDLE hKey)
Definition odbxx.h:532
odb & operator/=(double d)
Definition odbxx.h:1169
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:1546
odb operator--(int)
Definition odbxx.h:1127
void set_name(std::string s)
Definition odbxx.h:543
int get_subkeys(std::vector< std::string > &name)
Definition odbxx.cxx:632
void watch(std::function< void(midas::odb &)> f)
Definition odbxx.cxx:1560
static thread_local odb * s_odb
Definition odbxx.h:456
odb(const char *s)
Definition odbxx.h:734
int get_last_index()
Definition odbxx.h:1021
std::string s()
Definition odbxx.h:1465
friend std::ostream & operator<<(std::ostream &output, odb &o)
Definition odbxx.h:943
bool is_auto_enlarge_array() const
Definition odbxx.h:1388
friend bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1501
int detect_type(const T &)
Definition odbxx.h:752
void save(const std::string &filename)
Definition odbxx.cxx:518
void set_last_index(int i)
Definition odbxx.h:1022
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:460
void fix_order(std::vector< std::string > target_subkey_order)
Definition odbxx.cxx:1327
odb(const std::string &path, bool init_via_xml=false)
Definition odbxx.h:659
std::string dump()
Definition odbxx.cxx:427
int m_last_index
Definition odbxx.h:477
odb operator++(int)
Definition odbxx.h:1105
void connect_and_fix_structure(std::string path)
Definition odbxx.cxx:1472
static bool s_connected_odb
Definition odbxx.h:462
const std::array< T, SIZE > & operator=(const std::array< T, SIZE > &arr)
Definition odbxx.h:862
static void init_hdb()
Definition odbxx.cxx:50
int get_num_values()
Definition odbxx.h:1461
operator std::string()
Definition odbxx.h:894
odb & operator-=(double d)
Definition odbxx.h:1149
void set_num_values(int n)
Definition odbxx.h:541
uint32_t get_flags()
Definition odbxx.h:535
bool is_trigger_hotlink() const
Definition odbxx.h:1400
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:1434
odb(std::initializer_list< const char * > list)
Definition odbxx.h:738
std::bitset< 9 > m_flags
Definition odbxx.h:467
static std::vector< midas::odb > m_watch
Definition odbxx.h:464
odb & operator[](std::string str)
Definition odbxx.h:988
void set_deleted(bool f)
Definition odbxx.h:538
static void load(const std::string &filename, const std::string &odb_path)
Definition odbxx.cxx:102
int write_string_array(int str_size)
Definition odbxx.cxx:1012
void set_parent(midas::odb *p)
Definition odbxx.h:545
HNDLE m_hKey
Definition odbxx.h:479
T operator-(T i)
Definition odbxx.h:1052
void set_write_protect(bool f)
Definition odbxx.h:1395
std::string m_name
Definition odbxx.h:473
void get(T &v)
Definition odbxx.h:513
bool is_write_protect() const
Definition odbxx.h:1394
T operator*(const T i)
Definition odbxx.h:1074
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
Definition odbxx.cxx:1390
odb & items()
Definition odbxx.h:1463
void set_dirty(bool f)
Definition odbxx.h:1380
midas::odb * m_parent
Definition odbxx.h:483
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:1752
void set_tid(int tid)
Definition odbxx.h:105
void mult(double f, bool push=true)
Definition odbxx.cxx:1980
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:388
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:375
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1867
int16_t m_int16
Definition odbxx.h:55
u_odb & operator--()
Definition odbxx.h:257
odb & get_odb()
Definition odbxx.h:381
u_odb & operator-=(double d)
Definition odbxx.h:267
std::string s()
Definition odbxx.h:367
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
size_t string_size() const
Definition odbxx.h:360
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_CHAR
Definition midas.h:331
#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:3780
const char * rpc_tid_name(INT id)
Definition midas.cxx:11997
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:1565
bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1549
bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1483
bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1517
odb_flags
Definition odbxx.h:399
@ AUTO_REFRESH_WRITE
Definition odbxx.h:401
@ DIRTY
Definition odbxx.h:405
@ TRIGGER_HOTLINK
Definition odbxx.h:408
@ AUTO_REFRESH_READ
Definition odbxx.h:400
@ WRITE_PROTECT
Definition odbxx.h:407
@ AUTO_ENLARGE_ARRAY
Definition odbxx.h:404
@ AUTO_CREATE
Definition odbxx.h:403
@ PRESERVE_STRING_SIZE
Definition odbxx.h:402
@ DELETED
Definition odbxx.h:406
bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1533
bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1501
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