2 #include "TypeCode.hxx"
7 #include "YacsTrace.hxx"
9 using namespace YACS::ENGINE;
12 const char *TypeCode::KIND_STR_REPR []={ "None", "Double", "Int", "String", "Bool", "Objref", "Sequence", "Array","Struct" };
16 TypeCode::TypeCode(DynType kind):_kind(kind)
20 TypeCode::TypeCode(const TypeCode& tc):_kind(tc._kind)
28 DynType TypeCode::kind() const
33 TypeCode *TypeCode::clone() const
35 return new TypeCode(*this);
38 void TypeCode::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
40 AtomAny::putReprAtPlace(pt,val,this,deepCpy);
43 void TypeCode::destroyZippedAny(char *data) const
45 AtomAny::destroyReprAtPlace(data,this);
48 AnyPtr TypeCode::getOrBuildAnyFromZippedData(char *data) const
50 return AtomAny::getOrBuildFromData(data,this);
53 const char * TypeCode::name() const throw(Exception)
55 //throw Exception("No name");
59 const char * TypeCode::shortName() const
61 //throw Exception("No shortName");
65 const char * TypeCode::id() const throw(Exception)
82 int TypeCode::isA(const char* id) const throw(Exception)
84 throw Exception("Not implemented for this type");
87 int TypeCode::isA(const TypeCode* tc) const
89 if(_kind == tc->kind()) return 1;
93 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
95 * this TypeCode is adaptable to tc if tc type can be converted to this type
97 * \param tc : the TypeCode that must be convertible to this
99 int TypeCode::isAdaptable(const TypeCode* tc) const
104 if (tc->kind() == Double) return 1;
105 if (tc->kind() == Int) return 1;
108 if (tc->kind() == Int) return 1;
111 if (tc->kind() == String) return 1;
114 if (tc->kind() == Bool) return 1;
115 if (tc->kind() == Int) return 1;
118 //objref, sequence, ...
123 unsigned TypeCode::getSizeInByteOfAnyReprInSeq() const
128 return sizeof(double);
132 return sizeof(StringOnHeap *);
136 return sizeof(void *);
140 const TypeCode * TypeCode::contentType() const throw(Exception)
142 throw Exception("No content type");
145 static inline int validChar0(char c)
147 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
150 static inline int validNextChar(char c)
152 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
153 (c >= '0' && c <= '9') || (c == '_') || (c == '/'));
156 static void checkValidName(const char* name)
161 if (!validChar0(*name++)) ok = 0;
162 for(; ok && *name; name++) if (!validNextChar(*name)) ok = 0;
164 if (!ok)throw YACS::Exception("Invalid Name");
167 const char *TypeCode::getKindRepr(DynType kind)
169 return KIND_STR_REPR[(int)kind];
172 const char * TypeCode::getKindRepr() const
174 return KIND_STR_REPR[(int)_kind];
177 //! static factory of object reference type given an id and a name
178 TypeCode * TypeCode::interfaceTc(const char* id,
181 checkValidName(name);
182 return new TypeCodeObjref(id, name);
185 //! static factory of object reference type given an id, a name and a list of base types
188 * \param name : the name
189 * \param ltc : the list of base types
191 * The name must be a valid one (throw Exception is not)
193 TypeCode * TypeCode::interfaceTc(const char* id,
195 const std::list<TypeCodeObjref *>& ltc)
197 checkValidName(name);
198 return new TypeCodeObjref(id, name,ltc);
202 //! static factory of sequence type given an id, a name and a content type
203 TypeCode * TypeCode::sequenceTc(const char* id,
207 return new TypeCodeSeq(id, name,content);
209 //! static factory of struct type given an id and a name
210 TypeCode * TypeCode::structTc(const char* id,
213 return new TypeCodeStruct(id, name);
217 // --- TypeCodeObjref
220 TypeCodeObjref::TypeCodeObjref(const char* repositoryId,
221 const char* name) : TypeCode(Objref)
223 _repoId = repositoryId;
225 string::size_type debut =_name.find_last_of('/');
226 if(debut == std::string::npos)_shortName= name;
227 else _shortName=_name.substr(debut+1);
231 TypeCodeObjref::~TypeCodeObjref()
233 list<TypeCodeObjref *>::iterator iter;
234 for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
238 TypeCode *TypeCodeObjref::clone() const
240 return new TypeCodeObjref(*this);
243 void TypeCodeObjref::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
245 throw Exception("Not implemented yet : YACS::Any for objs ref");
248 void TypeCodeObjref::destroyZippedAny(char *data) const
250 throw Exception("Not implemented yet : YACS::Any for objs ref");
253 AnyPtr TypeCodeObjref::getOrBuildAnyFromZippedData(char *data) const
255 throw Exception("Not implemented yet : YACS::Any for objs ref");
258 const char * TypeCodeObjref::id() const throw(Exception)
260 return _repoId.c_str();
263 const char * TypeCodeObjref::name() const throw(Exception)
265 return _name.c_str();
268 const char * TypeCodeObjref::shortName() const
270 return _shortName.c_str();
273 TypeCodeObjref::TypeCodeObjref(const char* repositoryId,
275 const std::list<TypeCodeObjref *>& ltc) : TypeCode(Objref)
277 _repoId = repositoryId;
279 string::size_type debut =_name.find_last_of('/');
280 if(debut == std::string::npos)_shortName= name;
281 else _shortName=_name.substr(debut+1);
283 list<TypeCodeObjref *>::const_iterator iter;
284 for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
288 //! Check if this TypeCode is derived from a TypeCode with a given id
290 * \param id : a given id
291 * \return 1 if true, 0 if false
293 int TypeCodeObjref::isA(const char* id) const throw(Exception)
295 if(_repoId == id)return 1;
296 list<TypeCodeObjref *>::const_iterator iter;
297 for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
299 if ((*iter)->isA(id)) return 1;
304 //! Check if this TypeCode is derived from a given TypeCode
306 * \param tc : the given TypeCode
307 * \return 1 if true, 0 if false
309 int TypeCodeObjref::isA(const TypeCode* tc) const
311 return isA(tc->id());
314 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
316 * \param tc : the given TypeCode
317 * \return 1 if true, 0 if false
319 int TypeCodeObjref::isAdaptable(const TypeCode* tc) const
321 if(_kind == tc->kind()) return isA(tc->id());
325 TypeCodeObjref::TypeCodeObjref(const TypeCodeObjref& other):TypeCode(other),_name(other._name),
326 _repoId(other._shortName),
327 _listOfBases(other._listOfBases)
329 list<TypeCodeObjref *>::const_iterator iter;
330 for(iter=other._listOfBases.begin();iter!=other._listOfBases.end();iter++)
337 //! Create a sequence type with a given name, a given id and a given contained type.
339 * \param repositoryId : the given id
340 * \param name : the given name
341 * \param content : the given contained TypeCode
343 TypeCodeSeq::TypeCodeSeq(const char* repositoryId,
345 const TypeCode *content) : TypeCode(Sequence), _content(content)
347 _repoId = repositoryId;
349 string::size_type debut =_name.find_last_of('/');
350 if(debut == std::string::npos)_shortName= name;
351 else _shortName=_name.substr(debut+1);
355 TypeCodeSeq::~TypeCodeSeq()
357 ((TypeCode *)_content)->decrRef();
360 TypeCode *TypeCodeSeq::clone() const
362 return new TypeCodeSeq(*this);
365 void TypeCodeSeq::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
367 SequenceAny::putReprAtPlace(pt,val,this,deepCpy);
370 void TypeCodeSeq::destroyZippedAny(char *data) const
372 SequenceAny::destroyReprAtPlace(data,this);
375 AnyPtr TypeCodeSeq::getOrBuildAnyFromZippedData(char *data) const
377 return SequenceAny::getOrBuildFromData(data,this);
380 const char * TypeCodeSeq::id() const throw(Exception)
382 return _repoId.c_str();
385 const char * TypeCodeSeq::name() const throw(Exception)
387 return _name.c_str();
389 const char * TypeCodeSeq::shortName() const
391 return _shortName.c_str();
394 const TypeCode * TypeCodeSeq::contentType() const throw(Exception)
399 int TypeCodeSeq::isA(const TypeCode* tc) const
401 if(_kind == tc->kind())
402 return _content->isA(tc->contentType());
406 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
408 * \param tc : the given TypeCode
409 * \return 1 if true, 0 if false
411 int TypeCodeSeq::isAdaptable(const TypeCode* tc) const
413 if(_kind == tc->kind())
414 return contentType()->isAdaptable(tc->contentType());
418 TypeCodeSeq::TypeCodeSeq(const TypeCodeSeq& tc):TypeCode(tc),
419 _name(tc._name),_shortName(tc._shortName),
421 _content(tc._content)
429 //! Create an Array type with a given name, a given id and a given contained type.
431 * \param repositoryId : the given id
432 * \param name : the given name
433 * \param content : the given contained TypeCode
435 TypeCodeArray::TypeCodeArray(const char* repositoryId,
437 const TypeCode *content,
438 unsigned staticLgth) : TypeCode(Array), _content(content),_staticLgth(staticLgth)
440 _repoId = repositoryId;
442 string::size_type debut =_name.find_last_of('/');
443 if(debut == std::string::npos)_shortName= name;
444 else _shortName=_name.substr(debut+1);
448 TypeCodeArray::~TypeCodeArray()
450 ((TypeCode *)_content)->decrRef();
453 TypeCode *TypeCodeArray::clone() const
455 return new TypeCodeArray(*this);
458 void TypeCodeArray::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
460 ArrayAny::putReprAtPlace(pt,val,this,deepCpy);
463 void TypeCodeArray::destroyZippedAny(char *data) const
465 ArrayAny::destroyReprAtPlace(data,this);
468 AnyPtr TypeCodeArray::getOrBuildAnyFromZippedData(char *data) const
470 return ArrayAny::getOrBuildFromData(data,this);
473 const char * TypeCodeArray::id() const throw(Exception)
475 return _repoId.c_str();
478 const char * TypeCodeArray::name() const throw(Exception)
480 return _name.c_str();
482 const char * TypeCodeArray::shortName() const
484 return _shortName.c_str();
487 unsigned TypeCodeArray::getStaticLgth() const
492 const TypeCode * TypeCodeArray::contentType() const throw(Exception)
497 int TypeCodeArray::isA(const TypeCode* tc) const
499 if(_kind == tc->kind())
500 if(_content->isA(tc->contentType()))
502 const TypeCodeArray *tcC=dynamic_cast<const TypeCodeArray *>(tc);
504 return tcC->getStaticLgth()==_staticLgth;
510 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
512 * \param tc : the given TypeCode
513 * \return 1 if true, 0 if false
515 int TypeCodeArray::isAdaptable(const TypeCode* tc) const
517 if(_kind == tc->kind())
518 return contentType()->isAdaptable(tc->contentType());
522 TypeCodeArray::TypeCodeArray(const TypeCodeArray& tc):TypeCode(tc),
523 _name(tc._name),_shortName(tc._shortName),
525 _content(tc._content),
526 _staticLgth(tc._staticLgth)
531 unsigned TypeCodeArray::getSizeInByteOfAnyReprInSeq() const
533 return _staticLgth*_content->getSizeInByteOfAnyReprInSeq();
536 // --- TypeCodeStruct
539 //! Create a struct type with a given name and a given id
541 * \param repositoryId : the given id
542 * \param name : the given name
544 TypeCodeStruct::TypeCodeStruct(const char* repositoryId,
545 const char* name) : TypeCode(Struct), _name(name),_repoId(repositoryId)
547 string::size_type debut =_name.find_last_of('/');
548 if(debut == std::string::npos)_shortName= name;
549 else _shortName=_name.substr(debut+1);
552 TypeCodeStruct::~TypeCodeStruct()
556 TypeCode *TypeCodeStruct::clone() const
558 return new TypeCodeStruct(*this);
561 TypeCodeStruct::TypeCodeStruct(const TypeCodeStruct& tc):TypeCode(tc),
562 _name(tc._name),_shortName(tc._shortName),
567 void TypeCodeStruct::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
569 throw Exception("Not implemented yet : YACS::Any for struct");
572 void TypeCodeStruct::destroyZippedAny(char *data) const
574 throw Exception("Not implemented yet : YACS::Any for struct");
577 AnyPtr TypeCodeStruct::getOrBuildAnyFromZippedData(char *data) const
579 throw Exception("Not implemented yet : YACS::Any for struct");
582 const char * TypeCodeStruct::id() const throw(Exception)
584 return _repoId.c_str();
587 const char * TypeCodeStruct::name() const throw(Exception)
589 return _name.c_str();
592 const char * TypeCodeStruct::shortName() const
594 return _shortName.c_str();
597 //! Check if this TypeCode is derived from a TypeCode with a given id
599 * \param id : a given id
600 * \return 1 if true, 0 if false
602 int TypeCodeStruct::isA(const char* id) const throw(Exception)
604 if(_repoId.c_str() == id)return 1;
608 //! Check if this TypeCode is derived from a given TypeCode
610 * \param tc : the given TypeCode
611 * \return 1 if true, 0 if false
613 int TypeCodeStruct::isA(const TypeCode* tc) const
615 return isA(tc->id());
618 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
620 * \param tc : the given TypeCode
621 * \return 1 if true, 0 if false
623 int TypeCodeStruct::isAdaptable(const TypeCode* tc) const
625 if(_kind == tc->kind()) return isA(tc->id());
629 void TypeCodeStruct::addMember(const std::string& name,TypeCode* tc)
631 DEBTRACE(name << " " << tc->name());
632 std::vector< std::pair<std::string,TypeCode*> >::const_iterator iter;
633 for(iter=_members.begin();iter != _members.end(); iter++)
635 if((*iter).first == name)
636 throw Exception("Struct member " + name + " already defined");
638 _members.push_back(std::pair<std::string,TypeCode*>(name,tc));
641 int TypeCodeStruct::memberCount() const
643 return _members.size();
646 const char* TypeCodeStruct::memberName(int index) const
648 if(index > _members.size())
651 msg << "Struct size less than " << index;
652 msg << " : " << __FILE__ << ":" << __LINE__;
653 throw Exception(msg.str());
655 return _members[index].first.c_str();
658 TypeCode* TypeCodeStruct::memberType(int index) const
660 if(index > _members.size())
663 msg << "Struct size less than " << index;
664 msg << " : " << __FILE__ << ":" << __LINE__;
665 throw Exception(msg.str());
667 return _members[index].second;