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