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
29#include "midas.h"
30#include "mexcept.h"
31#include "mxml.h"
32// #include "mleak.h" // un-comment for memory leak debugging
33
34
35/*------------------------------------------------------------------*/
36
37namespace midas {
38
39 class odb;
40
41 //================================================================
42 // u_odb class is a union to hold one ODB value, either a basic
43 // type, a std::string or a pointer to an odb object
44 //================================================================
45
46 class u_odb {
47 private:
48 // union to hold data
49 union {
58 bool m_bool;
59 float m_float;
60 double m_double;
61 std::string *m_string;
63 };
64
65 int m_tid;
67
68 public:
70
71 // for shorter values, first set m_string to nullptr to initialize higher bytes to zero
73
75
77
79
81
83
85
87
88 u_odb(bool v) : m_tid{TID_BOOL}, m_parent_odb{nullptr} {m_string = nullptr; m_bool = v;};
89
90 u_odb(float v) : m_float{v}, m_tid{TID_FLOAT}, m_parent_odb{nullptr} {m_string = nullptr; m_float = v;};
91
92 u_odb(double v) : m_double{v}, m_tid{TID_DOUBLE}, m_parent_odb{nullptr} {m_string = nullptr; m_double = v;};
93
94 u_odb(std::string *v) : m_string{v}, m_tid{TID_STRING}, m_parent_odb{nullptr} {};
95
96 // Destructor
97 ~u_odb();
98
99 // Setters and getters
102
103 void set_tid(int tid) { m_tid = tid; }
104
105 int get_tid() { return m_tid; }
106
107 // Overload the Assignment Operators
116 bool operator=(bool v);
117 float operator=(float v);
118 double operator=(double v);
119 const char *operator=(const char *v);
120 std::string *operator=(std::string * v);
121 std::string operator=(std::string v);
122
123 // Overload the Conversion Operators
124 operator uint8_t();
125 operator int8_t();
126 operator uint16_t();
127 operator int16_t();
128 operator uint32_t();
129 operator int32_t();
130 operator uint64_t();
131 operator int64_t();
132 operator bool();
133 operator float();
134 operator double();
135 operator std::string();
136 operator const char *();
137 operator midas::odb &();
138
139 template<typename T>
140 void set(T v) {
141 if (m_tid == TID_UINT8)
142 m_uint8 = v;
143 else if (m_tid == TID_INT8)
144 m_int8 = v;
145 else if (m_tid == TID_UINT16)
146 m_uint16 = v;
147 else if (m_tid == TID_INT16)
148 m_int16 = v;
149 else if (m_tid == TID_UINT32)
150 m_uint32 = v;
151 else if (m_tid == TID_INT32)
152 m_int32 = v;
153 else if (m_tid == TID_UINT64)
154 m_uint64 = v;
155 else if (m_tid == TID_INT64)
156 m_int64 = v;
157 else if (m_tid == TID_BOOL)
158 m_bool = v;
159 else if (m_tid == TID_FLOAT)
160 m_float = v;
161 else if (m_tid == TID_DOUBLE)
162 m_double = v;
163 else if (m_tid == TID_STRING) {
164 delete m_string;
165 m_string = new std::string(std::to_string(v));
166 } else
167 mthrow("Invalid type ID " + std::to_string(m_tid));
168 }
169
170 void set_string(std::string s) {
171 delete m_string;
172 m_string = new std::string(s);
173 }
174
175 void set_string_size(std::string s, int size);
176
177 void set_string_ptr(std::string *s) {
178 m_string = s;
179 }
180
181 void set(odb *v) {
182 if (m_tid != TID_KEY)
183 mthrow("Subkey can only be assigned to ODB key");
184 m_odb = v;
185 }
186
187 void set_odb(odb *v) {
188 if (m_tid != TID_KEY)
189 mthrow("Subkey can only be assigned to ODB key");
190 m_odb = v;
191 }
192
193 void set(std::string v) {
194 if (m_tid == TID_UINT8)
195 m_uint8 = std::stoi(v);
196 else if (m_tid == TID_INT8)
197 m_int8 = std::stoi(v);
198 else if (m_tid == TID_UINT16)
199 m_uint16 = std::stoul(v);
200 else if (m_tid == TID_INT16)
201 m_int16 = std::stoi(v);
202 else if (m_tid == TID_UINT32)
203 m_uint32 = std::stoul(v);
204 else if (m_tid == TID_INT32)
205 m_int32 = std::stoi(v);
206 else if (m_tid == TID_UINT64)
207 m_uint64 = std::stoul(v);
208 else if (m_tid == TID_INT64)
209 m_int64 = std::stoi(v);
210 else if (m_tid == TID_BOOL)
211 m_bool = std::stoi(v);
212 else if (m_tid == TID_FLOAT)
213 m_float = std::stod(v);
214 else if (m_tid == TID_DOUBLE)
215 m_double = std::stod(v);
216 else if (m_tid == TID_STRING) {
217 delete m_string;
218 m_string = new std::string(v);
219 } else if (m_tid == TID_LINK) {
220 delete m_string;
221 m_string = new std::string(v);
222 } else
223 mthrow("Invalid type ID " + std::to_string(m_tid));
224 }
225
226 void set(const char *v) {
227 set(std::string(v));
228 }
229
230 void set(char *v) {
231 set(std::string(v));
232 }
233
234
235 void add(double inc, bool push = true);
236
237 void mult(double f, bool push = true);
238
239 // overload arithmetic operators
241 add(1);
242 return *this;
243 }
244
246 add(1);
247 return *this;
248 }
249
251 add(-1);
252 return *this;
253 }
254
256 add(-1);
257 return *this;
258 }
259
260 u_odb &operator+=(double d) {
261 add(d);
262 return *this;
263 }
264
265 u_odb &operator-=(double d) {
266 add(-d);
267 return *this;
268 }
269
270 u_odb &operator*=(double d) {
271 mult(d);
272 return *this;
273 }
274
275 u_odb &operator/=(double d) {
276 if (d == 0)
277 mthrow("Division by zero");
278 mult(1 / d);
279 return *this;
280 }
281
282 template<typename T>
284 double d = *this;
285 d += v;
286 set(v);
287 return *this;
288 }
289
290 template<typename T>
292 double d = *this;
293 d -= v;
294 set(v);
295 return *this;
296 }
297
298 template<typename T>
300 double d = *this;
301 d *= v;
302 set(v);
303 return *this;
304 }
305
306 template<typename T>
308 double d = *this;
309 d /= v;
310 set(v);
311 return *this;
312 }
313
314 // get function for basic type
315 template<typename T>
316 T get() {
317 if (m_tid == TID_UINT8)
318 return (T) m_uint8;
319 else if (m_tid == TID_INT8)
320 return (T) m_int8;
321 else if (m_tid == TID_UINT16)
322 return (T) m_uint16;
323 else if (m_tid == TID_INT16)
324 return (T) m_int16;
325 else if (m_tid == TID_UINT32)
326 return (T) m_uint32;
327 else if (m_tid == TID_INT32)
328 return (T) m_int32;
329 else if (m_tid == TID_UINT64)
330 return (T) m_uint64;
331 else if (m_tid == TID_INT64)
332 return (T) m_int64;
333 else if (m_tid == TID_BOOL)
334 return (T) m_bool;
335 else if (m_tid == TID_FLOAT)
336 return (T) m_float;
337 else if (m_tid == TID_DOUBLE)
338 return (T) m_double;
339 else if (m_tid == 0)
340 mthrow("Subkey not found");
341 else
342 mthrow("Invalid type ID %s" + std::to_string(m_tid));
343 }
344
345 // get function for string
346 std::string get() {
347 std::string s;
348 get(s);
349 return s;
350 }
351
352 std::string get_value() {
353 std::string s;
354 get(s);
355 return s;
356 }
357
358 // shortcut to above
359 std::string s() {
360 return get();
361 }
362
363 // get function for strings
364 void get(std::string &s);
365
366 // get_function for keys
368 if (m_tid != TID_KEY)
369 mthrow("odb_get() called for non-key object");
370 return m_odb;
371 }
372
374 if (m_tid != TID_KEY)
375 mthrow("odb_get() called for non-key object");
376 return *m_odb;
377 }
378
379 // overload stream out operator
380 friend std::ostream &operator<<(std::ostream &output, u_odb &o) {
381 std::string s = o;
382 output << s;
383 return output;
384 };
385
386 };
387
388 //-----------------------------------------------
389
390 // bit in odb::m_flags
402
403 //================================================================
404 // the odb object holds an ODB entry with name, type,
405 // hKey and array of u_odb values
406 //================================================================
407
408 class odb {
409 public:
410 class iterator {
411 public:
413
414 // Pre-increment
416 ++pu_odb;
417 return *this;
418 }
419
420 // Post-increment
422 iterator ret = *this;
423 this->operator++();
424 return ret;
425 }
426
427 bool operator!=(const iterator &other) const { return pu_odb != other.pu_odb; }
428
429 u_odb &operator*() { return *pu_odb; }
430
431 private:
433 };
434
435 private:
436
437 // handle to ODB, same for all instances
438 static HNDLE s_hDB;
439 // global debug flag for all instances
440 static bool s_debug;
441 // global flag indicating that we are connected to the ODB
442 static bool s_connected_odb;
443 // global list of ODB keys used by odb::watch
444 static std::vector<midas::odb> m_watch;
445
446 // various parameters defined in odb_flags
447 std::bitset<9> m_flags;
448 // type of this object, one of TID_xxx
449 int m_tid;
450 // vector containing data for this object
452 // name of ODB entry
453 std::string m_name;
454 // number of values of ODB entry
456 // last index accessed, needed for o[i] = x
458 // ODB handle for this key
460 // callback for watch funciton
462 // parent ODB key
464
465 //-------------------------------------------------------------
466
467 // static functions
468 static void init_hdb();
469 static midas::odb *search_hkey(midas::odb *po, int hKey);
470 static void watch_callback(int hDB, int hKey, int index, void *info);
471 static void unwatch_all();
472
473 //-------------------------------------------------------------
474
476 void resize_mdata(int size);
477
478 // get function for basic types
479 template<typename T>
480 T get() {
481 if (m_num_values > 1)
482 mthrow("ODB key \"" + get_full_path() +
483 "[0..." + std::to_string(m_num_values - 1) +
484 "]\" contains array. Please assign to std::vector.");
486 read();
487 return (T) m_data[0];
488 }
489
490 // get function for basic types as a parameter
491 template<typename T>
492 void get(T &v) {
493 if (m_num_values > 1)
494 mthrow("ODB key \"" + get_full_path() + "\" contains array. Please assign to std::vector.");
496 read();
497 v = (T) m_data[0];
498 }
499
500 // get function for strings
501 void get(std::string &s, bool quotes = false, bool refresh = true);
502
503 // return internal data
504 u_odb &get_mdata(int index = 0) { return m_data[index]; }
505
506 odb &get_subkey(std::string str);
507 int get_subkeys(std::vector<std::string> &name);
508 bool read_key(const std::string &path);
509 bool write_key(std::string &path, bool write_defaults);
510
512
513 void set_flags(uint32_t f) { m_flags = f; }
514 uint32_t get_flags() { return static_cast<uint32_t>(m_flags.to_ulong()); }
515
516 bool is_deleted() const { return m_flags[odb_flags::DELETED]; }
518
519 void set_tid(int tid) { m_tid = tid; }
521
522 void set_name(std::string s) { m_name = s; }
523
526
527 public:
528
529 // Default constructor
530 odb() :
534 (1 << odb_flags::AUTO_CREATE) |
535 (1 << odb_flags::TRIGGER_HOTLINK)},
536 m_tid{0},
538 m_name{},
539 m_num_values{0},
540 m_last_index{-1},
541 m_hKey{},
542 m_parent{} {}
543
544 // Destructor
546 delete[] m_data;
547 }
548
549 // Deep copy constructor
550 odb(const odb &o);
551
552 // Delete shallow assignment operator
553 odb operator=(odb &&o) = delete;
554
555 // Constructor for single basic types
556 template<typename T>
557 odb(T v):odb() {
558 m_num_values = 1;
559 m_data = new u_odb[1]{v};
560 m_tid = m_data[0].get_tid();
561 m_data[0].set_parent(this);
562 }
563
564 // Constructor with std::initializer_list
565 odb(std::initializer_list<std::pair<const char *, midas::odb>> list) : odb() {
566 m_tid = TID_KEY;
567 m_num_values = list.size();
569 int i = 0;
570 for (auto &element: list) {
571 // check if name exists already
572 for (int j=0 ; j<i ; j++) {
573 if (strcasecmp(element.first, m_data[j].get_odb().get_name().c_str()) == 0) {
574 if (element.first == m_data[j].get_odb().get_name().c_str()) {
575 mthrow("ODB key with name \"" + m_data[j].get_odb().get_name() + "\" exists already");
576 } else {
577 mthrow("ODB key \"" + std::string(element.first) + "\" exists already as \"" +
578 m_data[j].get_odb().get_name() + "\" (only case differs)");
579 }
580 }
581 }
582 auto o = new midas::odb(element.second);
583 o->set_name(element.first);
584 o->set_parent(this);
586 m_data[i].set_parent(this);
587 m_data[i].set(o);
588 i++;
589 }
590 }
591
592 // Constructor with basic type array
593 template<typename T>
594 odb(std::initializer_list<T> list) : odb() {
595 m_num_values = list.size();
596 m_data = new u_odb[m_num_values]{};
597 int i = 0;
598 for (auto &element : list) {
599 u_odb u(element);
600 m_data[i].set_tid(u.get_tid());
601 m_data[i].set_parent(this);
603 i++;
604 }
605 m_tid = m_data[0].get_tid();
606 }
607
608 // Constructor with basic explicit array
609 template<typename T, size_t SIZE>
610 odb(const std::array<T, SIZE> &arr) : odb() {
612 m_data = new u_odb[m_num_values]{};
613 for (int i = 0; i < (int)SIZE; i++) {
614 u_odb u(arr[i]);
615 m_data[i].set_tid(u.get_tid());
616 m_data[i].set_parent(this);
617 m_data[i].set(arr[i]);
618 }
619 m_tid = m_data[0].get_tid();
620 }
621
622 // Constructor with explicit array of std::string
623 template<size_t SIZE>
624 odb(const std::array<std::string, SIZE> &arr) : odb() {
626 m_data = new u_odb[m_num_values]{};
627 for (int i = 0; i < (int)SIZE; i++) {
628 std::string * mystring = new std::string(arr[i]);
630 m_data[i].set_tid(u.get_tid());
631 m_data[i].set_parent(this);
632 m_data[i].set(arr[i]);
633 }
634 m_tid = m_data[0].get_tid();
635 }
636
637 // Constructor for std::string
638 odb(const std::string &str, bool init_via_xml = false) : odb() {
639 if (str[0] == '/') {
640 // ODB path
641 if (init_via_xml) {
642 if (!exists(str))
643 odb::create(str.c_str(), TID_KEY);
645 } else {
646 if (!read_key(str))
647 // create subdir if key does not exist
648 odb::create(str.c_str(), TID_KEY);
649
650 if (!read_key(str))
651 mthrow("ODB key \"" + str + "\" not found in ODB");
652
653 if (m_tid != TID_KEY)
654 read();
655 }
656 } else {
657 // simple string
658
659 // Construct object from initializer_list
660 m_num_values = 1;
661 m_data = new u_odb[1]{new std::string{str}};
662 m_tid = m_data[0].get_tid();
663 m_data[0].set_parent(this);
664 }
665 }
666
667 // Constructor for C string
668 odb(const char *s) : odb(std::string(s)) {
669 }
670
671 // Constructor with const char * array
672 odb(std::initializer_list<const char *> list) : odb() {
673 m_num_values = list.size();
674 m_data = new u_odb[m_num_values]{};
675 int i = 0;
676 for (auto &element : list) {
678 m_data[i].set_parent(this);
680 i++;
681 }
682 m_tid = m_data[0].get_tid();
683 }
684
685 template<typename T>
686 int detect_type(const T &) {
687 if (std::is_same<T, uint8_t>::value)
688 return TID_UINT8;
689 else if (std::is_same<T, int8_t>::value)
690 return TID_INT8;
691 else if (std::is_same<T, uint16_t>::value)
692 return TID_UINT16;
693 else if (std::is_same<T, int16_t>::value)
694 return TID_INT16;
695 else if (std::is_same<T, uint32_t>::value)
696 return TID_UINT32;
697 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 4)
698 return TID_UINT32;
699 else if (std::is_same<T, int32_t>::value)
700 return TID_INT32;
701 else if (std::is_same<T, long>::value && sizeof(long) == 4)
702 return TID_INT32;
703 else if (std::is_same<T, uint64_t>::value)
704 return TID_UINT64;
705 else if (std::is_same<T, unsigned long>::value && sizeof(long) == 8)
706 return TID_UINT64;
707 else if (std::is_same<T, int64_t>::value)
708 return TID_INT64;
709 else if (std::is_same<T, long>::value && sizeof(long) == 8)
710 return TID_INT64;
711 else if (std::is_same<T, bool>::value)
712 return TID_BOOL;
713 else if (std::is_same<T, float>::value)
714 return TID_FLOAT;
715 else if (std::is_same<T, double>::value)
716 return TID_DOUBLE;
717 else
718 return TID_STRING;
719 }
720
721 // Overload the Assignment Operators
722 template<typename T>
723 const T &operator=(const T &v) {
724
725 if (this->is_write_protect())
726 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
727
728 if (m_num_values == 0) {
729 // initialize this
730 m_num_values = 1;
731 m_tid = detect_type(v);
732 m_data = new u_odb[1]{};
733 m_data[0].set_tid(m_tid);
734 m_data[0].set_parent(this);
735 m_data[0].set(v);
736 if (this->is_auto_refresh_write())
737 write();
738 } else {
739 for (int i = 0; i < m_num_values; i++)
740 m_data[i].set(v);
741
742 if (this->is_auto_refresh_write())
743 write();
744 }
745 return v;
746 }
747
748 // Overload the Assignment Operators for std::vector
749 template<typename T>
750 const std::vector<T> &operator=(const std::vector<T> &v) {
751
752 if (this->is_write_protect())
753 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
754
755 if (m_num_values == 0) {
756 // initialize this
757 m_num_values = v.size();
758 if (std::is_same<T, bool>::value) {
759 // Special logic for vector<bool>, which may not be a true
760 // container: it's often optimized to be a bitfield, with
761 // references to elements being masked bits rather than bools.
762 // So T is a bool here, but typeof(v[0]) may not be bool!
763 // "Fake container optimization" only applies to vector<bool>,
764 // not array<bool> or any other vector<T>.
765 m_tid = TID_BOOL;
766 } else {
767 // Every other type can be detected using ref to first element.
768 m_tid = detect_type(v[0]);
769 }
770
771 m_data = new u_odb[m_num_values]{};
772 for (int i = 0; i < m_num_values; i++) {
774 m_data[i].set_parent(this);
775 }
776
777 } else {
778
779 // resize internal array if different
780 if ((int)v.size() != m_num_values) {
781 resize_mdata(v.size());
782 }
783 }
784
785 for (int i = 0; i < m_num_values; i++)
786 m_data[i].set(v[i]);
787
788 if (this->is_auto_refresh_write())
789 write();
790
791 return v;
792 }
793
794 // Overload the Assignment Operators for std::array
795 template<typename T, size_t SIZE>
796 const std::array<T, SIZE> &operator=(const std::array<T, SIZE> &arr) {
797
798 if (this->is_write_protect())
799 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
800
801 if (m_num_values == 0) {
802 // initialize this
804 m_tid = detect_type(arr[0]);
805 m_data = new u_odb[m_num_values]{};
806 for (int i = 0; i < m_num_values; i++) {
808 m_data[i].set_parent(this);
809 }
810
811 } else {
812
813 // resize internal array if different
814 if (SIZE != m_num_values) {
816 }
817 }
818
819 for (int i = 0; i < m_num_values; i++)
820 m_data[i].set(arr[i]);
821
822 if (this->is_auto_refresh_write())
823 write();
824 return arr;
825 }
826
827 // overload conversion operator for std::string
828 operator std::string() {
829 std::string s;
830 if (m_tid == TID_KEY)
831 print(s, 0);
832 else
833 get(s); // forward to get(std::string)
834 return s;
835 }
836
837 // overload conversion operator for std::vector<T>
838 template<typename T>
839 operator std::vector<T>() {
841 read();
842 std::vector<T> v(m_num_values);
843 for (int i = 0; i < m_num_values; i++)
844 v[i] = m_data[i];
845 return v;
846 }
847
848 operator std::vector<std::string>() {
850 read();
851 std::vector<std::string> v(m_num_values);
852 for (int i = 0; i < m_num_values; i++)
853 v[i] = m_data[i].get();
854 return v;
855 }
856
857 // overload all other conversion operators
858 template<typename T, typename std::enable_if<
859 std::is_same<T, uint8_t>::value ||
860 std::is_same<T, int8_t>::value ||
861 std::is_same<T, uint16_t>::value ||
862 std::is_same<T, int16_t>::value ||
863 std::is_same<T, uint32_t>::value ||
864 std::is_same<T, int32_t>::value ||
865 std::is_same<T, uint64_t>::value ||
866 std::is_same<T, int64_t>::value ||
867 std::is_same<T, bool>::value ||
868 std::is_same<T, float>::value ||
869 std::is_same<T, double>::value, T>::type * = nullptr>
870 operator T() {
871 if (m_tid == 0)
872 mthrow("Element \"" + m_name + "\" not found");
873 return get<T>(); // forward to get<T>()
874 }
875
876 // overload stream out operator
877 friend std::ostream &operator<<(std::ostream &output, odb &o) {
878 std::string s;
879 if (o.m_tid == TID_KEY)
880 o.print(s, 0);
881 else
882 o.get(s);
883 output << s;
884 return output;
885 };
886
887 // overload index operator for arrays
889 if (this->is_write_protect())
890 mthrow("Cannot modify write protected key \"" + get_full_path() + "\"");
891
892 if (index < 0)
893 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) + "]\"");
894
895 if (index == 0 && m_num_values == 0) {
896 // initialize this
897 m_num_values = 1;
898 m_tid = 0;
899 m_data = new u_odb[1]{};
900 m_data[0].set_tid(m_tid);
901 m_data[0].set_parent(this);
902 m_last_index = 0;
903 return m_data[0];
904 } else if (index >= m_num_values) {
905 if (is_auto_enlarge_array()) {
907 if (this->is_auto_refresh_write())
908 write(index, 0);
909 } else {
910 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)");
911 }
912 }
913
915 read(index);
916
918 return m_data[index];
919 }
920
921 // overload index operator for subkeys
922 odb &operator[](std::string str) {
923 return get_subkey(str);
924 }
925
926 odb &operator[](const char *str) {
927 return get_subkey(std::string(str));
928 }
929
930 // overload the call operator
931 template <typename T>
933 if (m_tid == 0) {
934 if (m_num_values == 0) {
935 // initialize this
936 m_num_values = 1;
937 m_tid = detect_type(v);
938 m_data = new u_odb[1]{};
939 m_data[0].set_tid(m_tid);
940 m_data[0].set_parent(this);
941 m_data[0].set(v);
942 if (this->is_auto_refresh_write())
943 write();
944 } else {
945 for (int i = 0; i < m_num_values; i++)
946 m_data[i].set(v);
947 if (this->is_auto_refresh_write())
948 write();
949 }
950 }
951 return *this;
952 }
953
954 // indexed access, internal use only
955 int get_last_index() { return m_last_index; }
956 void set_last_index(int i) { m_last_index = i; }
957
958 // iterator support
959 iterator begin() const { return iterator(m_data); }
960 iterator end() const { return iterator(m_data + m_num_values); }
961
962 // overload arithmetic operators
963 template<typename T>
965 if (m_num_values > 1)
966 mthrow("ODB key \"" + get_full_path() +
967 "\" contains array which cannot be used in basic arithmetic operation.");
968 if (std::is_same<T, midas::odb>::value) {
969 if (is_auto_refresh_read()) {
970 read();
971 i.read();
972 }
973 // adding two midas::odb objects is best done in double
974 double s1 = static_cast<double>(m_data[0]);
975 double s2 = static_cast<double>(i.m_data[0]);
976 return s1 + s2;
977 } else {
979 read();
980 T s = (T) m_data[0];
981 return s + i;
982 }
983 }
984
985 template<typename T>
987 if (m_num_values > 1)
988 mthrow("ODB key \"" + get_full_path() +
989 "\" contains array which cannot be used in basic arithmetic operation.");
990 if (std::is_same<T, midas::odb>::value) {
991 if (is_auto_refresh_read()) {
992 read();
993 i.read();
994 }
995 // subtracting two midas::odb objects is best done in double
996 double s1 = static_cast<double>(m_data[0]);
997 double s2 = static_cast<double>(i.m_data[0]);
998 return s1 - s2;
999 } else {
1001 read();
1002 T s = (T) m_data[0];
1003 return s - i;
1004 }
1005 }
1006
1007 template<typename T>
1008 T operator*(const T i) {
1009 if (m_num_values > 1)
1010 mthrow("ODB key \"" + get_full_path() +
1011 "\" contains array which cannot be used in basic arithmetic operation.");
1013 read();
1014 T s = (T) m_data[0];
1015 return s * i;
1016 }
1017
1018 template<typename T>
1019 T operator/(const T i) {
1020 if (m_num_values > 1)
1021 mthrow("ODB key \"" + get_full_path() +
1022 "\" contains array which cannot be used in basic arithmetic operation.");
1024 read();
1025 T s = (T) m_data[0];
1026 return s / i;
1027 }
1028
1031 read();
1032 for (int i = 0; i < m_num_values; i++)
1033 m_data[i].add(1, false);
1034 if (this->is_auto_refresh_write())
1035 write();
1036 return *this;
1037 }
1038
1040 // create temporary object
1041 odb o(this);
1043 read();
1044 for (int i = 0; i < m_num_values; i++)
1045 m_data[i].add(1, false);
1046 if (this->is_auto_refresh_write())
1047 write();
1048 return o;
1049 }
1050
1053 read();
1054 for (int i = 0; i < m_num_values; i++)
1055 m_data[i].add(-1, false);
1056 if (this->is_auto_refresh_write())
1057 write();
1058 return *this;
1059 }
1060
1062 // create temporary object
1063 odb o(this);
1065 read();
1066 for (int i = 0; i < m_num_values; i++)
1067 m_data[i].add(-1, false);
1068 if (this->is_auto_refresh_write())
1069 write();
1070 return o;
1071 }
1072
1073 odb &operator+=(double d) {
1075 read();
1076 for (int i = 0; i < m_num_values; i++)
1077 m_data[i].add(d, false);
1078 if (this->is_auto_refresh_write())
1079 write();
1080 return *this;
1081 }
1082
1083 odb &operator-=(double d) {
1085 read();
1086 for (int i = 0; i < m_num_values; i++)
1087 m_data[i].add(-d, false);
1088 if (this->is_auto_refresh_write())
1089 write();
1090 return *this;
1091 }
1092
1093 odb &operator*=(double d) {
1095 read();
1096 for (int i = 0; i < m_num_values; i++)
1097 m_data[i].mult(d, false);
1098 if (this->is_auto_refresh_write())
1099 write();
1100 return *this;
1101 }
1102
1103 odb &operator/=(double d) {
1105 read();
1106 if (d == 0)
1107 mthrow("Division by zero");
1108 for (int i = 0; i < m_num_values; i++)
1109 m_data[i].mult(1 / d, false);
1110 if (this->is_auto_refresh_write())
1111 write();
1112 return *this;
1113 }
1114
1115 // overload comparison operators
1116 template<typename T>
1117 friend bool operator==(const midas::odb &o, const T &d);
1118 template<typename T>
1119 friend bool operator==(const T &d, const midas::odb &o);
1120 template<typename T>
1121 friend bool operator!=(const midas::odb &o, const T &d);
1122 template<typename T>
1123 friend bool operator!=(const T &d, const midas::odb &o);
1124 template<typename T>
1125 friend bool operator<(const midas::odb &o, const T &d);
1126 template<typename T>
1127 friend bool operator<(const T &d, const midas::odb &o);
1128 template<typename T>
1129 friend bool operator<=(const midas::odb &o, const T &d);
1130 template<typename T>
1131 friend bool operator<=(const T &d, const midas::odb &o);
1132 template<typename T>
1133 friend bool operator>(const midas::odb &o, const T &d);
1134 template<typename T>
1135 friend bool operator>(const T &d, const midas::odb &o);
1136 template<typename T>
1137 friend bool operator>=(const midas::odb &o, const T &d);
1138 template<typename T>
1139 friend bool operator>=(const T &d, const midas::odb &o);
1140
1141 // create midas::odb object form MXML node
1143 std::string type(mxml_get_name(node));
1144
1145 unsigned int tid = 0;
1146 if (type == "dir")
1147 tid = TID_KEY;
1148 else {
1149 for (tid = 0; tid < TID_LAST; tid++) {
1151 break;
1152 }
1153 }
1154 if (tid == TID_LAST)
1155 mthrow("Wrong key type in XML file");
1156
1157 if (o == nullptr)
1158 o = new midas::odb();
1159 o->set_tid(tid);
1160 o->set_name(mxml_get_attribute(node, "name"));
1161 if (mxml_get_attribute(node, "handle") == nullptr)
1162 mthrow("No \"handle\" attribute found in XML data");
1163 o->set_hkey(std::stoi(std::string(mxml_get_attribute(node, "handle"))));
1164
1165 if (type == "key") {
1166 std::string value(mxml_get_value(node));
1167 o->set(value);
1168 } else if (type == "keyarray") {
1169 int n = std::atoi(mxml_get_attribute(node, "num_values"));
1170 o->set_num_values(n);
1171 for (int i=0 ; i<n ; i++) {
1172 std::string value(mxml_get_value(mxml_subnode(node, i)));
1173 o->set(value, i);
1174 }
1175 } else if (type == "dir") {
1177 o->set_num_values(n);
1178 for (int i = 0; i < n; i++) {
1180 os->set_parent(o);
1181 o->set_odb(os, i);
1182 }
1183 } else
1184 mthrow("Unexpected XML element " + std::string(mxml_get_name(node)));
1185
1186 return o;
1187 };
1188
1189 // Deep copy
1190 void deep_copy(odb &d, const odb &s);
1191
1192 // Setters and Getters
1198
1204
1210
1211 bool is_dirty() const { return m_flags[odb_flags::DIRTY]; }
1212 void set_dirty(bool f) { m_flags[odb_flags::DIRTY] = f; }
1213
1219
1225
1231
1237
1238 // Static functions
1239 static void set_debug(bool flag) { s_debug = flag; }
1240 static bool get_debug() { return s_debug; }
1241 static int create(const char *name, int type = TID_KEY);
1242 static bool exists(const std::string &name);
1243 static int delete_key(const std::string &name);
1244 static void load(const std::string &filename, const std::string &odb_path);
1245
1246 void odb_from_xml(const std::string &str);
1247 void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults = false);
1248 void connect(std::string str, bool write_defaults = false, bool delete_keys_not_in_defaults = false);
1249 void connect_and_fix_structure(std::string path);
1250 static bool is_connected_odb() { return s_connected_odb; }
1251
1252 void read();
1253 void read(int index);
1254 void write(int str_size = 0);
1255 void write(int index, int str_size);
1256 std::string print();
1257 std::string dump();
1258 void print(std::string &s, int indent=0);
1259 void dump(std::string &s, int indent=0);
1260 void save(const std::string &filename);
1261 void delete_key();
1262 int size();
1263 void resize(int size);
1264 void resize(int size, bool b);
1265 void watch(std::function<void(midas::odb &)> f);
1266 void unwatch();
1267 void set(std::string str);
1268 void set(std::string s, int i);
1269 void set_odb(odb *o, int i);
1270 void set_string_size(std::string s, int size);
1271
1272 bool is_subkey(std::string str);
1273 HNDLE get_hkey() { return m_hKey; }
1274 std::string get_full_path();
1275 std::string get_parent_path();
1276 int get_tid() { return m_tid; }
1278 std::string get_name() { return m_name; }
1279 odb& items() { return *this; }
1280
1281 std::string s() {
1282 std::string s;
1283 get(s);
1284 return s;
1285 }
1286
1287 void fix_order(std::vector<std::string> target_subkey_order);
1288
1289 void set_mode(int mode);
1290 int get_mode();
1291
1292 unsigned int get_last_written();
1293 };
1294
1295 //---- midas::odb friend functions -------------------------------
1296
1297 // overload comparison operators
1298 template<typename T>
1299 bool operator==(const midas::odb &o, const T &d) {
1300 // the operator needs a "const midas::odb" reference,
1301 // so we have to make a non-const copy
1302 T v;
1303 midas::odb oc(o);
1304 oc.get(v);
1305 return v == d;
1306 }
1307
1308 template<typename T>
1309 bool operator==(const T &d, const midas::odb &o) {
1310 T v;
1311 midas::odb oc(o);
1312 oc.get(v);
1313 return d == v;
1314 }
1315
1316 template<typename T>
1317 bool operator!=(const midas::odb &o, const T &d) {
1318 T v;
1319 midas::odb oc(o);
1320 oc.get(v);
1321 return v != d;
1322 }
1323
1324 template<typename T>
1325 bool operator!=(const T &d, const midas::odb &o) {
1326 T v;
1327 midas::odb oc(o);
1328 oc.get(v);
1329 return d != v;
1330 }
1331
1332 template<typename T>
1333 bool operator<(const midas::odb &o, const T &d) {
1334 T v;
1335 midas::odb oc(o);
1336 oc.get(v);
1337 return v < d;
1338 }
1339
1340 template<typename T>
1341 bool operator<(const T &d, const midas::odb &o) {
1342 T v;
1343 midas::odb oc(o);
1344 oc.get(v);
1345 return d < v;
1346 }
1347
1348 template<typename T>
1349 bool operator<=(const midas::odb &o, const T &d) {
1350 T v;
1351 midas::odb oc(o);
1352 oc.get(v);
1353 return v <= d;
1354 }
1355
1356 template<typename T>
1357 bool operator<=(const T &d, const midas::odb &o) {
1358 T v;
1359 midas::odb oc(o);
1360 oc.get(v);
1361 return d <= v;
1362 }
1363
1364 template<typename T>
1365 bool operator>(const midas::odb &o, const T &d) {
1366 T v;
1367 midas::odb oc(o);
1368 oc.get(v);
1369 return v > d;
1370 }
1371
1372 template<typename T>
1373 bool operator>(const T &d, const midas::odb &o) {
1374 T v;
1375 midas::odb oc(o);
1376 oc.get(v);
1377 return d > v;
1378 }
1379
1380 template<typename T>
1381 bool operator>=(const midas::odb &o, const T &d) {
1382 T v;
1383 midas::odb oc(o);
1384 oc.get(v);
1385 return v >= d;
1386 }
1387
1388 template<typename T>
1389 bool operator>=(const T &d, const midas::odb &o) {
1390 T v;
1391 midas::odb oc(o);
1392 oc.get(v);
1393 return d >= v;
1394 }
1395
1396} // namespace midas
1397
1398
1399#endif // _ODBXX_HXX
iterator operator++()
Definition odbxx.h:415
iterator operator++(int)
Definition odbxx.h:421
iterator(u_odb *pu)
Definition odbxx.h:412
u_odb & operator*()
Definition odbxx.h:429
bool operator!=(const iterator &other) const
Definition odbxx.h:427
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1525
std::string get_parent_path()
Definition odbxx.cxx:307
odb operator=(odb &&o)=delete
odb(std::initializer_list< T > list)
Definition odbxx.h:594
odb & operator*=(double d)
Definition odbxx.h:1093
std::string get_full_path()
Definition odbxx.cxx:291
int m_num_values
Definition odbxx.h:455
iterator end() const
Definition odbxx.h:960
static bool exists(const std::string &name)
Definition odbxx.cxx:66
midas::odb * get_parent()
Definition odbxx.h:525
odb & operator+=(double d)
Definition odbxx.h:1073
std::string get_name()
Definition odbxx.h:1278
int m_tid
Definition odbxx.h:449
void set_mode(int mode)
Definition odbxx.cxx:1413
void set_auto_refresh_read(bool f)
Definition odbxx.h:1200
void set_auto_enlarge_array(bool f)
Definition odbxx.h:1221
odb(const std::array< T, SIZE > &arr)
Definition odbxx.h:610
void delete_key()
Definition odbxx.cxx:1384
void set_odb(odb *o, int i)
Definition odbxx.cxx:1539
u_odb * m_data
Definition odbxx.h:451
void deep_copy(odb &d, const odb &s)
Definition odbxx.cxx:263
bool is_deleted() const
Definition odbxx.h:516
static void set_debug(bool flag)
Definition odbxx.h:1239
odb & operator++()
Definition odbxx.h:1029
bool is_auto_refresh_read() const
Definition odbxx.h:1199
static void unwatch_all()
Definition odbxx.cxx:1486
static HNDLE s_hDB
Definition odbxx.h:438
HNDLE get_hkey()
Definition odbxx.h:1273
std::function< void(midas::odb &)> m_watch_callback
Definition odbxx.h:461
bool is_auto_create() const
Definition odbxx.h:1214
bool is_preserve_string_size() const
Definition odbxx.h:1193
static void watch_callback(int hDB, int hKey, int index, void *info)
Definition odbxx.cxx:114
odb(const std::array< std::string, SIZE > &arr)
Definition odbxx.h:624
void unwatch()
Definition odbxx.cxx:1474
T operator+(T i)
Definition odbxx.h:964
u_odb & operator[](int index)
Definition odbxx.h:888
T get()
Definition odbxx.h:480
odb(std::initializer_list< std::pair< const char *, midas::odb > > list)
Definition odbxx.h:565
int get_tid()
Definition odbxx.h:1276
static bool get_debug()
Definition odbxx.h:1240
bool is_auto_refresh_write() const
Definition odbxx.h:1205
u_odb & get_mdata(int index=0)
Definition odbxx.h:504
friend bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1299
void set_tid(int tid)
Definition odbxx.h:519
odb & operator[](const char *str)
Definition odbxx.h:926
bool read_key(const std::string &path)
Definition odbxx.cxx:571
friend bool operator>=(const midas::odb &o, const T &d)
Definition odbxx.h:1381
friend bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1349
friend bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1333
void resize(int size)
Definition odbxx.cxx:320
T operator/(const T i)
Definition odbxx.h:1019
void set_preserve_string_size(bool f)
Definition odbxx.h:1194
void set_trigger_hotlink(bool f)
Definition odbxx.h:1233
odb(T v)
Definition odbxx.h:557
int size()
Definition odbxx.cxx:315
void set_flags(uint32_t f)
Definition odbxx.h:513
void set_auto_refresh_write(bool f)
Definition odbxx.h:1206
int get_mode()
Definition odbxx.cxx:1430
odb & operator--()
Definition odbxx.h:1051
void set_auto_create(bool f)
Definition odbxx.h:1215
void read()
Definition odbxx.cxx:716
void resize_mdata(int size)
Definition odbxx.cxx:190
friend bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1365
bool is_dirty() const
Definition odbxx.h:1211
const std::vector< T > & operator=(const std::vector< T > &v)
Definition odbxx.h:750
iterator begin() const
Definition odbxx.h:959
const T & operator=(const T &v)
Definition odbxx.h:723
odb & get_subkey(std::string str)
Definition odbxx.cxx:482
odb & operator()(T v)
Definition odbxx.h:932
void set_hkey(HNDLE hKey)
Definition odbxx.h:511
odb & operator/=(double d)
Definition odbxx.h:1103
void set_flags_recursively(uint32_t f)
Definition odbxx.cxx:142
unsigned int get_last_written()
Definition odbxx.cxx:1444
odb operator--(int)
Definition odbxx.h:1061
void set_name(std::string s)
Definition odbxx.h:522
int get_subkeys(std::vector< std::string > &name)
Definition odbxx.cxx:546
void watch(std::function< void(midas::odb &)> f)
Definition odbxx.cxx:1458
odb(const char *s)
Definition odbxx.h:668
int get_last_index()
Definition odbxx.h:955
std::string s()
Definition odbxx.h:1281
friend std::ostream & operator<<(std::ostream &output, odb &o)
Definition odbxx.h:877
bool is_auto_enlarge_array() const
Definition odbxx.h:1220
friend bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1317
int detect_type(const T &)
Definition odbxx.h:686
void save(const std::string &filename)
Definition odbxx.cxx:436
void set_last_index(int i)
Definition odbxx.h:956
odb(const std::string &str, bool init_via_xml=false)
Definition odbxx.h:638
static int create(const char *name, int type=TID_KEY)
Definition odbxx.cxx:130
bool is_subkey(std::string str)
Definition odbxx.cxx:458
static bool s_debug
Definition odbxx.h:440
void fix_order(std::vector< std::string > target_subkey_order)
Definition odbxx.cxx:1228
std::string dump()
Definition odbxx.cxx:356
int m_last_index
Definition odbxx.h:457
odb operator++(int)
Definition odbxx.h:1039
void connect_and_fix_structure(std::string path)
Definition odbxx.cxx:1370
static bool s_connected_odb
Definition odbxx.h:442
const std::array< T, SIZE > & operator=(const std::array< T, SIZE > &arr)
Definition odbxx.h:796
static void init_hdb()
Definition odbxx.cxx:43
int get_num_values()
Definition odbxx.h:1277
operator std::string()
Definition odbxx.h:828
odb & operator-=(double d)
Definition odbxx.h:1083
void set_num_values(int n)
Definition odbxx.h:520
uint32_t get_flags()
Definition odbxx.h:514
bool is_trigger_hotlink() const
Definition odbxx.h:1232
bool write_key(std::string &path, bool write_defaults)
Definition odbxx.cxx:657
std::string print()
Definition odbxx.cxx:348
static midas::odb * search_hkey(midas::odb *po, int hKey)
Definition odbxx.cxx:52
static bool is_connected_odb()
Definition odbxx.h:1250
odb(std::initializer_list< const char * > list)
Definition odbxx.h:672
std::bitset< 9 > m_flags
Definition odbxx.h:447
static std::vector< midas::odb > m_watch
Definition odbxx.h:444
odb & operator[](std::string str)
Definition odbxx.h:922
void set_deleted(bool f)
Definition odbxx.h:517
static void load(const std::string &filename, const std::string &odb_path)
Definition odbxx.cxx:92
midas::odb * odb_from_xml(PMXML_NODE node, odb *o)
Definition odbxx.h:1142
void set_parent(midas::odb *p)
Definition odbxx.h:524
HNDLE m_hKey
Definition odbxx.h:459
T operator-(T i)
Definition odbxx.h:986
void set_write_protect(bool f)
Definition odbxx.h:1227
std::string m_name
Definition odbxx.h:453
void get(T &v)
Definition odbxx.h:492
bool is_write_protect() const
Definition odbxx.h:1226
T operator*(const T i)
Definition odbxx.h:1008
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
Definition odbxx.cxx:1291
odb & items()
Definition odbxx.h:1279
void set_dirty(bool f)
Definition odbxx.h:1212
midas::odb * m_parent
Definition odbxx.h:463
void set(const char *v)
Definition odbxx.h:226
u_odb & operator/=(double d)
Definition odbxx.h:275
uint8_t m_uint8
Definition odbxx.h:50
bool m_bool
Definition odbxx.h:58
uint8_t operator=(uint8_t v)
Definition odbxx.cxx:1601
void set_tid(int tid)
Definition odbxx.h:103
void mult(double f, bool push=true)
Definition odbxx.cxx:1826
void set_string(std::string s)
Definition odbxx.h:170
u_odb(uint8_t v)
Definition odbxx.h:72
u_odb(int8_t v)
Definition odbxx.h:74
u_odb & operator+(T v)
Definition odbxx.h:283
int8_t m_int8
Definition odbxx.h:51
u_odb(double v)
Definition odbxx.h:92
uint64_t m_uint64
Definition odbxx.h:56
u_odb & operator--(int)
Definition odbxx.h:250
u_odb & operator+=(double d)
Definition odbxx.h:260
int32_t m_int32
Definition odbxx.h:55
u_odb(float v)
Definition odbxx.h:90
int64_t m_int64
Definition odbxx.h:57
void set(T v)
Definition odbxx.h:140
double m_double
Definition odbxx.h:60
u_odb & operator/(T v)
Definition odbxx.h:307
odb * m_parent_odb
Definition odbxx.h:66
u_odb & operator*=(double d)
Definition odbxx.h:270
u_odb & operator++()
Definition odbxx.h:245
void set_odb(odb *v)
Definition odbxx.h:187
u_odb(std::string *v)
Definition odbxx.h:94
int m_tid
Definition odbxx.h:65
void set_parent(odb *o)
Definition odbxx.h:100
void set(std::string v)
Definition odbxx.h:193
u_odb & operator++(int)
Definition odbxx.h:240
void set(odb *v)
Definition odbxx.h:181
friend std::ostream & operator<<(std::ostream &output, u_odb &o)
Definition odbxx.h:380
u_odb(int16_t v)
Definition odbxx.h:78
u_odb & operator-(T v)
Definition odbxx.h:291
u_odb(uint32_t v)
Definition odbxx.h:80
uint16_t m_uint16
Definition odbxx.h:52
odb * get_podb()
Definition odbxx.h:367
void set_string_size(std::string s, int size)
Definition odbxx.cxx:1716
int16_t m_int16
Definition odbxx.h:53
u_odb & operator--()
Definition odbxx.h:255
odb & get_odb()
Definition odbxx.h:373
u_odb & operator-=(double d)
Definition odbxx.h:265
std::string s()
Definition odbxx.h:359
u_odb(int64_t v)
Definition odbxx.h:86
u_odb(uint64_t v)
Definition odbxx.h:84
u_odb(int32_t v)
Definition odbxx.h:82
std::string * m_string
Definition odbxx.h:61
void set_string_ptr(std::string *s)
Definition odbxx.h:177
std::string get()
Definition odbxx.h:346
u_odb(uint16_t v)
Definition odbxx.h:76
odb * get_parent()
Definition odbxx.h:101
u_odb & operator*(T v)
Definition odbxx.h:299
odb * m_odb
Definition odbxx.h:62
float m_float
Definition odbxx.h:59
uint32_t m_uint32
Definition odbxx.h:54
u_odb(bool v)
Definition odbxx.h:88
void set(char *v)
Definition odbxx.h:230
std::string get_value()
Definition odbxx.h:352
int get_tid()
Definition odbxx.h:105
#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
INT i
Definition mdump.cxx:32
#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:1381
bool operator>(const midas::odb &o, const T &d)
Definition odbxx.h:1365
bool operator==(const midas::odb &o, const T &d)
Definition odbxx.h:1299
bool operator<(const midas::odb &o, const T &d)
Definition odbxx.h:1333
odb_flags
Definition odbxx.h:391
@ AUTO_REFRESH_WRITE
Definition odbxx.h:393
@ DIRTY
Definition odbxx.h:397
@ TRIGGER_HOTLINK
Definition odbxx.h:400
@ AUTO_REFRESH_READ
Definition odbxx.h:392
@ WRITE_PROTECT
Definition odbxx.h:399
@ AUTO_ENLARGE_ARRAY
Definition odbxx.h:396
@ AUTO_CREATE
Definition odbxx.h:395
@ PRESERVE_STRING_SIZE
Definition odbxx.h:394
@ DELETED
Definition odbxx.h:398
bool operator<=(const midas::odb &o, const T &d)
Definition odbxx.h:1349
bool operator!=(const midas::odb &o, const T &d)
Definition odbxx.h:1317
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