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);
198 else if (m_tid == TID_INT8)
199 m_int8 = std::stoi(v);
200 else if (m_tid == TID_UINT16)
201 m_uint16 = std::stoul(v);
202 else if (m_tid == TID_INT16)
203 m_int16 = std::stoi(v);
204 else if (m_tid == TID_UINT32)
205 m_uint32 = std::stoul(v);
206 else if (m_tid == TID_INT32)
207 m_int32 = std::stoi(v);
208 else if (m_tid == TID_UINT64)
209 m_uint64 = std::stoul(v);
210 else if (m_tid == TID_INT64)
211 m_int64 = std::stoi(v);
212 else if (m_tid == TID_BOOL)
213 m_bool = std::stoi(v);
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
448 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(5, 14) == "/MIDAS version")
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
687 if (s_odb_source_str.find(".xml") != std::string::npos ||
688 s_odb_source_str.find(".XML") != std::string::npos)
689 odb_from_xml_string(ss.str(), path);
690 else if (s_odb_source_str.find(".json") != std::string::npos ||
691 s_odb_source_str.find(".JSON") != std::string::npos)
692 odb_from_json_string(ss.str(), path);
693 else
694 mthrow("File type of \"" +s_odb_source_str + "\" is not supported");
695
696 } else
697 mthrow("Unknown ODB source: " + std::to_string(s_odb_source));
698
699 } else {
700 // simple string
701
702 // Construct object from initializer_list
703 m_num_values = 1;
704 m_data = new u_odb[1]{new std::string{path}};
705 m_tid = m_data[0].get_tid();
706 m_data[0].set_parent(this);
707 }
708 }
709
710 // Constructor for C string
711 odb(const char *s) : odb(std::string(s)) {
712 }
713
714 // Constructor with const char * array
715 odb(std::initializer_list<const char *> list) : odb() {
716 m_num_values = list.size();
717 m_data = new u_odb[m_num_values]{};
718 int i = 0;
719 for (auto &element : list) {
721 m_data[i].set_parent(this);
723 i++;
724 }
725 m_tid = m_data[0].get_tid();
726 }
727
728 template<typename T>
729 int detect_type(const T &) {
730 if (std::is_same<T, uint8_t>::value)
731 return TID_UINT8;
732 else if (std::is_same<T, int8_t>::value)
733 return TID_INT8;
734 else if (std::is_same<T, uint16_t>::value)
735 return TID_UINT16;
736 else if (std::is_same<T, int16_t>::value)
737 return TID_INT16;
738 else if (std::is_same<T, uint32_t>::value)
739 return TID_UINT32;
740 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
741 return TID_UINT32;
742 else if (std::is_same<T, int32_t>::value)
743 return TID_INT32;
744 else if (std::is_same<T, long>::value && sizeof(long) == 4)
745 return TID_INT32;
746 else if (std::is_same<T, uint64_t>::value)
747 return TID_UINT64;
748 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
749 return TID_UINT64;
750 else if (std::is_same<T, int64_t>::value)
751 return TID_INT64;
752 else if (std::is_same<T, long>::value && sizeof(long) == 8)
753 return TID_INT64;
754 else if (std::is_same<T, bool>::value)
755 return TID_BOOL;
756 else if (std::is_same<T, float>::value)
757 return TID_FLOAT;
758 else if (std::is_same<T, double>::value)
759 return TID_DOUBLE;
760 else
761 return TID_STRING;
762 }
763
764 // Overload the Assignment Operators
765 template<typename T>
766 const T &operator=(const T &v) {
767
768 if (this->is_write_protect())
769 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
770
771 if (m_num_values == 0) {
772 // initialize this
773 m_num_values = 1;
774 m_tid = detect_type(v);
775 m_data = new u_odb[1]{};
776 m_data[0].set_tid(m_tid);
777 m_data[0].set_parent(this);
778 m_data[0].set(v);
779 if (this->is_auto_refresh_write())
780 write();
781 } else {
782 for (int i = 0; i < m_num_values; i++)
783 m_data[i].set(v);
784
785 if (this->is_auto_refresh_write())
786 write();
787 }
788 return v;
789 }
790
791 // Overload the Assignment Operators for std::vector
792 template<typename T>
793 const std::vector<T> &operator=(const std::vector<T> &v) {
794
795 if (this->is_write_protect())
796 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
797
798 if (m_num_values == 0) {
799 // initialize this
800 m_num_values = v.size();
801 if (std::is_same<T, bool>::value) {
802 // Special logic for vector<bool>, which may not be a true
803 // container: it's often optimized to be a bitfield, with
804 // references to elements being masked bits rather than bools.
805 // So T is a bool here, but typeof(v[0]) may not be bool!
806 // "Fake container optimization" only applies to vector<bool>,
807 // not array<bool> or any other vector<T>.
808 m_tid = TID_BOOL;
809 } else {
810 // Every other type can be detected using ref to first element.
811 m_tid = detect_type(v[0]);
812 }
813
814 m_data = new u_odb[m_num_values]{};
815 for (int i = 0; i < m_num_values; i++) {
817 m_data[i].set_parent(this);
818 }
819
820 } else {
821
822 // resize internal array if different
823 if ((int)v.size() != m_num_values) {
824 resize_mdata(v.size());
825 }
826 }
827
828 for (int i = 0; i < m_num_values; i++)
829 m_data[i].set(v[i]);
830
831 if (this->is_auto_refresh_write())
832 write();
833
834 return v;
835 }
836
837 // Overload the Assignment Operators for std::array
838 template<typename T, size_t SIZE>
839 const std::array<T, SIZE> &operator=(const std::array<T, SIZE> &arr) {
840
841 if (this->is_write_protect())
842 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
843
844 if (m_num_values == 0) {
845 // initialize this
847 m_tid = detect_type(arr[0]);
848 m_data = new u_odb[m_num_values]{};
849 for (int i = 0; i < m_num_values; i++) {
851 m_data[i].set_parent(this);
852 }
853
854 } else {
855
856 // resize internal array if different
857 if (SIZE != m_num_values) {
859 }
860 }
861
862 for (int i = 0; i < m_num_values; i++)
863 m_data[i].set(arr[i]);
864
865 if (this->is_auto_refresh_write())
866 write();
867 return arr;
868 }
869
870 // overload conversion operator for std::string
871 operator std::string() {
872 std::string s;
873 if (m_tid == TID_KEY)
874 print(s, 0);
875 else
876 get(s); // forward to get(std::string)
877 return s;
878 }
879
880 // overload conversion operator for std::vector<T>
881 template<typename T>
882 operator std::vector<T>() {
884 read();
885 std::vector<T> v(m_num_values);
886 for (int i = 0; i < m_num_values; i++)
887 v[i] = m_data[i];
888 return v;
889 }
890
891 operator std::vector<std::string>() {
893 read();
894 std::vector<std::string> v(m_num_values);
895 for (int i = 0; i < m_num_values; i++)
896 v[i] = m_data[i].get();
897 return v;
898 }
899
900 // overload all other conversion operators
901 template<typename T, typename std::enable_if<
902 std::is_same<T, uint8_t>::value ||
903 std::is_same<T, int8_t>::value ||
904 std::is_same<T, uint16_t>::value ||
905 std::is_same<T, int16_t>::value ||
906 std::is_same<T, uint32_t>::value ||
907 std::is_same<T, int32_t>::value ||
908 std::is_same<T, uint64_t>::value ||
909 std::is_same<T, int64_t>::value ||
910 std::is_same<T, bool>::value ||
911 std::is_same<T, float>::value ||
912 std::is_same<T, double>::value, T>::type * = nullptr>
913 operator T() {
914 if (m_tid == 0)
915 mthrow("Element \"" + m_name + "\" not found");
916 return get<T>(); // forward to get<T>()
917 }
918
919 // overload stream out operator
920 friend std::ostream &operator<<(std::ostream &output, odb &o) {
921 std::string s;
922 if (o.m_tid == TID_KEY)
923 o.print(s, 0);
924 else
925 o.get(s);
926 output << s;
927 return output;
928 };
929
930 // overload index operator for arrays
932 if (this->is_write_protect())
933 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
934
935 if (index < 0)
936 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) + "]\"");
937
938 if (index == 0 && m_num_values == 0) {
939 // initialize this
940 m_num_values = 1;
941 m_tid = 0;
942 m_data = new u_odb[1]{};
943 m_data[0].set_tid(m_tid);
944 m_data[0].set_parent(this);
945 m_last_index = 0;
946 return m_data[0];
947 } else if (index >= m_num_values) {
948 if (is_auto_enlarge_array()) {
950 if (this->is_auto_refresh_write())
951 write(index, 0);
952 } else {
953 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)");
954 }
955 }
956
958 read(index);
959
961 return m_data[index];
962 }
963
964 // overload index operator for subkeys
965 odb &operator[](std::string str) {
966 return get_subkey(str);
967 }
968
969 odb &operator[](const char *str) {
970 return get_subkey(std::string(str));
971 }
972
973 // overload the call operator
974 template <typename T>
976 if (m_tid == 0) {
977 if (m_num_values == 0) {
978 // initialize this
979 m_num_values = 1;
980 m_tid = detect_type(v);
981 m_data = new u_odb[1]{};
982 m_data[0].set_tid(m_tid);
983 m_data[0].set_parent(this);
984 m_data[0].set(v);
985 if (this->is_auto_refresh_write())
986 write();
987 } else {
988 for (int i = 0; i < m_num_values; i++)
989 m_data[i].set(v);
990 if (this->is_auto_refresh_write())
991 write();
992 }
993 }
994 return *this;
995 }
996
997 // indexed access, internal use only
998 int get_last_index() { return m_last_index; }
999 void set_last_index(int i) { m_last_index = i; }
1000
1001 // iterator support
1002 iterator begin() const { return iterator(m_data); }
1003 iterator end() const { return iterator(m_data + m_num_values); }
1004
1005 // overload arithmetic operators
1006 template<typename T>
1008 if (m_num_values > 1)
1009 mthrow("ODB key \"" + get_full_path() +
1010 "\" contains array which cannot be used in basic arithmetic operation.");
1011 if (std::is_same<T, midas::odb>::value) {
1012 if (is_auto_refresh_read()) {
1013 read();
1014 i.read();
1015 }
1016 // adding two midas::odb objects is best done in double
1017 double s1 = static_cast<double>(m_data[0]);
1018 double s2 = static_cast<double>(i.m_data[0]);
1019 return s1 + s2;
1020 } else {
1022 read();
1023 T s = (T) m_data[0];
1024 return s + i;
1025 }
1026 }
1027
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 // subtracting 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>
1051 T operator*(const T i) {
1052 if (m_num_values > 1)
1053 mthrow("ODB key \"" + get_full_path() +
1054 "\" contains array which cannot be used in basic arithmetic operation.");
1056 read();
1057 T s = (T) m_data[0];
1058 return s * i;
1059 }
1060
1061 template<typename T>
1062 T operator/(const T i) {
1063 if (m_num_values > 1)
1064 mthrow("ODB key \"" + get_full_path() +
1065 "\" contains array which cannot be used in basic arithmetic operation.");
1067 read();
1068 T s = (T) m_data[0];
1069 return s / i;
1070 }
1071
1074 read();
1075 for (int i = 0; i < m_num_values; i++)
1076 m_data[i].add(1, false);
1077 if (this->is_auto_refresh_write())
1078 write();
1079 return *this;
1080 }
1081
1083 // create temporary object
1084 odb o(this);
1086 read();
1087 for (int i = 0; i < m_num_values; i++)
1088 m_data[i].add(1, false);
1089 if (this->is_auto_refresh_write())
1090 write();
1091 return o;
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
1116 odb &operator+=(double d) {
1118 read();
1119 for (int i = 0; i < m_num_values; i++)
1120 m_data[i].add(d, false);
1121 if (this->is_auto_refresh_write())
1122 write();
1123 return *this;
1124 }
1125
1126 odb &operator-=(double d) {
1128 read();
1129 for (int i = 0; i < m_num_values; i++)
1130 m_data[i].add(-d, false);
1131 if (this->is_auto_refresh_write())
1132 write();
1133 return *this;
1134 }
1135
1136 odb &operator*=(double d) {
1138 read();
1139 for (int i = 0; i < m_num_values; i++)
1140 m_data[i].mult(d, false);
1141 if (this->is_auto_refresh_write())
1142 write();
1143 return *this;
1144 }
1145
1146 odb &operator/=(double d) {
1148 read();
1149 if (d == 0)
1150 mthrow("Division by zero");
1151 for (int i = 0; i < m_num_values; i++)
1152 m_data[i].mult(1 / d, false);
1153 if (this->is_auto_refresh_write())
1154 write();
1155 return *this;
1156 }
1157
1158 // overload comparison operators
1159 template<typename T>
1160 friend bool operator==(const midas::odb &o, const T &d);
1161 template<typename T>
1162 friend bool operator==(const T &d, const midas::odb &o);
1163 template<typename T>
1164 friend bool operator!=(const midas::odb &o, const T &d);
1165 template<typename T>
1166 friend bool operator!=(const T &d, const midas::odb &o);
1167 template<typename T>
1168 friend bool operator<(const midas::odb &o, const T &d);
1169 template<typename T>
1170 friend bool operator<(const T &d, const midas::odb &o);
1171 template<typename T>
1172 friend bool operator<=(const midas::odb &o, const T &d);
1173 template<typename T>
1174 friend bool operator<=(const T &d, const midas::odb &o);
1175 template<typename T>
1176 friend bool operator>(const midas::odb &o, const T &d);
1177 template<typename T>
1178 friend bool operator>(const T &d, const midas::odb &o);
1179 template<typename T>
1180 friend bool operator>=(const midas::odb &o, const T &d);
1181 template<typename T>
1182 friend bool operator>=(const T &d, const midas::odb &o);
1183
1184 // create midas::odb object form MXML node
1186 std::string type(mxml_get_name(node));
1187
1188 unsigned int tid = 0;
1189 if (type == "dir" || type == "odb")
1190 tid = TID_KEY;
1191 else {
1192 for (tid = 0; tid < TID_LAST; tid++) {
1194 break;
1195 }
1196 }
1197 if (tid == TID_LAST)
1198 mthrow("Wrong key type in XML file");
1199
1200 if (o == nullptr)
1201 o = new midas::odb();
1202 o->set_tid(tid);
1203 if (type == "odb") {
1204 o->set_name("root");
1205 o->set_hkey(0);
1206 } else {
1207 o->set_name(mxml_get_attribute(node, "name"));
1208 if (mxml_get_attribute(node, "handle") == nullptr)
1209 mthrow("No \"handle\" attribute found in XML data");
1210 o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1211 }
1212
1213 if (type == "key") {
1214 std::string value(mxml_get_value(node));
1215 o->set(value);
1216 } else if (type == "keyarray") {
1217 int n = std::atoi(mxml_get_attribute(node, "num_values"));
1218 o->set_num_values(n);
1219 for (int i=0 ; i<n ; i++) {
1220 std::string value(mxml_get_value(mxml_subnode(node, i)));
1221 o->set(value, i);
1222 }
1223 } else if (type == "dir" || type == "odb") {
1225 o->set_num_values(n);
1226 for (int i = 0; i < n; i++) {
1228 os->set_parent(o);
1229 o->set_odb(os, i);
1230 }
1231 } else
1232 mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1233
1234 return o;
1235 };
1236
1237 // create midas::odb object form MJsonNode
1238 midas::odb *odb_from_json(const MJsonNode* node, std::string name, odb *o) {
1239 int type = node->GetType();
1240
1241 if (type == MJSON_OBJECT) { // subdir
1242 const MJsonStringVector* names = node->GetObjectNames();
1243 const MJsonNodeVector* nodes = node->GetObjectNodes();
1244 if (names == nullptr || nodes==nullptr || names->size() != nodes->size())
1245 mthrow("Invalid JSON format");
1246
1247 if (o == nullptr)
1248 o = new midas::odb();
1249 o->set_tid(TID_KEY);
1250 o->set_name(name);
1251 o->set_hkey(0);
1252
1253 int n=0;
1254 for (int i=0 ; i<(int)names->size() ; i++) {
1255 const char *name = (*names)[i].c_str();
1256 const MJsonNode *node = (*nodes)[i];
1257
1258 if (strchr(name, '/'))// skip special entries
1259 continue;
1260
1261 midas::odb *os = odb_from_json(node, (*names)[i].c_str(), nullptr);
1262 os->set_parent(o);
1263 o->set_odb(os, n);
1264 n++;
1265 }
1266
1267 o->set_num_values(n);
1268
1269 } else { // key
1270
1271 auto key = node->FindObjectNode((std::string(name) + "/key").c_str());
1272 int tid = key->FindObjectNode("type")->GetInt();
1273 const std::string value = node->GetString();
1274
1275 if (o == nullptr)
1276 o = new midas::odb();
1277 o->set_name(name);
1278 o->set_tid(tid);
1279 o->set_hkey(0);
1280 o->set(value);
1281 }
1282
1283// if (type == "odb") {
1284// o->set_name("root");
1285// o->set_hkey(0);
1286// } else {
1287// o->set_name(mxml_get_attribute(node, "name"));
1288// if (mxml_get_attribute(node, "handle") == nullptr)
1289// mthrow("No \"handle\" attribute found in XML data");
1290// o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1291// }
1292//
1293// if (type == "key") {
1294// std::string value(mxml_get_value(node));
1295// o->set(value);
1296// } else if (type == "keyarray") {
1297// int n = std::atoi(mxml_get_attribute(node, "num_values"));
1298// o->set_num_values(n);
1299// for (int i=0 ; i<n ; i++) {
1300// std::string value(mxml_get_value(mxml_subnode(node, i)));
1301// o->set(value, i);
1302// }
1303// } else if (type == "dir" || type == "odb") {
1304// int n = mxml_get_number_of_children(node);
1305// o->set_num_values(n);
1306// for (int i = 0; i < n; i++) {
1307// midas::odb *os = odb_from_xml(mxml_subnode(node, i), nullptr);
1308// os->set_parent(o);
1309// o->set_odb(os, i);
1310// }
1311// } else
1312// mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1313
1314 return o;
1315 };
1316
1317 // Deep copy
1318 void deep_copy(odb &d, const odb &s);
1319
1320 // Setters and Getters
1326
1332
1338
1339 bool is_dirty() const { return m_flags[odb_flags::DIRTY]; }
1340 void set_dirty(bool f) { m_flags[odb_flags::DIRTY] = f; }
1341
1347
1353
1359
1365
1366 // Static functions
1367 static void set_debug(bool flag) { s_debug = flag; }
1368 static bool get_debug() { return s_debug; }
1369 static int create(const char *name, int type = TID_KEY);
1370 static bool exists(const std::string &name);
1371 static int delete_key(const std::string &name);
1372 static void load(const std::string &filename, const std::string &odb_path);
1373
1374 void odb_from_xml_remote(const std::string &str);
1375 void odb_from_xml_string(const std::string &str, const std::string &subkey);
1376 void odb_from_json_string(const std::string &str, const std::string &subkey);
1377 void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults = false);
1378 void connect(std::string str, bool write_defaults = false, bool delete_keys_not_in_defaults = false);
1379 void connect_and_fix_structure(std::string path);
1380
1383 if (s == STRING)
1384 mthrow1("ODB source STRING requires a string");
1385 if (s == FILE)
1386 mthrow1("ODB source FILE requires a filename");
1387 s_odb_source = s;
1388 }
1389 static void set_odb_source(odb::odb_source s, std::string str) {
1390 s_odb_source = s;
1392 }
1393
1394 static bool is_connected_odb() { return s_connected_odb; }
1395
1396 void read();
1397 void read(int index);
1398 void write(int str_size = 0);
1399 void write(int index, int str_size);
1400 std::string print();
1401 std::string dump();
1402 void print(std::string &s, int indent=0);
1403 void dump(std::string &s, int indent=0);
1404 void save(const std::string &filename);
1405 void delete_key();
1406 int size();
1407 void resize(int size);
1408 void resize(int size, bool b);
1409 void watch(std::function<void(midas::odb &)> f);
1410 void unwatch();
1411 void set(std::string str);
1412 void set(std::string s, int i);
1413 void set_odb(odb *o, int i);
1414 void set_string_size(std::string s, int size);
1415
1416 bool is_subkey(std::string str);
1417 HNDLE get_hkey() { return m_hKey; }
1418 std::string get_full_path();
1419 std::string get_parent_path();
1420 int get_tid() { return m_tid; }
1422 std::string get_name() { return m_name; }
1423 odb& items() { return *this; }
1424
1425 std::string s() {
1426 std::string s;
1427 get(s);
1428 return s;
1429 }
1430
1431 void fix_order(std::vector<std::string> target_subkey_order);
1432
1433 void set_mode(int mode);
1434 int get_mode();
1435
1436 unsigned int get_last_written();
1437 };
1438
1439 //---- midas::odb friend functions -------------------------------
1440
1441 // overload comparison operators
1442 template<typename T>
1443 bool operator==(const midas::odb &o, const T &d) {
1444 // the operator needs a "const midas::odb" reference,
1445 // so we have to make a non-const copy
1446 T v;
1447 midas::odb oc(o);
1448 oc.get(v);
1449 return v == d;
1450 }
1451
1452 template<typename T>
1453 bool operator==(const T &d, const midas::odb &o) {
1454 T v;
1455 midas::odb oc(o);
1456 oc.get(v);
1457 return d == v;
1458 }
1459
1460 template<typename T>
1461 bool operator!=(const midas::odb &o, const T &d) {
1462 T v;
1463 midas::odb oc(o);
1464 oc.get(v);
1465 return v != d;
1466 }
1467
1468 template<typename T>
1469 bool operator!=(const T &d, const midas::odb &o) {
1470 T v;
1471 midas::odb oc(o);
1472 oc.get(v);
1473 return d != v;
1474 }
1475
1476 template<typename T>
1477 bool operator<(const midas::odb &o, const T &d) {
1478 T v;
1479 midas::odb oc(o);
1480 oc.get(v);
1481 return v < d;
1482 }
1483
1484 template<typename T>
1485 bool operator<(const T &d, const midas::odb &o) {
1486 T v;
1487 midas::odb oc(o);
1488 oc.get(v);
1489 return d < v;
1490 }
1491
1492 template<typename T>
1493 bool operator<=(const midas::odb &o, const T &d) {
1494 T v;
1495 midas::odb oc(o);
1496 oc.get(v);
1497 return v <= d;
1498 }
1499
1500 template<typename T>
1501 bool operator<=(const T &d, const midas::odb &o) {
1502 T v;
1503 midas::odb oc(o);
1504 oc.get(v);
1505 return d <= v;
1506 }
1507
1508 template<typename T>
1509 bool operator>(const midas::odb &o, const T &d) {
1510 T v;
1511 midas::odb oc(o);
1512 oc.get(v);
1513 return v > d;
1514 }
1515
1516 template<typename T>
1517 bool operator>(const T &d, const midas::odb &o) {
1518 T v;
1519 midas::odb oc(o);
1520 oc.get(v);
1521 return d > v;
1522 }
1523
1524 template<typename T>
1525 bool operator>=(const midas::odb &o, const T &d) {
1526 T v;
1527 midas::odb oc(o);
1528 oc.get(v);
1529 return v >= d;
1530 }
1531
1532 template<typename T>
1533 bool operator>=(const T &d, const midas::odb &o) {
1534 T v;
1535 midas::odb oc(o);
1536 oc.get(v);
1537 return d >= v;
1538 }
1539
1540} // namespace midas
1541
1542
1543#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:1592
std::string get_parent_path()
Definition odbxx.cxx:374
odb operator=(odb &&o)=delete
odb(std::initializer_list< T > list)
Definition odbxx.h:606
odb & operator*=(double d)
Definition odbxx.h:1136
std::string get_full_path()
Definition odbxx.cxx:358
int m_num_values
Definition odbxx.h:467
iterator end() const
Definition odbxx.h:1003
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:1389
odb & operator+=(double d)
Definition odbxx.h:1116
std::string get_name()
Definition odbxx.h:1422
int m_tid
Definition odbxx.h:461
void set_mode(int mode)
Definition odbxx.cxx:1480
void set_auto_refresh_read(bool f)
Definition odbxx.h:1328
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1349
odb(const std::array< T, SIZE > &arr)
Definition odbxx.h:622
void delete_key()
Definition odbxx.cxx:1451
void set_odb(odb *o, int i)
Definition odbxx.cxx:1606
u_odb * m_data
Definition odbxx.h:463
void deep_copy(odb &d, const odb &s)
Definition odbxx.cxx:330
bool is_deleted() const
Definition odbxx.h:528
static void set_debug(bool flag)
Definition odbxx.h:1367
odb & operator++()
Definition odbxx.h:1072
bool is_auto_refresh_read() const
Definition odbxx.h:1327
static void unwatch_all()
Definition odbxx.cxx:1553
static HNDLE s_hDB
Definition odbxx.h:450
HNDLE get_hkey()
Definition odbxx.h:1417
static void set_odb_source(odb::odb_source s)
Definition odbxx.h:1382
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:473
bool is_auto_create() const
Definition odbxx.h:1342
bool is_preserve_string_size() const
Definition odbxx.h:1321
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:1541
T operator+(T i)
Definition odbxx.h:1007
u_odb & operator[](int index)
Definition odbxx.h:931
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:1420
static bool get_debug()
Definition odbxx.h:1368
bool is_auto_refresh_write() const
Definition odbxx.h:1333
u_odb & get_mdata(int index=0)
Definition odbxx.h:516
friend bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1443
void set_tid(int tid)
Definition odbxx.h:531
odb & operator[](const char *str)
Definition odbxx.h:969
midas::odb * odb_from_json(const MJsonNode *node, std::string name, odb *o)
Definition odbxx.h:1238
bool read_key(const std::string &path)
Definition odbxx.cxx:638
friend bool operator>=(const midas::odb &o, const T &d)
Definition odbxx.h:1525
friend bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1493
static std::string s_odb_source_str
Definition odbxx.h:448
friend bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1477
void resize(int size)
Definition odbxx.cxx:387
T operator/(const T i)
Definition odbxx.h:1062
void set_preserve_string_size(bool f)
Definition odbxx.h:1322
void set_trigger_hotlink(bool f)
Definition odbxx.h:1361
odb(T v)
Definition odbxx.h:569
int size()
Definition odbxx.cxx:382
void set_flags(uint32_t f)
Definition odbxx.h:525
void set_auto_refresh_write(bool f)
Definition odbxx.h:1334
int get_mode()
Definition odbxx.cxx:1497
odb & operator--()
Definition odbxx.h:1094
void odb_from_xml_remote(const std::string &str)
Definition odbxx.cxx:159
void set_auto_create(bool f)
Definition odbxx.h:1343
void odb_from_xml_string(const std::string &str, const std::string &subkey)
Definition odbxx.cxx:198
void read()
Definition odbxx.cxx:783
void resize_mdata(int size)
Definition odbxx.cxx:257
static odb::odb_source get_odb_source()
Definition odbxx.h:1381
friend bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1509
bool is_dirty() const
Definition odbxx.h:1339
const std::vector< T > & operator=(const std::vector< T > &v)
Definition odbxx.h:793
iterator begin() const
Definition odbxx.h:1002
const T & operator=(const T &v)
Definition odbxx.h:766
odb & get_subkey(std::string str)
Definition odbxx.cxx:549
odb & operator()(T v)
Definition odbxx.h:975
void set_hkey(HNDLE hKey)
Definition odbxx.h:523
odb & operator/=(double d)
Definition odbxx.h:1146
void odb_from_json_string(const std::string &str, const std::string &subkey)
Definition odbxx.cxx:241
void set_flags_recursively(uint32_t f)
Definition odbxx.cxx:151
unsigned int get_last_written()
Definition odbxx.cxx:1511
odb operator--(int)
Definition odbxx.h:1104
void set_name(std::string s)
Definition odbxx.h:534
int get_subkeys(std::vector< std::string > &name)
Definition odbxx.cxx:613
void watch(std::function< void(midas::odb &)> f)
Definition odbxx.cxx:1525
odb(const char *s)
Definition odbxx.h:711
int get_last_index()
Definition odbxx.h:998
std::string s()
Definition odbxx.h:1425
friend std::ostream & operator<<(std::ostream &output, odb &o)
Definition odbxx.h:920
bool is_auto_enlarge_array() const
Definition odbxx.h:1348
friend bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1461
int detect_type(const T &)
Definition odbxx.h:729
void save(const std::string &filename)
Definition odbxx.cxx:503
void set_last_index(int i)
Definition odbxx.h:999
static int create(const char *name, int type=TID_KEY)
Definition odbxx.cxx:139
bool is_subkey(std::string str)
Definition odbxx.cxx:525
static bool s_debug
Definition odbxx.h:452
void fix_order(std::vector< std::string > target_subkey_order)
Definition odbxx.cxx:1295
odb(const std::string &path, bool init_via_xml=false)
Definition odbxx.h:650
static odb_source s_odb_source
Definition odbxx.h:447
std::string dump()
Definition odbxx.cxx:423
int m_last_index
Definition odbxx.h:469
odb operator++(int)
Definition odbxx.h:1082
void connect_and_fix_structure(std::string path)
Definition odbxx.cxx:1437
static bool s_connected_odb
Definition odbxx.h:454
const std::array< T, SIZE > & operator=(const std::array< T, SIZE > &arr)
Definition odbxx.h:839
static void init_hdb()
Definition odbxx.cxx:49
int get_num_values()
Definition odbxx.h:1421
operator std::string()
Definition odbxx.h:871
odb & operator-=(double d)
Definition odbxx.h:1126
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:1360
bool write_key(std::string &path, bool write_defaults)
Definition odbxx.cxx:724
std::string print()
Definition odbxx.cxx:415
static midas::odb * search_hkey(midas::odb *po, int hKey)
Definition odbxx.cxx:61
static bool is_connected_odb()
Definition odbxx.h:1394
odb(std::initializer_list< const char * > list)
Definition odbxx.h:715
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:965
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:1185
void set_parent(midas::odb *p)
Definition odbxx.h:536
HNDLE m_hKey
Definition odbxx.h:471
T operator-(T i)
Definition odbxx.h:1029
void set_write_protect(bool f)
Definition odbxx.h:1355
std::string m_name
Definition odbxx.h:465
void get(T &v)
Definition odbxx.h:504
bool is_write_protect() const
Definition odbxx.h:1354
T operator*(const T i)
Definition odbxx.h:1051
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
Definition odbxx.cxx:1358
odb & items()
Definition odbxx.h:1423
void set_dirty(bool f)
Definition odbxx.h:1340
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:1668
void set_tid(int tid)
Definition odbxx.h:105
void mult(double f, bool push=true)
Definition odbxx.cxx:1893
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:1783
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:3201
const char * rpc_tid_name(INT id)
Definition midas.cxx:11764
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:1525
bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1509
bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1443
bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1477
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:1493
bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1461
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:1311
static te_expr * list(state *s)
Definition tinyexpr.c:567