ARB
ad_hcb.h
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : ad_hcb.h //
4 // Purpose : hierarchical callbacks //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in January 2014 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =============================================================== //
11 
12 #ifndef AD_HCB_H
13 #define AD_HCB_H
14 
15 #ifndef ARBDB_BASE_H
16 #include "arbdb_base.h"
17 #endif
18 #ifndef GB_LOCAL_H
19 #include "gb_local.h"
20 #endif
21 #ifndef GB_KEY_H
22 #include "gb_key.h"
23 #endif
24 
25 // --------------------------------
26 // hierarchical callbacks
27 
28 
32  static const int MAX_HIERARCHY_DEPTH = 10; // no real limit, just avoids dynamic allocation
33  GBQUARK quark[MAX_HIERARCHY_DEPTH];
34  int depth; // depth for bottom-up-match of hierarchy (normally INT_MAX, i.e. unrestricted)
35 
36  void invalidate() { quark[0] = 0; }
37 
38 public:
39  explicit gb_hierarchy_location(GBDATA *gbd) :
40  depth(INT_MAX)
41  {
42  for (int offset = 0; gbd; ++offset) {
43  gb_assert(offset<MAX_HIERARCHY_DEPTH); // increase MAX_HIERARCHY_DEPTH (or use dynamic mem)
44  quark[offset] = GB_KEY_QUARK(gbd);
45  if (!quark[offset]) return;
46 
47  gbd = gbd->get_father();
48  }
49  gb_assert(0); // did not reach DB-root (invalid entry?)
50  }
51  gb_hierarchy_location(GBDATA *gb_main, const char *db_path);
52 
53  bool is_valid() const { return quark[0] != 0; }
54  bool is_submatch() const { gb_assert(is_valid()); return depth != INT_MAX; }
55 
56  bool matches(GBDATA *gbd) const {
58  if (is_valid()) {
59  for (int offset = 0; gbd; ++offset) {
60  if (offset == depth) {
62  return true;
63  }
64  GBQUARK q = GB_KEY_QUARK(gbd);
65  if (!quark[offset]) return !q;
66  if (q != quark[offset]) return false;
67 
68  gbd = gbd->get_father();
69  }
70  gb_assert(0); // went beyond root
71  }
72  return false;
73  }
74 
75  bool operator == (const gb_hierarchy_location& other) const {
76  if (is_valid() &&
77  other.is_valid() &&
78  is_submatch() == other.is_submatch() &&
79  implicated(is_submatch(), depth == other.depth)
80  )
81  {
82  int offset;
83  for (offset = 0; quark[offset]; ++offset) {
84  if (quark[offset] != other.quark[offset]) return false;
85  }
86  return other.quark[offset] == 0;
87  }
88  return false;
89  }
90 
91  char *get_db_path(GBDATA *gb_main) const;
92 };
93 
96 public:
98  : gb_callback(spec_),
99  loc(loc_)
100  {}
101  bool triggered_by(GBDATA *gbd) const { return loc.matches(gbd); }
102  const gb_hierarchy_location& get_location() const { return loc; }
103 };
104 
105 struct gb_hierarchy_callback_list : public CallbackList<gb_hierarchy_callback> {
106  // need forward decl for gb_hierarchy_callback_list, i.e. cant use a simple typedef here
107 };
108 
109 #else
110 #error ad_hcb.h included twice
111 #endif // AD_HCB_H
112 
113 
#define implicated(hypothesis, conclusion)
Definition: arb_assert.h:289
bool is_valid() const
Definition: ad_hcb.h:53
const gb_hierarchy_location & get_location() const
Definition: ad_hcb.h:102
char * get_db_path(GBDATA *gb_main) const
Definition: ad_cb.cxx:54
gb_hierarchy_callback(const TypedDatabaseCallback &spec_, const gb_hierarchy_location &loc_)
Definition: ad_hcb.h:97
bool triggered_by(GBDATA *gbd) const
Definition: ad_hcb.h:101
bool is_submatch() const
Definition: ad_hcb.h:54
bool matches(GBDATA *gbd) const
Definition: ad_hcb.h:56
bool operator==(const gb_hierarchy_location &other) const
Definition: ad_hcb.h:75
GBQUARK GB_KEY_QUARK(GBDATA *gbd)
Definition: gb_key.h:48
#define gb_assert(cond)
Definition: arbdbt.h:11
#define offset(field)
Definition: GLwDrawA.c:73
gb_hierarchy_location(GBDATA *gbd)
Definition: ad_hcb.h:39
GBDATA * gb_main
Definition: adname.cxx:33
GBCONTAINER * get_father()
Definition: gb_data.h:276