Free Electron
TypeMaster.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_TypeMaster_h__
8 #define __core_TypeMaster_h__
9 
10 namespace fe
11 {
12 
13 
14 /**************************************************************************//**
15 *//***************************************************************************/
16 class FE_DL_EXPORT TypeConversion : public Counted
17 {
18  public:
19  typedef enum
20  {
21  e_cast, ///< 'out' points to pre-existing instance
22  e_copy ///< 'out' points to newly allocated instance
23  } InstanceAllocation;
24 
25 virtual ~TypeConversion(void) {}
26 
27 virtual InstanceAllocation operator()(void *in,void *&out)
28  {
29  out = in;
30  return e_cast;
31  }
32 
33 #if FE_COUNTED_TRACK
34  TypeConversion(void): m_name("TypeConversion") {}
35 const String& name(void) const { return m_name; }
36  private:
37  String m_name;
38 #endif
39 
40 };
41 
42 template<class In, class Out>
43 class FE_DL_EXPORT NativeConversion : public TypeConversion
44 {
45  public:
46  InstanceAllocation operator()(void *in,void *&out)
47  {
48  out = new Out;
49  *reinterpret_cast<Out *>(out)=
50  static_cast<Out>(*reinterpret_cast<In *>(in));
51  return e_copy;
52  }
53 };
54 
55 typedef AutoHashMap< TypeInfo, sp<BaseType> > type_info_map;
56 typedef AutoHashMap< String, sp<BaseType> > string_type_map;
57  //* reverse map: just one name of potentially many
58 typedef AutoHashMap< sp<BaseType>, String > type_string_map;
59 typedef AutoHashMap< sp<BaseType>, sp<TypeConversion> > out_converter_map;
60 typedef AutoHashMap< sp<BaseType>, out_converter_map > in_out_converter_map;
61 
62 /** @brief Run time C++ type management
63 
64  @ingroup core
65  */
66 class FE_DL_EXPORT TypeMaster : public Counted, public ClassSafe<TypeMaster>
67 {
68  private:
69  class TypeMasterEntry
70  {
71  public:
72  BaseType *type(void) {return m_pType;}
73  void addType(BaseType *pType) {m_pType = pType;}
74  private:
75  BaseType *m_pType;
76  };
77 
78  public:
79 
80  class TypeLoader:
81  virtual public Counted,
82  public CastableAs<TypeLoader>
83  {
84  public:
85  /** @brief called when a requested type is not found
86  */
87  virtual Result loadType(String a_name) =0;
88  };
89 
90  TypeMaster(void);
91  ~TypeMaster(void);
92 
93  template<class T>
94  sp<BaseType> lookupType(void);
95  sp<BaseType> lookupType(const TypeInfo &typeInfo);
96  void dumpTypes(void) const;
97 
98  Result addTypeLoader(sp<TypeLoader> a_spTypeLoader);
99  Result loadType(String a_name);
100 
101  template<class Converter, class In, class Out>
102  void registerConversion(void);
103 
104  template<class In, class Out>
105  void nativeConversion(void);
106 
107  void registerConversion(
108  sp<TypeConversion> spConv,
109  sp<BaseType> spInType,
110  sp<BaseType> spOutType);
111 
112 
113  sp<BaseType> lookupName(const String &name);
114  //* without autoload
115  sp<BaseType> lookupNameLoaded(const String &name);
116 
117  String lookupBaseType(const sp<BaseType>& type);
118 
119  template<class In, class Out>
120  sp<TypeConversion> lookupConversion(void);
121 
122  void reverseLookup(sp<BaseType> basetype,
123  std::list<String> &names);
124  String reverseLookup(sp<BaseType> basetype);
125 
126  /// @internal
127  sp<TypeConversion> lookupConversion(sp<BaseType> spInType,
128  sp<BaseType> spOutType);
129 
130  void peek(Peeker &peeker);
131 
132  template<class T>
133  sp<BaseType> assertType(const String &name);
134 
135  template<class T>
136  sp<BaseType> assertType(void);
137 
138  template<class T, class Info>
139  sp<BaseType> assertTypeInfo(const String &name);
140 
141 
142  template<class T>
143  sp<BaseType> assertPtr(const String &name);
144 
145 const String& name(void) const { return m_name; }
146 
147  sp<BaseType> assertTypeInternal(const TypeInfo &typeInfo,
148  sp<BaseType> spT, const String &name);
149 
150  /// @brief serialize String buffer into value
151  template<class T>
152  Result input(String a_buffer,T& a_value);
153 
154  /// @brief serialize value into String buffer
155  template<class T>
156  Result output(T& a_value,String& a_buffer);
157 
158  private:
159  type_info_map m_hTypeidMap;
160  string_type_map m_hNameMap;
161  type_string_map m_hTypeMap;
162  in_out_converter_map m_hConverter;
163  String m_name;
164  Array< sp<TypeLoader> > m_typeLoaderArray;
165 };
166 
167 template<class T>
168 inline sp<BaseType> TypeMaster::lookupType(void)
169 {
170  return lookupType(TypeInfo(getTypeId<T>()));
171 }
172 
173 template<class Converter, class In, class Out>
174 void TypeMaster::registerConversion(void)
175 {
176  sp<TypeConversion> spConv(new Converter);
177  sp<BaseType> spInType = lookupType<In>();
178  sp<BaseType> spOutType = lookupType<Out>();
179  if(spInType.isValid() && spOutType.isValid())
180  {
181  registerConversion(spConv,spInType,spOutType);
182  }
183  else
184  {
185  feX("fe::TypeMaster::registerConversion",
186  "cannot convert unknown types");
187  }
188 }
189 
190 template<class In, class Out>
191 void TypeMaster::nativeConversion(void)
192 {
193  registerConversion< NativeConversion<In,Out>, In, Out>();
194 }
195 
196 template<class In, class Out>
197 sp<TypeConversion> TypeMaster::lookupConversion(void)
198 {
199  sp<BaseType> spInType = lookupType<In>();
200  sp<BaseType> spOutType = lookupType<Out>();
201  if(spInType.isValid() && spOutType.isValid())
202  {
203  return lookupConversion(spInType,spOutType);
204  }
205  else
206  {
207  feX("fe::TypeMaster::lookupConversion",
208  "cannot convert unknown types");
209  }
210 }
211 
212 template<class T>
213 inline sp<BaseType> assertType(sp<TypeMaster> spTypeMaster, const String &name)
214 {
215  sp<BaseType> spType(Type<T>::create());
216  return spTypeMaster->assertTypeInternal(TypeInfo(getTypeId<T>()), spType, name);
217 }
218 
219 template<class T>
220 inline sp<BaseType> TypeMaster::assertType(const String &name)
221 {
222  sp<BaseType> spType(Type<T>::create());
223  return assertTypeInternal(TypeInfo(getTypeId<T>()), spType, name);
224 }
225 
226 template<class T>
227 sp<BaseType> TypeMaster::assertType(void)
228 {
229  String name = "local_rtti_";
230  name.cat(FE_TYPESTRING(T));
231  sp<BaseType> spType(Type<T>::create());
232  return assertTypeInternal(TypeInfo(getTypeId<T>()), spType, name);
233 }
234 
235 template<class T, class Info>
236 sp<BaseType> TypeMaster::assertTypeInfo(const String &name)
237 {
238  sp<BaseType> spType(Type<T>::create());
239 
240  sp<BaseType> spReturn;
241  spReturn = assertTypeInternal(TypeInfo(getTypeId<T>()), spType, name);
242  spReturn->setInfo(new Info());
243  return spReturn;
244 }
245 
246 template<class T>
247 class PtrInfo : public TypeInfoConstructable<sp<T> >
248 {
249 };
250 #if 0
251 template<class T>
252 class PtrInfo : public BaseType::Info
253 {
254  public:
255  virtual bool getConstruct(void)
256  {
257  return true;
258  }
259  virtual void construct(void *instance)
260  {
261  new(instance)sp<T>;
262  }
263  virtual void destruct(void *instance)
264  {
265  ((sp<T> *)instance)->~sp<T>();
266  }
267 };
268 #endif
269 
270 template<class T>
271 sp<BaseType> TypeMaster::assertPtr(const String &name)
272 {
273  sp<BaseType> spT;
274  spT = assertType<sp<T> >(name);
275  spT->setInfo(new PtrInfo<T>());
276  return spT;
277 }
278 
279 template<class T>
280 Result TypeMaster::input(String a_buffer,T& a_value)
281 {
282  const sp<BaseType> spBaseType=lookupType<T>();
283  if(spBaseType.isNull())
284  {
285  feLog("TypeMaster::output bad type\n");
286  return e_unsupported;
287  }
288 
289  void* data = &a_value;
290 
291  std::istringstream istrstrm(a_buffer.c_str());
292  spBaseType->getInfo()->input(istrstrm,data,
293  BaseType::Info::e_ascii);
294 
295  return e_ok;
296 }
297 
298 template<class T>
299 Result TypeMaster::output(T& a_value,String& a_buffer)
300 {
301  const sp<BaseType> spBaseType=lookupType<T>();
302  if(spBaseType.isNull())
303  {
304  feLog("TypeMaster::output bad type\n");
305  return e_unsupported;
306  }
307 
308  void* data = &a_value;
309 
310  std::ostringstream ostrstrm;
311  if(-1 == spBaseType->getInfo()->output(ostrstrm, data,
312  BaseType::Info::e_ascii))
313  {
314  feLog("TypeMaster::output ascii write failed\n");
315  return e_writeFailed;
316  }
317 
318  a_buffer=ostrstrm.str().c_str();
319  return e_ok;
320 }
321 
322 } /* namespace */
323 
324 #endif /* ___core_TypeMaster_h__ */
Class level locking for thread safety.
Definition: Safe.h:213
const FESTRING_I8 * c_str(void) const
Return the contents of the 8-bit buffer cast as signed bytes.
Definition: String.h:352
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
Run time C++ type management.
Definition: TypeMaster.h:66
C++ type_info wrapper.
Definition: Type.h:20
A class to associate functionality with run time types.
Definition: Type.h:571
A class to associate functionality with run time types.
Definition: Type.h:120
Result input(String a_buffer, T &a_value)
serialize String buffer into value
Definition: TypeMaster.h:280
Result output(T &a_value, String &a_buffer)
serialize value into String buffer
Definition: TypeMaster.h:299
String & cat(const char *operand)
Append the current String with the given text.
Definition: String.cc:545
Automatically reference-counted string container.
Definition: String.h:128
Wrapper for std::vector.
Definition: Array.h:21
Result
Generalized return value indicating success or failure, and why.
Definition: Result.h:24
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192