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 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
498 // get function for basic types
499 template<typename T>
500 T get() {
501 if (m_num_values > 1)
502 mthrow("ODB key \"" + get_full_path() +
503 "[0..." + std::to_string(m_num_values - 1) +
504 "]\" contains array. Please assign to std::vector.");
506 read();
507 return (T) m_data[0];
508 }
509
510 // get function for basic types as a parameter
511 template<typename T>
512 void get(T &v) {
513 if (m_num_values > 1)
514 mthrow("ODB key \"" + get_full_path() + "\" contains array. Please assign to std::vector.");
516 read();
517 v = (T) m_data[0];
518 }
519
520 // get function for strings
521 void get(std::string &s, bool quotes = false, bool refresh = true);
522
523 // return internal data
524 u_odb &get_mdata(int index = 0) { return m_data[index]; }
525
526 odb &get_subkey(std::string str);
527 int get_subkeys(std::vector<std::string> &name);
528 bool read_key(const std::string &path);
529 bool write_key(std::string &path, bool write_defaults);
530
532
533 void set_flags(uint32_t f) { m_flags = f; }
534 uint32_t get_flags() { return static_cast<uint32_t>(m_flags.to_ulong()); }
535
536 bool is_deleted() const { return m_flags[odb_flags::DELETED]; }
538
539 void set_tid(int tid) { m_tid = tid; }
541
542 void set_name(std::string s) { m_name = s; }
543
546
547 public:
548
549 // Default constructor
550 odb() :
554 (1 << odb_flags::AUTO_CREATE) |
555 (1 << odb_flags::TRIGGER_HOTLINK)},
556 m_tid{0},
557 m_data{nullptr},
558 m_name{},
559 m_num_values{0},
560 m_last_index{-1},
561 m_hKey{},
562 m_parent{} {}
563
564 // Destructor
566 delete[] m_data;
567 }
568
569 // Deep copy constructor
570 odb(const odb &o);
571
572 // Delete shallow assignment operator
573 odb operator=(odb &&o) = delete;
574
575 // Constructor for single basic types
576 template<typename T>
577 odb(T v):odb() {
578 m_num_values = 1;
579 m_data = new u_odb[1]{v};
580 m_tid = m_data[0].get_tid();
581 m_data[0].set_parent(this);
582 }
583
584 // Constructor with std::initializer_list
585 odb(std::initializer_list<std::pair<const char *, midas::odb>> list) : odb() {
586 m_tid = TID_KEY;
587 m_num_values = list.size();
589 int i = 0;
590 for (auto &element: list) {
591 // check if name exists already
592 for (int j=0 ; j<i ; j++) {
593 if (strcasecmp(element.first, m_data[j].get_odb().get_name().c_str()) == 0) {
594 if (element.first == m_data[j].get_odb().get_name()) {
595 mthrow("ODB key with name \"" + m_data[j].get_odb().get_name() + "\" exists already");
596 } else {
597 mthrow("ODB key \"" + std::string(element.first) + "\" exists already as \"" +
598 m_data[j].get_odb().get_name() + "\" (only case differs)");
599 }
600 }
601 }
602 auto o = new midas::odb(element.second);
603 o->set_name(element.first);
604 o->set_parent(this);
606 m_data[i].set_parent(this);
607 m_data[i].set(o);
608 i++;
609 }
610 }
611
612 // Constructor with basic type array
613 template<typename T>
614 odb(std::initializer_list<T> list) : odb() {
615 m_num_values = list.size();
616 m_data = new u_odb[m_num_values]{};
617 int i = 0;
618 for (auto &element : list) {
619 u_odb u(element);
620 m_data[i].set_tid(u.get_tid());
621 m_data[i].set_parent(this);
623 i++;
624 }
625 m_tid = m_data[0].get_tid();
626 }
627
628 // Constructor with basic explicit array
629 template<typename T, size_t SIZE>
630 odb(const std::array<T, SIZE> &arr) : odb() {
632 m_data = new u_odb[m_num_values]{};
633 for (int i = 0; i < (int)SIZE; i++) {
634 u_odb u(arr[i]);
635 m_data[i].set_tid(u.get_tid());
636 m_data[i].set_parent(this);
637 m_data[i].set(arr[i]);
638 }
639 m_tid = m_data[0].get_tid();
640 }
641
642 // Constructor with explicit array of std::string
643 template<size_t SIZE>
644 odb(const std::array<std::string, SIZE> &arr) : odb() {
646 m_data = new u_odb[m_num_values]{};
647 for (int i = 0; i < (int)SIZE; i++) {
648 std::string * mystring = new std::string(arr[i]);
649 u_odb u(mystring);
650 m_data[i].set_tid(u.get_tid());
651 m_data[i].set_parent(this);
652 m_data[i].set(arr[i]);
653 }
654 m_tid = m_data[0].get_tid();
655 }
656
657 // Constructor for std::string
658 odb(const std::string &path, bool init_via_xml = false) : odb() {
659 if (path[0] == '/') {
660 // ODB path
661 if (s_odb_source == ONLINE) {
662 if (init_via_xml) {
663 if (!exists(path))
664 odb::create(path.c_str(), TID_KEY);
666 } else {
667 if (!read_key(path))
668 // create subdir if key does not exist
669 odb::create(path.c_str(), TID_KEY);
670
671 if (!read_key(path))
672 mthrow("ODB key \"" + path + "\" not found in ODB");
673
674 if (m_tid != TID_KEY)
675 read();
676 }
677 } else if (s_odb_source == STRING || s_odb_source == FILE) {
678
679 // split path
680 std::stringstream ss(path.substr(1));
681 std::string item;
682 std::vector<std::string> arr;
683 while (std::getline(ss, item, '/'))
684 arr.push_back(item);
685
686 // extract subkey from root odb
687 odb *o = s_odb;
688 for (size_t i = 0; i < arr.size(); i++)
689 o = &(*o)[arr[i]];
690
691 // do a deep copy from "o" to "this"
692 m_tid = o->m_tid;
693 m_tid = o->m_tid;
694 m_name = o->m_name;
696 m_hKey = o->m_hKey;
699 for (int i = 0; i < m_num_values; i++) {
701 m_data[i].set_parent(this);
702 if (m_tid == TID_STRING || m_tid == TID_LINK) {
703 // set_string() creates a copy of our string
704 m_data[i].set_string(o->m_data[i]);
705 } else if (m_tid == TID_KEY) {
706 // recursive call to create a copy of the odb object
707 auto *po= o->m_data[i].get_podb();
708 auto *pc = new midas::odb(*po);
709 pc->set_parent(this);
710 m_data[i].set(pc);
711 } else {
712 // simply pass basic types
713 m_data[i] = o->m_data[i];
714 m_data[i].set_parent(this);
715 }
716 }
717
718 } else
719 mthrow("Unknown ODB source: " + std::to_string(s_odb_source));
720
721 } else {
722 // simple string
723
724 // Construct object from initializer_list
725 m_num_values = 1;
726 m_data = new u_odb[1]{new std::string{path}};
727 m_tid = m_data[0].get_tid();
728 m_data[0].set_parent(this);
729 }
730 }
731
732 // Constructor for C string
733 odb(const char *s) : odb(std::string(s)) {
734 }
735
736 // Constructor with const char * array
737 odb(std::initializer_list<const char *> list) : odb() {
738 m_num_values = list.size();
739 m_data = new u_odb[m_num_values]{};
740 int i = 0;
741 for (auto &element : list) {
743 m_data[i].set_parent(this);
745 i++;
746 }
747 m_tid = m_data[0].get_tid();
748 }
749
750 template<typename T>
751 int detect_type(const T &) {
752 if (std::is_same<T, uint8_t>::value)
753 return TID_UINT8;
754 else if (std::is_same<T, int8_t>::value)
755 return TID_INT8;
756 else if (std::is_same<T, uint16_t>::value)
757 return TID_UINT16;
758 else if (std::is_same<T, int16_t>::value)
759 return TID_INT16;
760 else if (std::is_same<T, uint32_t>::value)
761 return TID_UINT32;
762 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
763 return TID_UINT32;
764 else if (std::is_same<T, int32_t>::value)
765 return TID_INT32;
766 else if (std::is_same<T, long>::value && sizeof(long) == 4)
767 return TID_INT32;
768 else if (std::is_same<T, uint64_t>::value)
769 return TID_UINT64;
770 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
771 return TID_UINT64;
772 else if (std::is_same<T, int64_t>::value)
773 return TID_INT64;
774 else if (std::is_same<T, long>::value && sizeof(long) == 8)
775 return TID_INT64;
776 else if (std::is_same<T, bool>::value)
777 return TID_BOOL;
778 else if (std::is_same<T, float>::value)
779 return TID_FLOAT;
780 else if (std::is_same<T, double>::value)
781 return TID_DOUBLE;
782 else
783 return TID_STRING;
784 }
785
786 // Overload the Assignment Operators
787 template<typename T>
788 const T &operator=(const T &v) {
789
790 if (this->is_write_protect())
791 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
792
793 if (m_num_values == 0) {
794 // initialize this
795 m_num_values = 1;
796 m_tid = detect_type(v);
797 m_data = new u_odb[1]{};
798 m_data[0].set_tid(m_tid);
799 m_data[0].set_parent(this);
800 m_data[0].set(v);
801 if (this->is_auto_refresh_write())
802 write();
803 } else {
804 for (int i = 0; i < m_num_values; i++)
805 m_data[i].set(v);
806
807 if (this->is_auto_refresh_write())
808 write();
809 }
810 return v;
811 }
812
813 // Overload the Assignment Operators for std::vector
814 template<typename T>
815 const std::vector<T> &operator=(const std::vector<T> &v) {
816
817 if (this->is_write_protect())
818 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
819
820 if (m_num_values == 0) {
821 // initialize this
822 m_num_values = v.size();
823 if (std::is_same<T, bool>::value) {
824 // Special logic for vector<bool>, which may not be a true
825 // container: it's often optimized to be a bitfield, with
826 // references to elements being masked bits rather than bools.
827 // So T is a bool here, but typeof(v[0]) may not be bool!
828 // "Fake container optimization" only applies to vector<bool>,
829 // not array<bool> or any other vector<T>.
830 m_tid = TID_BOOL;
831 } else {
832 // Every other type can be detected using ref to first element.
833 m_tid = detect_type(v[0]);
834 }
835
836 m_data = new u_odb[m_num_values]{};
837 for (int i = 0; i < m_num_values; i++) {
839 m_data[i].set_parent(this);
840 }
841
842 } else {
843
844 // resize internal array if different
845 if ((int)v.size() != m_num_values) {
846 resize_mdata(v.size());
847 }
848 }
849
850 for (int i = 0; i < m_num_values; i++)
851 m_data[i].set(v[i]);
852
853 if (this->is_auto_refresh_write())
854 write();
855
856 return v;
857 }
858
859 // Overload the Assignment Operators for std::array
860 template<typename T, size_t SIZE>
861 const std::array<T, SIZE> &operator=(const std::array<T, SIZE> &arr) {
862
863 if (this->is_write_protect())
864 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
865
866 if (m_num_values == 0) {
867 // initialize this
869 m_tid = detect_type(arr[0]);
870 m_data = new u_odb[m_num_values]{};
871 for (int i = 0; i < m_num_values; i++) {
873 m_data[i].set_parent(this);
874 }
875
876 } else {
877
878 // resize internal array if different
879 if (SIZE != m_num_values) {
881 }
882 }
883
884 for (int i = 0; i < m_num_values; i++)
885 m_data[i].set(arr[i]);
886
887 if (this->is_auto_refresh_write())
888 write();
889 return arr;
890 }
891
892 // overload conversion operator for std::string
893 operator std::string() {
894 std::string s;
895 if (m_tid == TID_KEY)
896 print(s, 0);
897 else
898 get(s); // forward to get(std::string)
899 return s;
900 }
901
902 // overload conversion operator for std::vector<T>
903 template<typename T>
904 operator std::vector<T>() {
906 read();
907 std::vector<T> v(m_num_values);
908 for (int i = 0; i < m_num_values; i++)
909 v[i] = m_data[i];
910 return v;
911 }
912
913 operator std::vector<std::string>() {
915 read();
916 std::vector<std::string> v(m_num_values);
917 for (int i = 0; i < m_num_values; i++)
918 v[i] = m_data[i].get();
919 return v;
920 }
921
922 // overload all other conversion operators
923 template<typename T, typename std::enable_if<
924 std::is_same<T, uint8_t>::value ||
925 std::is_same<T, int8_t>::value ||
926 std::is_same<T, uint16_t>::value ||
927 std::is_same<T, int16_t>::value ||
928 std::is_same<T, uint32_t>::value ||
929 std::is_same<T, int32_t>::value ||
930 std::is_same<T, uint64_t>::value ||
931 std::is_same<T, int64_t>::value ||
932 std::is_same<T, bool>::value ||
933 std::is_same<T, float>::value ||
934 std::is_same<T, double>::value, T>::type * = nullptr>
935 operator T() {
936 if (m_tid == 0)
937 mthrow("Element \"" + m_name + "\" not found");
938 return get<T>(); // forward to get<T>()
939 }
940
941 // overload stream out operator
942 friend std::ostream &operator<<(std::ostream &output, odb &o) {
943 std::string s;
944 if (o.m_tid == TID_KEY)
945 o.print(s, 0);
946 else
947 o.get(s);
948 output << s;
949 return output;
950 };
951
952 // overload index operator for arrays
954 if (this->is_write_protect())
955 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
956
957 if (index < 0)
958 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) + "]\"");
959
960 if (index == 0 && m_num_values == 0) {
961 // initialize this
962 m_num_values = 1;
963 m_tid = 0;
964 m_data = new u_odb[1]{};
965 m_data[0].set_tid(m_tid);
966 m_data[0].set_parent(this);
967 m_last_index = 0;
968 return m_data[0];
969 } else if (index >= m_num_values) {
970 if (is_auto_enlarge_array()) {
972 if (this->is_auto_refresh_write())
973 write(index, 0);
974 } else {
975 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)");
976 }
977 }
978
980 read(index);
981
983 return m_data[index];
984 }
985
986 // overload index operator for subkeys
987 odb &operator[](std::string str) {
988 return get_subkey(str);
989 }
990
991 odb &operator[](const char *str) {
992 return get_subkey(std::string(str));
993 }
994
995 // overload the call operator
996 template <typename T>
998 if (m_tid == 0) {
999 if (m_num_values == 0) {
1000 // initialize this
1001 m_num_values = 1;
1002 m_tid = detect_type(v);
1003 m_data = new u_odb[1]{};
1004 m_data[0].set_tid(m_tid);
1005 m_data[0].set_parent(this);
1006 m_data[0].set(v);
1007 if (this->is_auto_refresh_write())
1008 write();
1009 } else {
1010 for (int i = 0; i < m_num_values; i++)
1011 m_data[i].set(v);
1012 if (this->is_auto_refresh_write())
1013 write();
1014 }
1015 }
1016 return *this;
1017 }
1018
1019 // indexed access, internal use only
1021 void set_last_index(int i) { m_last_index = i; }
1022
1023 // iterator support
1024 iterator begin() const { return iterator(m_data); }
1025 iterator end() const { return iterator(m_data + m_num_values); }
1026
1027 // overload arithmetic operators
1028 template<typename T>
1030 if (m_num_values > 1)
1031 mthrow("ODB key \"" + get_full_path() +
1032 "\" contains array which cannot be used in basic arithmetic operation.");
1033 if (std::is_same<T, midas::odb>::value) {
1034 if (is_auto_refresh_read()) {
1035 read();
1036 i.read();
1037 }
1038 // adding two midas::odb objects is best done in double
1039 double s1 = static_cast<double>(m_data[0]);
1040 double s2 = static_cast<double>(i.m_data[0]);
1041 return s1 + s2;
1042 } else {
1044 read();
1045 T s = (T) m_data[0];
1046 return s + i;
1047 }
1048 }
1049
1050 template<typename T>
1052 if (m_num_values > 1)
1053 mthrow("ODB key \"" + get_full_path() +
1054 "\" contains array which cannot be used in basic arithmetic operation.");
1055 if (std::is_same<T, midas::odb>::value) {
1056 if (is_auto_refresh_read()) {
1057 read();
1058 i.read();
1059 }
1060 // subtracting two midas::odb objects is best done in double
1061 double s1 = static_cast<double>(m_data[0]);
1062 double s2 = static_cast<double>(i.m_data[0]);
1063 return s1 - s2;
1064 } else {
1066 read();
1067 T s = (T) m_data[0];
1068 return s - i;
1069 }
1070 }
1071
1072 template<typename T>
1073 T operator*(const T i) {
1074 if (m_num_values > 1)
1075 mthrow("ODB key \"" + get_full_path() +
1076 "\" contains array which cannot be used in basic arithmetic operation.");
1078 read();
1079 T s = (T) m_data[0];
1080 return s * i;
1081 }
1082
1083 template<typename T>
1084 T operator/(const T i) {
1085 if (m_num_values > 1)
1086 mthrow("ODB key \"" + get_full_path() +
1087 "\" contains array which cannot be used in basic arithmetic operation.");
1089 read();
1090 T s = (T) m_data[0];
1091 return s / i;
1092 }
1093
1096 read();
1097 for (int i = 0; i < m_num_values; i++)
1098 m_data[i].add(1, false);
1099 if (this->is_auto_refresh_write())
1100 write();
1101 return *this;
1102 }
1103
1105 // create temporary object
1106 odb o(this);
1108 read();
1109 for (int i = 0; i < m_num_values; i++)
1110 m_data[i].add(1, false);
1111 if (this->is_auto_refresh_write())
1112 write();
1113 return o;
1114 }
1115
1118 read();
1119 for (int i = 0; i < m_num_values; i++)
1120 m_data[i].add(-1, false);
1121 if (this->is_auto_refresh_write())
1122 write();
1123 return *this;
1124 }
1125
1127 // create temporary object
1128 odb o(this);
1130 read();
1131 for (int i = 0; i < m_num_values; i++)
1132 m_data[i].add(-1, false);
1133 if (this->is_auto_refresh_write())
1134 write();
1135 return o;
1136 }
1137
1138 odb &operator+=(double d) {
1140 read();
1141 for (int i = 0; i < m_num_values; i++)
1142 m_data[i].add(d, false);
1143 if (this->is_auto_refresh_write())
1144 write();
1145 return *this;
1146 }
1147
1148 odb &operator-=(double d) {
1150 read();
1151 for (int i = 0; i < m_num_values; i++)
1152 m_data[i].add(-d, false);
1153 if (this->is_auto_refresh_write())
1154 write();
1155 return *this;
1156 }
1157
1158 odb &operator*=(double d) {
1160 read();
1161 for (int i = 0; i < m_num_values; i++)
1162 m_data[i].mult(d, false);
1163 if (this->is_auto_refresh_write())
1164 write();
1165 return *this;
1166 }
1167
1168 odb &operator/=(double d) {
1170 read();
1171 if (d == 0)
1172 mthrow("Division by zero");
1173 for (int i = 0; i < m_num_values; i++)
1174 m_data[i].mult(1 / d, false);
1175 if (this->is_auto_refresh_write())
1176 write();
1177 return *this;
1178 }
1179
1180 // overload comparison operators
1181 template<typename T>
1182 friend bool operator==(const midas::odb &o, const T &d);
1183 template<typename T>
1184 friend bool operator==(const T &d, const midas::odb &o);
1185 template<typename T>
1186 friend bool operator!=(const midas::odb &o, const T &d);
1187 template<typename T>
1188 friend bool operator!=(const T &d, const midas::odb &o);
1189 template<typename T>
1190 friend bool operator<(const midas::odb &o, const T &d);
1191 template<typename T>
1192 friend bool operator<(const T &d, const midas::odb &o);
1193 template<typename T>
1194 friend bool operator<=(const midas::odb &o, const T &d);
1195 template<typename T>
1196 friend bool operator<=(const T &d, const midas::odb &o);
1197 template<typename T>
1198 friend bool operator>(const midas::odb &o, const T &d);
1199 template<typename T>
1200 friend bool operator>(const T &d, const midas::odb &o);
1201 template<typename T>
1202 friend bool operator>=(const midas::odb &o, const T &d);
1203 template<typename T>
1204 friend bool operator>=(const T &d, const midas::odb &o);
1205
1206 // create midas::odb object form MXML node
1207 static midas::odb *odb_from_xml(PMXML_NODE node, odb *o) {
1208 std::string type(mxml_get_name(node));
1209
1210 unsigned int tid = 0;
1211 if (type == "dir" || type == "odb")
1212 tid = TID_KEY;
1213 else {
1214 for (tid = 0; tid < TID_LAST; tid++) {
1215 if (equal_ustring(rpc_tid_name(tid), mxml_get_attribute(node, "type")))
1216 break;
1217 }
1218 }
1219 if (tid == TID_LAST)
1220 mthrow("Wrong key type in XML file");
1221
1222 if (o == nullptr)
1223 o = new midas::odb();
1224 o->set_tid(tid);
1225 if (type == "odb") {
1226 o->set_name("root");
1227 o->set_hkey(0);
1228 } else {
1229 o->set_name(mxml_get_attribute(node, "name"));
1230 if (mxml_get_attribute(node, "handle") == nullptr)
1231 mthrow("No \"handle\" attribute found in XML data");
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:1614
std::string get_parent_path()
Definition odbxx.cxx:378
odb operator=(odb &&o)=delete
odb(std::initializer_list< T > list)
Definition odbxx.h:614
odb & operator*=(double d)
Definition odbxx.h:1158
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:1260
int m_num_values
Definition odbxx.h:475
iterator end() const
Definition odbxx.h:1025
static bool exists(const std::string &name)
Definition odbxx.cxx:76
midas::odb * get_parent()
Definition odbxx.h:545
odb & operator+=(double d)
Definition odbxx.h:1138
std::string get_name()
Definition odbxx.h:1462
int m_tid
Definition odbxx.h:469
void set_mode(int mode)
Definition odbxx.cxx:1502
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:630
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:471
void deep_copy(odb &d, const odb &s)
Definition odbxx.cxx:334
bool is_deleted() const
Definition odbxx.h:536
static void set_debug(bool flag)
Definition odbxx.h:1407
static midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
Definition odbxx.h:1207
odb & operator++()
Definition odbxx.h:1094
bool is_auto_refresh_read() const
Definition odbxx.h:1367
static void unwatch_all()
Definition odbxx.cxx:1575
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:644
void unwatch()
Definition odbxx.cxx:1563
T operator+(T i)
Definition odbxx.h:1029
u_odb & operator[](int index)
Definition odbxx.h:953
T get()
Definition odbxx.h:500
odb(std::initializer_list< std::pair< const char *, midas::odb > > list)
Definition odbxx.h:585
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:524
friend bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1483
void set_tid(int tid)
Definition odbxx.h:539
odb & operator[](const char *str)
Definition odbxx.h:991
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:1084
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:577
int size()
Definition odbxx.cxx:386
void set_flags(uint32_t f)
Definition odbxx.h:533
void set_auto_refresh_write(bool f)
Definition odbxx.h:1374
int get_mode()
Definition odbxx.cxx:1519
odb & operator--()
Definition odbxx.h:1116
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:815
iterator begin() const
Definition odbxx.h:1024
const T & operator=(const T &v)
Definition odbxx.h:788
odb & get_subkey(std::string str)
Definition odbxx.cxx:568
odb & operator()(T v)
Definition odbxx.h:997
void set_hkey(HNDLE hKey)
Definition odbxx.h:531
odb & operator/=(double d)
Definition odbxx.h:1168
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:1126
void set_name(std::string s)
Definition odbxx.h:542
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:456
odb(const char *s)
Definition odbxx.h:733
int get_last_index()
Definition odbxx.h:1020
std::string s()
Definition odbxx.h:1465
friend std::ostream & operator<<(std::ostream &output, odb &o)
Definition odbxx.h:942
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:751
void save(const std::string &filename)
Definition odbxx.cxx:518
void set_last_index(int i)
Definition odbxx.h:1021
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:1314
odb(const std::string &path, bool init_via_xml=false)
Definition odbxx.h:658
std::string dump()
Definition odbxx.cxx:427
int m_last_index
Definition odbxx.h:477
odb operator++(int)
Definition odbxx.h:1104
void connect_and_fix_structure(std::string path)
Definition odbxx.cxx:1459
static bool s_connected_odb
Definition odbxx.h:462
const std::array< T, SIZE > & operator=(const std::array< T, SIZE > &arr)
Definition odbxx.h:861
static void init_hdb()
Definition odbxx.cxx:50
int get_num_values()
Definition odbxx.h:1461
operator std::string()
Definition odbxx.h:893
odb & operator-=(double d)
Definition odbxx.h:1148
void set_num_values(int n)
Definition odbxx.h:540
uint32_t get_flags()
Definition odbxx.h:534
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:737
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:987
void set_deleted(bool f)
Definition odbxx.h:537
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:544
HNDLE m_hKey
Definition odbxx.h:479
T operator-(T i)
Definition odbxx.h:1051
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:512
bool is_write_protect() const
Definition odbxx.h:1394
T operator*(const T i)
Definition odbxx.h:1073
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: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: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: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:1854
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_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: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