Free Electron
Catalog.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 __core_Catalog_h__
8 #define __core_Catalog_h__
9 
10 #define FE_CAT_SPEC(name, description) name
11 #define FE_CAT(name) name
12 
13 namespace fe
14 {
15 
16 /**************************************************************************//**
17  @brief Dictionary of Arbitrary Instances
18 
19  @ingroup plugin
20 
21  TODO allow reordering
22  TODO allow individual removal (remember to also remove from order map)
23 *//***************************************************************************/
24 class FE_DL_EXPORT Catalog:
25  virtual public Component,
26  public CastableAs<Catalog>
27 {
28  public:
29 
30  class Remove
31  {
32  public:
33  bool operator==(const Remove &other) const { return true; }
34  };
35 
36  Catalog(void);
37 virtual ~Catalog(void);
38 
39  /** @brief Returns a mirror of the catalog
40 
41  All values shared references with the original.
42  */
43  sp<Catalog> catalogShallowCopy(void);
44 
45  /** @brief Returns a duplicate of the catalog
46 
47  All values are also copied by assignment.
48  */
49  sp<Catalog> catalogDeepCopy(void);
50 
51  /** @brief Returns the number of name keys
52 
53  Each name key may have any number of properties.
54  */
55  U32 catalogSize(void) const;
56 
57  /** @brief Returns a key by ordered index
58 
59  By default, keys are index in creation order.
60  */
61  String catalogKey(U32 index) const;
62 
63  /** @brief Returns keys in order of creation
64 
65  Keys are appended to the given array.
66  Clear the array if only want new values.
67 
68  If a regex pattern is given,
69  only matching keys are returned.
70 
71  Future improvements may allow reordering.
72  */
73  void catalogKeys(Array<String> &a_keys,
74  String a_pattern=".*") const;
75 
76  /** @brief Returns properties for a key
77 
78  Properties are appended to the given array.
79  Clear the array if only want new values.
80 
81  Order is arbitrary.
82  */
83  void catalogProperties(String a_name,
84  Array<String> &a_properties) const;
85 
86  /** @brief Returns TRUE if the given property for
87  the given name has been created.
88 
89  The default property is 'value'.
90  */
91  BWORD cataloged(String a_name,
92  String a_property="value") const;
93 
94  /** @brief Returns TRUE if any property for
95  the given name has been created.
96  */
97  BWORD catalogedAny(String a_name) const;
98 
99  /// @brief Remove all entries.
100  void catalogClear(void);
101 
102  /** @brief Duplicates entries from another catalog.
103 
104  Optionally, a list of type names limits which
105  entries are copied.
106  */
107  void catalogOverlay(sp<Catalog> a_spOtherCatalog,
108  Array<String>* a_pTypeList=NULL,
109  BWORD a_shallow=FALSE);
110 
111  /** @brief Returns a component entry of the given
112  property for the given name.
113 
114  If the entry does not exist,
115  it may be created using the given
116  implementation name.
117 
118  The return value will be invalid if the
119  implementation could not be instantiated.
120  */
121  sp<Component> catalogComponent(String implementation,
122  String a_name,String a_property="value");
123 
124  /** @brief Returns a component entry of the given
125  property for the given name.
126 
127  Regardless of whether the entry previously
128  existed, it is replaced by the given Component.
129 
130  The default property if 'value'.
131  */
132  sp<Component> catalogComponent(sp<Component> a_spComponent,
133  String a_name,String a_property="value");
134 
135  /** @brief Returns the literal Instance of the
136  given property for the given name.
137 
138  Regardless of whether the entry previously
139  existed, it is replaced by the given Instance.
140 
141  The default property is 'value'.
142  */
143  Instance& catalogInstance(Instance &instance,
144  String a_name,String a_property="value");
145 
146  /** @brief Returns the literal Instance of the
147  given property for the given name.
148 
149  If the entry does not exist, it will be created.
150 
151  The default property is 'value'.
152  */
153  Instance& catalogInstance(String a_name,
154  String a_property="value");
155 
156  /** @brief Returns the type_info of the
157  given property for the given name.
158 
159  If the entry does not exist, it will be created.
160 
161  The default property is 'value'.
162  */
163 const fe_type_info& catalogTypeInfo(String a_name,
164  String a_property="value") const;
165  /** @brief Returns the type name of the
166  given property, determined by the TypeMaster
167 
168  If the entry does not exist, it will be created.
169 
170  The default property is 'value'.
171  */
172 const String catalogTypeName(String a_name,
173  String a_property="value") const;
174 
175  /** @brief Returns TRUE if
176  given catalog entry match the template type
177  */
178  template <class T>
179  BWORD catalogTypeIs(String a_name,
180  String a_property="value") const;
181 
182  /** @brief Returns existing catalog entry
183  if already set or a default if not
184 
185  If entry does not exist, this version will
186  create an entry and set it to the appropriate
187  Type default.
188 
189  The default property is 'value'.
190  */
191  template <class T>
192  T& catalog(String a_name,String a_property="value");
193 
194  /** @brief Returns existing catalog entry
195  if already set or default if not
196 
197  If entry does not exist, this version will
198  create an entry and set it to the given default.
199  */
200  template <class T>
201  T& catalog(String a_name,String a_property,
202  const T& a_default);
203 // template <class T>
204 // T& catalog(String a_name,const T& a_default)
205 // { return catalog(a_name,"value",a_default); }
206 
207  /** @brief Returns existing catalog entry
208  if already set or default if not
209 
210  If entry does not exist, this version will
211  not create an entry and simply return
212  the given default.
213 
214  The default property is 'value'.
215  */
216  template <class T>
217 const T& catalogOrDefault(String a_name,String a_property,
218  const T& a_default) const;
219  template <class T>
220 const T& catalogOrDefault(String a_name,
221  const T& a_default) const
222  { return catalogOrDefault(a_name,
223  "value",a_default); }
224 
225  /** @brief Returns existing catalog entry,
226  converted to a String
227 
228  If entry does not exist,
229  an empty String is returned.
230 
231  The default property is 'value'.
232  */
233  String catalogValue(String a_name,
234  String a_property="value") const;
235 
236  /** @brief Converts a catalog entry,
237  into raw binary
238 
239  Returns the number of bytes in the buffer.
240 
241  If entry does not exist,
242  zero bytes is returned.
243  */
244  I32 catalogBytes(String a_name,
245  String a_property,
246  Array<U8>& a_rByteArray) const;
247 
248  /** @brief Sets the value for a catalog entry,
249  converted to the existing type,
250  from a given String
251 
252  If entry does not exist,
253  it is not created.
254 
255  The default property is 'value'.
256  */
257  BWORD catalogSet(String a_name,
258  String a_property,
259  String a_value);
260  BWORD catalogSet(String a_name,
261  String a_value)
262  { return catalogSet(a_name,
263  "value",a_value); }
264 
265  /** @brief Sets the value for a catalog entry,
266  converted to the existing type,
267  from a given String
268 
269  If entry does not exist,
270  it is created using the named type.
271 
272  If the Instance pointer pointer is not null.
273  the contained pointer is set to point to
274  the instance.
275  This can save the time of immediately doing
276  another map lookup, if you need the instance.
277  */
278  BWORD catalogSet(String a_name,
279  String a_property,
280  String a_type,
281  String a_value,
282  Instance** a_ppInstance=NULL);
283 
284  /** @brief Sets the value for a catalog entry,
285  using a raw byte block
286 
287  If entry does not exist, it is created.
288 
289  If the Instance pointer pointer is not null.
290  the contained pointer is set to point to
291  the instance.
292  This can save the time of immediately doing
293  another map lookup, if you need the instance.
294  */
295  BWORD catalogSet(String a_name,
296  String a_property,
297  String a_type,
298  const U8* a_pRawBytes,
299  I32 a_byteCount,
300  Instance** a_ppInstance=NULL);
301 
302  /** @brief Returns an existing catalog entry,
303  if it exists
304 
305  If entry does not exist, this version will
306  throw an exception.
307 
308  The default property is 'value'.
309  */
310  template <class T>
311  T& catalogOrException(String a_name,
312  String a_property) const;
313 
314  /** @brief Gets the Instance of
315  an existing catalog entry, if it exists
316 
317  If entry does not exist,
318  the method return false.
319 
320  The default property is 'value'.
321  */
322  bool catalogLookup(const String a_name,
323  String a_property,
324  Instance &a_instance) const;
325  bool catalogLookup(const String a_name,
326  Instance &a_instance) const
327  { return catalogLookup(a_name,"value",
328  a_instance); }
329 
330  /// @brief Move all properties for name to bottom
331  void catalogMoveToEnd(String a_name);
332 
333  /// @brief Remove all properties for a name
334  void catalogRemove(String a_name);
335 
336  /// @brief Remove one property for a name
337  void catalogRemove(String a_name,String a_property);
338 
339  /** @brief Print a description of the catalog
340  to the log
341  */
342  void catalogDump(void) const;
343 
344  sp<TypeMaster> typeMaster(void) const;
345 
346  private:
347 
348  template<class T>
349  T& createInstance(String a_name,
350  String a_property="value");
351 
352  std::map< String, InstanceMap > m_instanceMapMap;
353  std::map< I32, String > m_orderMap;
354  I32 m_highest;
355 };
356 
357 template<class T>
358 T& Catalog::createInstance(String a_name,String a_property)
359 {
360  if(!catalogedAny(a_name))
361  {
362  m_orderMap[++m_highest]=a_name;
363  }
364  T& rT=m_instanceMapMap[a_name][a_property].create<T>(typeMaster());
365 #if FE_COUNTED_TRACK
366  Counted::trackReference(&rT,this,"Catalog "+FE_TYPESTRING(T));
367 #endif
368  return rT;
369 }
370 
371 template<class T>
372 T &Catalog::catalog(String a_name,String a_property)
373 {
374  if(!cataloged(a_name,a_property))
375  {
376  return createInstance<T>(a_name,a_property);
377  }
378  return m_instanceMapMap[a_name][a_property].cast<T>();
379 }
380 
381 template<class T>
382 T &Catalog::catalog(String a_name,String a_property,const T& a_default)
383 {
384  if(!cataloged(a_name,a_property))
385  {
386  createInstance<T>(a_name,a_property)=a_default;
387  }
388  return m_instanceMapMap[a_name][a_property].cast<T>();
389 }
390 
391 template<class T>
392 const T& Catalog::catalogOrDefault(String a_name,String a_property,
393  const T& a_default) const
394 {
395  std::map<String, InstanceMap>::const_iterator it=
396  m_instanceMapMap.find(a_name);
397  if(it==m_instanceMapMap.end())
398  {
399  return a_default;
400  }
401 
402  const std::map<String, Instance>& instanceMap=it->second;
403 
404  std::map<String, Instance>::const_iterator it2=
405  instanceMap.find(a_property);
406  if(it2==instanceMap.end())
407  {
408  return a_default;
409  }
410 
411  return it2->second.cast<T>();
412 }
413 
414 template<class T>
415 T &Catalog::catalogOrException(String a_name,String a_property) const
416 {
417  std::map<String, InstanceMap>::const_iterator it=
418  m_instanceMapMap.find(a_name);
419  if(it==m_instanceMapMap.end())
420  {
421  feX("Catalog::catalogOrException",
422  ("missing key '" + a_name + "'").c_str());
423  }
424 
425  const std::map<String, Instance>& instanceMap=it->second;
426 
427  std::map<String, Instance>::const_iterator it2=
428  instanceMap.find(a_property);
429  if(it2==instanceMap.end())
430  {
431  feX("Catalog::catalogOrException",
432  ("missing property '" + a_property +
433  "' for '" + a_name + "'").c_str());
434  }
435 
436  return it2->second.cast<T>();
437 }
438 
440  String a_name,String a_property)
441 {
442  sp<Component>& rspComponent=
443  createInstance< sp<Component> >(a_name,a_property);
444 
445  rspComponent=a_spComponent;
446 
447  return a_spComponent;
448 }
449 
450 inline Instance &Catalog::catalogInstance(String a_name,String a_property)
451 {
452  if(!catalogedAny(a_name))
453  {
454  m_orderMap[++m_highest]=a_name;
455  }
456  return m_instanceMapMap[a_name][a_property];
457 }
458 
460  String a_property)
461 {
462  if(!catalogedAny(a_name))
463  {
464  m_orderMap[++m_highest]=a_name;
465  }
466  m_instanceMapMap[a_name][a_property]=instance;
467  return m_instanceMapMap[a_name][a_property];
468 }
469 
470 inline const fe_type_info& Catalog::catalogTypeInfo(String a_name,
471  String a_property) const
472 {
473  std::map<String, InstanceMap>::const_iterator it=
474  m_instanceMapMap.find(a_name);
475  if(it==m_instanceMapMap.end())
476  {
477  return getTypeId<void>();
478  }
479 
480  const std::map<String, Instance>& instanceMap=it->second;
481 
482  std::map<String, Instance>::const_iterator it2=
483  instanceMap.find(a_property);
484  if(it2==instanceMap.end())
485  {
486  return getTypeId<void>();
487  }
488 
489  const Instance& rInstance=it2->second;
490  return rInstance.type()->typeinfo().ref();
491 }
492 
494  String a_property) const
495 {
496 // const Instance& rInstance=catalogInstance(a_name,a_property);
497  if(!cataloged(a_name,a_property))
498  {
499  return "";
500  }
501  const Instance& rInstance=m_instanceMapMap.at(a_name).at(a_property);
502 
503  const sp<BaseType> spBaseType=rInstance.type();
504  if(spBaseType.isNull())
505  {
506  feX("Catalog::catalogTypeName","invalid Instance");
507  return "<unknown>";
508  }
509 
510  String typeName=rInstance.type()->typeinfo().ref().name();
511 
512  std::list<String> typeNames;
513  typeMaster()->reverseLookup(spBaseType,typeNames);
514  if(typeNames.size()>0)
515  {
516  typeName= *(typeNames.begin());
517  }
518 
519  return typeName;
520 }
521 
522 template<class T>
523 inline BWORD Catalog::catalogTypeIs(String a_name,
524  String a_property) const
525 {
526  return (catalogTypeInfo(a_name,a_property)==getTypeId<T>());
527 }
528 
529 inline BWORD Catalog::catalogedAny(String a_name) const
530 {
531  std::map<String, InstanceMap>::const_iterator it=
532  m_instanceMapMap.find(a_name);
533 
534  return it!=m_instanceMapMap.end();
535 }
536 
537 inline BWORD Catalog::cataloged(String a_name,String a_property) const
538 {
539  std::map<String, InstanceMap>::const_iterator it=
540  m_instanceMapMap.find(a_name);
541 
542  return it!=m_instanceMapMap.end() &&
543  it->second.find(a_property) != it->second.end();
544 }
545 
547 {
548  for(std::map< I32, String >::iterator it = m_orderMap.begin();
549  it != m_orderMap.end(); it++)
550  {
551  if(it->second==a_name)
552  {
553  m_orderMap.erase(it->first);
554  m_orderMap[++m_highest]=a_name;
555  return;
556  }
557  }
558 }
559 
560 inline void Catalog::catalogRemove(String a_name)
561 {
562 #if FE_COUNTED_TRACK
563  std::map<String, InstanceMap>::iterator i_name=
564  m_instanceMapMap.find(a_name);
565 
566  if(i_name!=m_instanceMapMap.end())
567  {
568  InstanceMap& rInstanceMap=i_name->second;
569  for(std::map< String, Instance >::iterator i_prop=rInstanceMap.begin();
570  i_prop!=rInstanceMap.end(); i_prop++)
571  {
572  Counted::untrackReference(i_prop->second.data(),this);
573  }
574  }
575 #endif
576  m_instanceMapMap.erase(a_name);
577 
578  for(std::map< I32, String >::iterator it = m_orderMap.begin();
579  it != m_orderMap.end(); it++)
580  {
581  if(it->second==a_name)
582  {
583  m_orderMap.erase(it->first);
584  break;
585  }
586  }
587 }
588 
589 inline void Catalog::catalogRemove(String a_name,String a_property)
590 {
591  std::map<String, InstanceMap>::iterator i_name=
592  m_instanceMapMap.find(a_name);
593 
594  if(i_name!=m_instanceMapMap.end())
595  {
596  InstanceMap& rInstanceMap=i_name->second;
597 
598  std::map<String, Instance>::const_iterator i_prop=
599  rInstanceMap.find(a_property);
600  if(i_prop!=rInstanceMap.end())
601  {
602 #if FE_COUNTED_TRACK
603  Counted::untrackReference(i_prop->second.data(),this);
604 #endif
605  rInstanceMap.erase(a_property);
606  }
607  }
608 }
609 
610 inline void Catalog::catalogClear(void)
611 {
612 #if FE_COUNTED_TRACK
613  for(std::map< String, InstanceMap >::iterator i_name=
614  m_instanceMapMap.begin(); i_name!=m_instanceMapMap.end(); i_name++)
615  {
616  InstanceMap& rInstanceMap=i_name->second;
617  for(std::map< String, Instance >::iterator i_prop=rInstanceMap.begin();
618  i_prop!=rInstanceMap.end(); i_prop++)
619  {
620  Counted::untrackReference(i_prop->second.data(),this);
621  }
622  }
623 #endif
624  m_instanceMapMap.clear();
625  m_orderMap.clear();
626 }
627 
628 class FE_DL_EXPORT SafeCatalog:
629  public ObjectSafeShared<SafeCatalog>,
630  virtual public Catalog
631 {
632  public:
633  SafeCatalog(void) {}
634 virtual ~SafeCatalog(void) {}
635 };
636 
637 } /* namespace */
638 
639 #endif /* __core_Catalog_h__ */
sp< Component > catalogComponent(String implementation, String a_name, String a_property="value")
Returns a component entry of the given property for the given name.
Definition: Catalog.cc:213
BWORD catalogTypeIs(String a_name, String a_property="value") const
Returns TRUE if given catalog entry match the template type.
Definition: Catalog.h:523
BWORD catalogedAny(String a_name) const
Returns TRUE if any property for the given name has been created.
Definition: Catalog.h:529
Smart pointer used with types represented by BaseType.
Definition: Instance.h:28
const String catalogTypeName(String a_name, String a_property="value") const
Returns the type name of the given property, determined by the TypeMaster.
Definition: Catalog.h:493
kernel
Definition: namespace.dox:3
Dictionary of Arbitrary Instances.
Definition: Catalog.h:24
T & catalog(String a_name, String a_property="value")
Returns existing catalog entry if already set or a default if not.
Definition: Catalog.h:372
void catalogMoveToEnd(String a_name)
Move all properties for name to bottom.
Definition: Catalog.h:546
Instance & catalogInstance(Instance &instance, String a_name, String a_property="value")
Returns the literal Instance of the given property for the given name.
Definition: Catalog.h:459
void catalogClear(void)
Remove all entries.
Definition: Catalog.h:610
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
const T & catalogOrDefault(String a_name, String a_property, const T &a_default) const
Returns existing catalog entry if already set or default if not.
Definition: Catalog.h:392
Group of named instances.
Definition: InstanceMap.h:17
T & catalogOrException(String a_name, String a_property) const
Returns an existing catalog entry, if it exists.
Definition: Catalog.h:415
BWORD cataloged(String a_name, String a_property="value") const
Returns TRUE if the given property for the given name has been created.
Definition: Catalog.h:537
Wrapper for std::vector.
Definition: Array.h:21
const fe_type_info & catalogTypeInfo(String a_name, String a_property="value") const
Returns the type_info of the given property for the given name.
Definition: Catalog.h:470
Base for all interfacable components.
Definition: Component.h:20
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
void catalogRemove(String a_name)
Remove all properties for a name.
Definition: Catalog.h:560
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192
Object level locking for thread safety.
Definition: SafeShared.h:220