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
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(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
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 // set midas::odb object form a non-array MJsonNode
1238 std::string node_to_string(const MJsonNode* node) {
1239 std::string value;
1240
1241 switch (node->GetType()) {
1242 case MJSON_STRING:
1243 value = node->GetString();
1244 break;
1245 case MJSON_INT:
1246 value = std::to_string(node->GetInt());
1247 break;
1248 case MJSON_NUMBER:
1249 value = std::to_string(node->GetDouble());
1250 break;
1251 case MJSON_BOOL:
1252 value = std::to_string(node->GetBool());
1253 break;
1254 default:
1255 mthrow("Invalid MJSON type \"" + std::to_string(node->GetType()) + "\"");
1256 }
1257
1258 return value;
1259 };
1260
1261 // create midas::odb object form MJsonNode
1262 midas::odb *odb_from_json(const MJsonNode* node, std::string name, int tid, odb *o) {
1263 int type = node->GetType();
1264
1265 if (type == MJSON_OBJECT) { // subdir
1266 const MJsonStringVector* names = node->GetObjectNames();
1267 const MJsonNodeVector* nodes = node->GetObjectNodes();
1268 if (names == nullptr || nodes==nullptr || names->size() != nodes->size())
1269 mthrow("Invalid JSON format");
1270
1271 if (o == nullptr)
1272 o = new midas::odb();
1273 o->set_tid(TID_KEY);
1274 o->set_name(name);
1275 o->set_hkey(0);
1276
1277 // count subkeys
1278 int n=0;
1279 for (int i=0 ; i<(int)names->size() ; i++) {
1280 const char *name = (*names)[i].c_str();
1281
1282 if (strchr(name, '/'))// skip special entries
1283 continue;
1284 n++;
1285 }
1286 o->set_num_values(n);
1287
1288 for (int i=n=0 ; i<(int)names->size() ; i++) {
1289 const char *name = (*names)[i].c_str();
1290
1291 if (strchr(name, '/'))// skip special entries
1292 continue;
1293
1294 int t = 0;
1295 auto key = node->FindObjectNode((std::string(name) + "/key").c_str());
1296 if (key)
1297 t = key->FindObjectNode("type")->GetInt();
1298 else
1299 t = TID_KEY;
1300
1301 midas::odb *os = odb_from_json((*nodes)[i], (*names)[i].c_str(), t, nullptr);
1302 os->set_parent(o);
1303 o->set_odb(os, n);
1304 n++;
1305 }
1306
1307 o->set_num_values(n);
1308
1309 } else { // key
1310
1311 if (o == nullptr)
1312 o = new midas::odb();
1313
1314 o->set_name(name);
1315 o->set_tid(tid);
1316 o->set_hkey(0);
1317
1318 if (node->GetType() == MJSON_ARRAY) {
1319 const MJsonNodeVector* a = node->GetArray();
1320 o->set_num_values(a->size());
1321 for (int i=0 ; i<a->size() ; i++) {
1322 MJsonNode *n = (*a)[i];
1323 auto value = node_to_string(n);
1324 o->set(value, i);
1325 }
1326 } else {
1327 auto value = node_to_string(node);
1328 o->set(value);
1329 }
1330 }
1331
1332 return o;
1333 };
1334
1335 // Deep copy
1336 void deep_copy(odb &d, const odb &s);
1337
1338 // Setters and Getters
1344
1350
1356
1357 bool is_dirty() const { return m_flags[odb_flags::DIRTY]; }
1358 void set_dirty(bool f) { m_flags[odb_flags::DIRTY] = f; }
1359
1365
1371
1377
1383
1384 // Static functions
1385 static void set_debug(bool flag) { s_debug = flag; }
1386 static bool get_debug() { return s_debug; }
1387 static int create(const char *name, int type = TID_KEY);
1388 static bool exists(const std::string &name);
1389 static int delete_key(const std::string &name);
1390 static void load(const std::string &filename, const std::string &odb_path);
1391
1392 void odb_from_xml_remote(const std::string &str);
1393 void odb_from_xml_string(const std::string &str, const std::string &subkey);
1394 void odb_from_json_string(const std::string &str, const std::string &subkey);
1395 void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults = false);
1396 void connect(std::string str, bool write_defaults = false, bool delete_keys_not_in_defaults = false);
1397 void connect_and_fix_structure(std::string path);
1398
1401 if (s == STRING)
1402 mthrow1("ODB source STRING requires a string");
1403 if (s == FILE)
1404 mthrow1("ODB source FILE requires a filename");
1405 s_odb_source = s;
1406 }
1407 static void set_odb_source(odb::odb_source s, std::string str) {
1408 s_odb_source = s;
1410 }
1411
1412 static bool is_connected_odb() { return s_connected_odb; }
1413
1414 void read();
1415 void read(int index);
1416 void write(int str_size = 0);
1417 void write(int index, int str_size);
1418 std::string print();
1419 std::string dump();
1420 void print(std::string &s, int indent=0);
1421 void dump(std::string &s, int indent=0);
1422 void save(const std::string &filename);
1423 void delete_key();
1424 int size();
1425 void resize(int size);
1426 void resize(int size, bool b);
1427 void watch(std::function<void(midas::odb &)> f);
1428 void unwatch();
1429 void set(std::string str);
1430 void set(std::string s, int i);
1431 void set_odb(odb *o, int i);
1432 void set_string_size(std::string s, int size);
1433
1434 bool is_subkey(std::string str);
1435 HNDLE get_hkey() { return m_hKey; }
1436 std::string get_full_path();
1437 std::string get_parent_path();
1438 int get_tid() { return m_tid; }
1440 std::string get_name() { return m_name; }
1441 odb& items() { return *this; }
1442
1443 std::string s() {
1444 std::string s;
1445 get(s);
1446 return s;
1447 }
1448
1449 void fix_order(std::vector<std::string> target_subkey_order);
1450
1451 void set_mode(int mode);
1452 int get_mode();
1453
1454 unsigned int get_last_written();
1455 };
1456
1457 //---- midas::odb friend functions -------------------------------
1458
1459 // overload comparison operators
1460 template<typename T>
1461 bool operator==(const midas::odb &o, const T &d) {
1462 // the operator needs a "const midas::odb" reference,
1463 // so we have to make a non-const copy
1464 T v;
1465 midas::odb oc(o);
1466 oc.get(v);
1467 return v == d;
1468 }
1469
1470 template<typename T>
1471 bool operator==(const T &d, const midas::odb &o) {
1472 T v;
1473 midas::odb oc(o);
1474 oc.get(v);
1475 return d == v;
1476 }
1477
1478 template<typename T>
1479 bool operator!=(const midas::odb &o, const T &d) {
1480 T v;
1481 midas::odb oc(o);
1482 oc.get(v);
1483 return v != d;
1484 }
1485
1486 template<typename T>
1487 bool operator!=(const T &d, const midas::odb &o) {
1488 T v;
1489 midas::odb oc(o);
1490 oc.get(v);
1491 return d != v;
1492 }
1493
1494 template<typename T>
1495 bool operator<(const midas::odb &o, const T &d) {
1496 T v;
1497 midas::odb oc(o);
1498 oc.get(v);
1499 return v < d;
1500 }
1501
1502 template<typename T>
1503 bool operator<(const T &d, const midas::odb &o) {
1504 T v;
1505 midas::odb oc(o);
1506 oc.get(v);
1507 return d < v;
1508 }
1509
1510 template<typename T>
1511 bool operator<=(const midas::odb &o, const T &d) {
1512 T v;
1513 midas::odb oc(o);
1514 oc.get(v);
1515 return v <= d;
1516 }
1517
1518 template<typename T>
1519 bool operator<=(const T &d, const midas::odb &o) {
1520 T v;
1521 midas::odb oc(o);
1522 oc.get(v);
1523 return d <= v;
1524 }
1525
1526 template<typename T>
1527 bool operator>(const midas::odb &o, const T &d) {
1528 T v;
1529 midas::odb oc(o);
1530 oc.get(v);
1531 return v > d;
1532 }
1533
1534 template<typename T>
1535 bool operator>(const T &d, const midas::odb &o) {
1536 T v;
1537 midas::odb oc(o);
1538 oc.get(v);
1539 return d > v;
1540 }
1541
1542 template<typename T>
1543 bool operator>=(const midas::odb &o, const T &d) {
1544 T v;
1545 midas::odb oc(o);
1546 oc.get(v);
1547 return v >= d;
1548 }
1549
1550 template<typename T>
1551 bool operator>=(const T &d, const midas::odb &o) {
1552 T v;
1553 midas::odb oc(o);
1554 oc.get(v);
1555 return d >= v;
1556 }
1557
1558} // namespace midas
1559
1560
1561#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:1653
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:1136
std::string get_full_path()
Definition odbxx.cxx:419
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:1407
odb & operator+=(double d)
Definition odbxx.h:1116
std::string get_name()
Definition odbxx.h:1440
int m_tid
Definition odbxx.h:461
void set_mode(int mode)
Definition odbxx.cxx:1541
void set_auto_refresh_read(bool f)
Definition odbxx.h:1346
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1367
odb(const std::array< T, SIZE > &arr)
Definition odbxx.h:622
void delete_key()
Definition odbxx.cxx:1512
void set_odb(odb *o, int i)
Definition odbxx.cxx:1667
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:1385
odb & operator++()
Definition odbxx.h:1072
bool is_auto_refresh_read() const
Definition odbxx.h:1345
static void unwatch_all()
Definition odbxx.cxx:1614
static HNDLE s_hDB
Definition odbxx.h:450
HNDLE get_hkey()
Definition odbxx.h:1435
static void set_odb_source(odb::odb_source s)
Definition odbxx.h:1400
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:473
bool is_auto_create() const
Definition odbxx.h:1360
bool is_preserve_string_size() const
Definition odbxx.h:1339
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:1602
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:1438
static bool get_debug()
Definition odbxx.h:1386
bool is_auto_refresh_write() const
Definition odbxx.h:1351
u_odb & get_mdata(int index=0)
Definition odbxx.h:516
friend bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1461
void set_tid(int tid)
Definition odbxx.h:531
odb & operator[](const char *str)
Definition odbxx.h:969
bool read_key(const std::string &path)
Definition odbxx.cxx:699
friend bool operator>=(const midas::odb &o, const T &d)
Definition odbxx.h:1543
friend bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1511
static std::string s_odb_source_str
Definition odbxx.h:448
friend bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1495
void resize(int size)
Definition odbxx.cxx:448
T operator/(const T i)
Definition odbxx.h:1062
void set_preserve_string_size(bool f)
Definition odbxx.h:1340
void set_trigger_hotlink(bool f)
Definition odbxx.h:1379
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:1352
int get_mode()
Definition odbxx.cxx:1558
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:1361
void odb_from_xml_string(const std::string &str, const std::string &subkey)
Definition odbxx.cxx:198
void read()
Definition odbxx.cxx:844
void resize_mdata(int size)
Definition odbxx.cxx:318
static odb::odb_source get_odb_source()
Definition odbxx.h:1399
friend bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1527
bool is_dirty() const
Definition odbxx.h:1357
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:610
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:259
void set_flags_recursively(uint32_t f)
Definition odbxx.cxx:151
unsigned int get_last_written()
Definition odbxx.cxx:1572
midas::odb * odb_from_json(const MJsonNode *node, std::string name, int tid, odb *o)
Definition odbxx.h:1262
std::string node_to_string(const MJsonNode *node)
Definition odbxx.h:1238
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:674
void watch(std::function< void(midas::odb &)> f)
Definition odbxx.cxx:1586
odb(const char *s)
Definition odbxx.h:711
int get_last_index()
Definition odbxx.h:998
std::string s()
Definition odbxx.h:1443
friend std::ostream & operator<<(std::ostream &output, odb &o)
Definition odbxx.h:920
bool is_auto_enlarge_array() const
Definition odbxx.h:1366
friend bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1479
int detect_type(const T &)
Definition odbxx.h:729
void save(const std::string &filename)
Definition odbxx.cxx:564
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:586
static bool s_debug
Definition odbxx.h:452
void fix_order(std::vector< std::string > target_subkey_order)
Definition odbxx.cxx:1356
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:484
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:1498
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:1439
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:1378
bool write_key(std::string &path, bool write_defaults)
Definition odbxx.cxx:785
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:1412
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:1373
std::string m_name
Definition odbxx.h:465
void get(T &v)
Definition odbxx.h:504
bool is_write_protect() const
Definition odbxx.h:1372
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:1419
odb & items()
Definition odbxx.h:1441
void set_dirty(bool f)
Definition odbxx.h:1358
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:1729
void set_tid(int tid)
Definition odbxx.h:105
void mult(double f, bool push=true)
Definition odbxx.cxx:1954
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:1844
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:11772
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:1543
bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1527
bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1461
bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1495
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:1511
bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1479
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