Free Electron
AccessorSet.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __data_AccessorSet_h__
8 #define __data_AccessorSet_h__
9 
10 namespace fe
11 {
12 
13 /** @brief Set of accessors
14 
15  @ingroup data
16 */
17 
18 class FE_DL_EXPORT AccessorSet : virtual public PopulateI,
19  public CastableAs<AccessorSet>
20 {
21  public:
22  AccessorSet(void)
23  {
24  setActive(false);
25  }
26  AccessorSet(sp<Scope> spScope)
27  {
28  setActive(false);
29  bind(spScope);
30  }
31 virtual ~AccessorSet(void)
32  {
33  if(m_hpScope.isValid())
34  {
35  m_hpScope->removeAccessorSet(this);
36  }
37  }
38 virtual FE_UWORD size(void) const { return m_accessors.size(); }
39 virtual BaseAccessor *operator[](FE_UWORD index)
40  {
41  return m_accessors[index];
42  }
43 
44  bool operator==(const AccessorSet &a_aset) const
45  {
46  if(!m_hpScope.isValid()) { feX("AccessorSet::==", "invalid left scope"); }
47  if(!a_aset.m_hpScope.isValid()) { feX("AccessorSet::==", "invalid right scope"); }
48 
49  if(m_hpScope != a_aset.m_hpScope) { return false; }
50 
51  return (m_bitset == a_aset.m_bitset);
52  }
53 
54  bool operator<(const AccessorSet &a_aset) const
55  {
56  if(!m_hpScope.isValid()) { feX("AccessorSet::<", "invalid left scope"); }
57  if(!a_aset.m_hpScope.isValid()) { feX("AccessorSet::<", "invalid right scope"); }
58  if(m_hpScope != a_aset.m_hpScope) { feX("AccessorSet::<", "scope mismatch"); }
59 
60  return (m_bitset < a_aset.m_bitset);
61  }
62 
63 
64  bool bind(const WeakRecord a_record)
65  {
66  if(!a_record.isValid()) { return false; }
67  bind(a_record.layout()->scope());
68  bool rv = check(a_record);
69  if(rv)
70  {
71  m_optional_record = a_record;
72  for(unsigned int i = 0; i < m_accessors.size(); i++)
73  {
74  m_accessors[i]->bind(a_record);
75  }
76  }
77  return rv;
78  }
79  void bind(sp<Scope> spScope)
80  {
81  if(!spScope.isValid())
82  {
83  feX("AccessorSet::bind",
84  "given invalid scope");
85  }
86  if(m_hpScope==spScope)
87  {
88  return;
89  }
90  if(m_hpScope.isValid())
91  {
92  feX("AccessorSet::bind","changed scope\n");
93  }
94  m_hpScope = spScope;
95 
96  t_bitset bitset(m_hpScope->attributes().size());
97  for(unsigned int j = 0; j < size(); j++)
98  {
99  bitset.set((*this)[j]->index());
100  }
101  setBitset(bitset);
102 
103  m_hpScope->addAccessorSet(this);
104 
105  setActive(true);
106  initializeAll();
107  }
108 virtual void populate(sp<Layout> spLayout)
109  {
110  if(!spLayout.isValid())
111  {
112  feX("AccessorSet::populate","has invalid layout\n");
113  }
114  bind(spLayout->scope());
115  for(unsigned int i = 0; i < size(); i++)
116  {
117  spLayout->populate(*((*this)[i]));
118  }
119  }
120  void enforceHaving(const AccessorSet &a_other)
121  {
122  if(!m_hpScope.isValid())
123  {
124  feX("AccessorSet::populate","unset scope\n");
125  }
126 
127  Array<String> self_set;
128  for(unsigned int i = 0; i < size(); i++)
129  {
130  self_set.push_back((*this)[i]->name());
131  }
132 
133  for(unsigned int i = 0; i < a_other.size(); i++)
134  {
135  m_hpScope->enforce(self_set, a_other.m_accessors[i]->name());
136  }
137  }
138  bool bindCheck(sp<Layout> spLayout)
139  {
140  bind(spLayout->scope());
141  return m_bitset.is_subset_of(spLayout->bitset());
142 #if 0
143  for(unsigned int i = 0; i < size(); i++)
144  {
145  if(!((*this)[i]->check(spLayout))) { return false; }
146  }
147  return true;
148 #endif
149  }
150  bool check(sp<LayoutSB> spLayout)
151  {
152  return m_bitset.is_subset_of(spLayout->bitset());
153  }
154  bool check(sp<LayoutAV> spLayout)
155  {
156  return m_bitset.is_subset_of(spLayout->bitset());
157  }
158 
159  bool bindCheck(sp<RecordArray> spRA)
160  {
161  bind(spRA->layout()->scope());
162  for(unsigned int i = 0; i < size(); i++)
163  {
164  if(!((*this)[i]->check(spRA))) { return false; }
165  }
166  return true;
167  }
168  bool check(sp<RecordArray> spRA)
169  {
170 // fe_fprintf(stderr, "CHECK %d\n", m_bitset.is_subset_of(spRA->layout()->bitset()));
171  return m_bitset.is_subset_of(spRA->layout()->bitset());
172 #if 0
173  for(unsigned int i = 0; i < size(); i++)
174  {
175  if(!((*this)[i]->check(spRA)))
176  {
177  return false;
178  }
179  }
180  return true;
181 #endif
182  }
183  bool check(const WeakRecord &a_record)
184  {
185  return m_bitset.is_subset_of(a_record.layout()->bitset());
186 #if 0
187  for(unsigned int i = 0; i < size(); i++)
188  {
189  if(!((*this)[i]->check(a_record)))
190  {
191  return false;
192  }
193  }
194 
195  return true;
196 #endif
197  }
198  bool check(const Record &a_record)
199  {
200  return m_bitset.is_subset_of(a_record.layout()->bitset());
201 #if 0
202  for(unsigned int i = 0; i < size(); i++)
203  {
204  if(!((*this)[i]->check(a_record)))
205  {
206  return false;
207  }
208  }
209 
210  return true;
211 #endif
212  }
213  void check(const WeakRecord a_record,
214  const char *a_annotation)
215  {
216  for(unsigned int i = 0; i < size(); i++)
217  {
218  if(!((*this)[i]->check(a_record)))
219  {
220  feX("AccessorSet::assert",
221  "%s | %s | missing %s",
222  (a_annotation!=NULL)?a_annotation:"",
223  a_record.layout()->name().c_str(),
224  (*this)[i]->attribute()->name().c_str());
225  }
226  }
227  }
228  void enforce(const String &a_ifHas)
229  {
230  for(unsigned int i = 0; i < size(); i++)
231  {
232  m_hpScope->enforce(a_ifHas, (*this)[i]->attribute()->name());
233  }
234  }
235 
236  void filter(sp<RecordGroup> rg_output, sp<RecordGroup> rg_input)
237  {
238  for(RecordGroup::iterator i_in = rg_input->begin();
239  i_in != rg_input->end(); i_in++)
240  {
241  bind((*i_in)->layout()->scope());
242  if(check(*i_in))
243  {
244  for(int i = (*i_in)->length() - 1; i >= 0; i--)
245  {
246  rg_output->add((*i_in)->getRecord(i));
247  }
248  }
249  }
250  }
251  hp<Scope> scope(void) { return m_hpScope; }
252 
253  void filter(std::vector<Record> &a_records, sp<RecordGroup> rg_input)
254  {
255  for(RecordGroup::iterator i_in = rg_input->begin();
256  i_in != rg_input->end(); i_in++)
257  {
258  bind((*i_in)->layout()->scope());
259  if(check(*i_in))
260  {
261  for(int i = (*i_in)->length() - 1; i >= 0; i--)
262  {
263  a_records.push_back((*i_in)->getRecord(i));
264  }
265  }
266  }
267  }
268 
269  void filter(std::vector<WeakRecord> &a_records, sp<RecordGroup> rg_input)
270  {
271  for(RecordGroup::iterator i_in = rg_input->begin();
272  i_in != rg_input->end(); i_in++)
273  {
274  bind((*i_in)->layout()->scope());
275  if(check(*i_in))
276  {
277  for(int i = (*i_in)->length() - 1; i >= 0; i--)
278  {
279  a_records.push_back((*i_in)->getRecord(i));
280  }
281  }
282  }
283  }
284  const t_bitset &bitset(void) const { return m_bitset; }
285  void setBitset(const t_bitset &a_bs) { m_bitset = a_bs; }
286  public:
287  //TODO: these adds are grossly bad/slow at scale. Fix.
288  void add(BaseAccessor &a_accessor, const String &a_attribute)
289  {
290  if(m_hpScope.isValid())
291  {
292  a_accessor.setup(m_hpScope, a_attribute);
293  m_accessors.push_back(&a_accessor);
294  t_bitset bitset(m_hpScope->attributes().size());
295  for(unsigned int j = 0; j < size(); j++)
296  {
297  bitset.set((*this)[j]->index());
298  }
299  setBitset(bitset);
300  }
301  if(m_optional_record.isValid())
302  {
303  a_accessor.bind(m_optional_record);
304  }
305  }
306  void add(BaseAccessor &a_accessor)
307  {
308  if(m_hpScope.isValid())
309  {
310  m_accessors.push_back(&a_accessor);
311  t_bitset bitset(m_hpScope->attributes().size());
312  for(unsigned int j = 0; j < size(); j++)
313  {
314  bitset.set((*this)[j]->index());
315  }
316  setBitset(bitset);
317  }
318  if(m_optional_record.isValid())
319  {
320  a_accessor.bind(m_optional_record);
321  }
322  }
323  void attach(const WeakRecord &a_record)
324  {
325  for(unsigned int i = 0; i < m_accessors.size(); i++)
326  {
327  m_accessors[i]->bind(a_record);
328  }
329  }
330  protected:
331  hp<Scope> m_hpScope;
332  Array<BaseAccessor*> m_accessors;
333  t_bitset m_bitset;
334  WeakRecord m_optional_record;
335 };
336 
337 } /* namespace */
338 
339 #endif /* __data_AccessorSet_h__ */
340 
Set of accessors.
Definition: AccessorSet.h:18
virtual void add(const Record &record)
Add record to the collection.
Definition: RecordGroup.cc:77
kernel
Definition: namespace.dox:3
const sp< LayoutSB > & layout(void) const
Return the Layout.
Definition: WeakRecordSB.h:251
sp< Layout > layout(void) const
Return the Layout.
Definition: RecordSB.h:189
void bind(const WeakRecord &a_record)
optionally bind to a record
Definition: Accessor.h:111
Type inspecific Accessor.
Definition: Accessor.h:26
Safe handle for shared pointer.
Definition: Handled.h:61
BWORD operator==(const DualString &s1, const DualString &s2)
Compare two DualString&#39;s.
Definition: DualString.h:208
Automatically reference-counted string container.
Definition: String.h:128
STL style iterator.
Definition: RecordGroup.h:124
Wrapper for std::vector.
Definition: Array.h:21
Reference to an instance of a Layout.
Definition: RecordSB.h:35
bool isValid(void) const
Return true if the record points to the original valid state block.
Definition: WeakRecordSB.h:181
void setup(sp< Scope > spScope, const String &attribute)
setup functions setup the accessor and also setup the Scope.
Definition: Accessor.cc:113
Populate a layout with attributes.
Definition: PopulateI.h:14
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192
Non-persistent reference to an instance of a Layout.
Definition: WeakRecordSB.h:17