]> SALOME platform Git repositories - modules/yacs.git/blobdiff - src/engine/TypeCode.cxx
Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / engine / TypeCode.cxx
index 93e0f31b28c299de97b26c13addddab7b6a6b32c..9aeb6ba7290793fb44433137d4cc4b72df536690 100644 (file)
@@ -1,14 +1,24 @@
 
 #include "TypeCode.hxx"
+#include <sstream>
+#include <iostream>
+
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
 
 using namespace YACS::ENGINE;
 using namespace std;
 
+const char *TypeCode::KIND_STR_REPR []={ "None", "Double", "Int", "String", "Bool", "Objref", "Sequence", "Array","Struct" };
+
 // --- TypeCode
 
-TypeCode::TypeCode(DynType kind)
+TypeCode::TypeCode(DynType kind):_kind(kind)
+{
+}
+
+TypeCode::TypeCode(const TypeCode& tc):_kind(tc._kind)
 {
-  _kind=kind;
 }
 
 TypeCode::~TypeCode()
@@ -20,11 +30,37 @@ DynType TypeCode::kind() const
   return _kind;
 }
 
+TypeCode *TypeCode::clone() const
+{
+  return new TypeCode(*this);
+}
+
+void TypeCode::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
+{
+  AtomAny::putReprAtPlace(pt,val,this,deepCpy);
+}
+
+void TypeCode::destroyZippedAny(char *data) const
+{
+  AtomAny::destroyReprAtPlace(data,this);
+}
+
+AnyPtr TypeCode::getOrBuildAnyFromZippedData(char *data) const
+{
+  return AtomAny::getOrBuildFromData(data,this);
+}
+
 const char * TypeCode::name() const throw(Exception)
 {
-  throw Exception("No name");
+  //throw Exception("No name");
+  return id();
 }
 
+const char * TypeCode::shortName() const
+{
+  //throw Exception("No shortName");
+  return id();
+}
 
 const char * TypeCode::id() const throw(Exception)
 {
@@ -36,146 +72,599 @@ const char * TypeCode::id() const throw(Exception)
       return "Int";
     case String:
       return "String";
+    case Bool:
+      return "Bool";
     default:
       return "";
     }
 }
 
-int TypeCode::is_a(const char* id)
+int TypeCode::isA(const char* id) const throw(Exception)
 {
   throw Exception("Not implemented for this type");
 }
 
-int TypeCode::is_a(TypeCode* tc)
+int TypeCode::isA(const TypeCode* tc) const 
 {
   if(_kind == tc->kind()) return 1;
   return 0;
 }
 
-TypeCode * TypeCode::content_type() const throw(Exception)
+//! Check if this TypeCode is adaptable to a given TypeCode (tc)
+/*!
+ * this TypeCode is adaptable to tc if tc type can be converted to this type
+ *
+ *   \param tc : the TypeCode that must be convertible to this
+ */
+int TypeCode::isAdaptable(const TypeCode* tc) const
+{
+  switch(_kind)
+    {
+    case Double:
+      if (tc->kind() == Double) return 1;
+      if (tc->kind() == Int) return 1;
+      return 0;
+    case Int:
+      if (tc->kind() == Int) return 1;
+      return 0;
+    case String:
+      if (tc->kind() == String) return 1;
+      return 0;
+    case Bool:
+      if (tc->kind() == Bool) return 1;
+      if (tc->kind() == Int) return 1;
+      return 0;
+    default:
+      //objref, sequence, ...
+      return 0;
+    }
+}
+
+unsigned TypeCode::getSizeInByteOfAnyReprInSeq() const
+{
+  switch(_kind)
+    {
+    case Double:
+      return sizeof(double);
+    case Int:
+      return sizeof(int);
+    case String:
+      return sizeof(StringOnHeap *);
+    case Bool:
+      return sizeof(bool);
+    default:
+      return sizeof(void *);
+    }
+}
+
+const TypeCode * TypeCode::contentType() const throw(Exception)
 {
   throw Exception("No content type");
 };
 
-/**
- * static factory of object reference types
- */
+static inline int validChar0(char c)
+{
+  return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+}
 
-TypeCode * TypeCode::interface_tc(const char* id,
-                                 const char* name)
+static inline int validNextChar(char c)
 {
-  return new TypeCode_objref(id, name);
-};
+  return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+          (c >= '0' && c <= '9') || (c == '_') || (c == '/'));
+}
 
-TypeCode * TypeCode::interface_tc(const char* id,
-                                 const char* name,
-                                 list<TypeCode_objref *> ltc)
+static void checkValidName(const char* name)
 {
-  return new TypeCode_objref(id, name,ltc);
+  int ok = 1;
+  if (*name) 
+    {
+      if (!validChar0(*name++)) ok = 0;
+      for(; ok && *name; name++) if (!validNextChar(*name)) ok = 0; 
+    }
+  if (!ok)throw YACS::Exception("Invalid Name");
+}
+
+const char *TypeCode::getKindRepr(DynType kind)
+{
+  return KIND_STR_REPR[(int)kind];
 }
 
+const char * TypeCode::getKindRepr() const
+{
+  return KIND_STR_REPR[(int)_kind];
+}
 
-/**
- * static factory of sequence types
+//! static factory of object reference type given an id and a name
+TypeCode * TypeCode::interfaceTc(const char* id,
+                                  const char* name)
+{
+  checkValidName(name);
+  return new TypeCodeObjref(id, name);
+};
+
+//! static factory of object reference type given an id, a name and a list of base types
+/*!
+ *   \param id :  the id
+ *   \param name :  the name
+ *   \param ltc :  the list of base types
+ *
+ *   The name must be a valid one (throw Exception is not)
  */
+TypeCode * TypeCode::interfaceTc(const char* id,
+                                  const char* name,
+                                  const std::list<TypeCodeObjref *>& ltc)
+{
+  checkValidName(name);
+  return new TypeCodeObjref(id, name,ltc);
+}
 
-TypeCode * TypeCode::sequence_tc(const char* id,
-                                const char* name,
-                                TypeCode *content)
+
+//! static factory of sequence type given an id, a name and a content type
+TypeCode * TypeCode::sequenceTc(const char* id,
+                                 const char* name,
+                                 TypeCode *content)
+{
+  return new TypeCodeSeq(id, name,content);
+};
+//! static factory of struct type given an id and a name 
+TypeCode * TypeCode::structTc(const char* id,
+                                 const char* name)
 {
-  return new TypeCode_seq(id, name,content);
+  return new TypeCodeStruct(id, name);
 };
 
 
-// --- TypeCode_objref
+// --- TypeCodeObjref
 
 
-TypeCode_objref::TypeCode_objref(const char* repositoryId, 
-                                const char* name)
-  : TypeCode(Objref)
+TypeCodeObjref::TypeCodeObjref(const char* repositoryId, 
+                                 const char* name) : TypeCode(Objref)
 {
   _repoId = repositoryId;
   _name = name;
+  string::size_type debut =_name.find_last_of('/');
+  if(debut == std::string::npos)_shortName= name;
+  else _shortName=_name.substr(debut+1);
 }
 
 
-TypeCode_objref::~TypeCode_objref()
+TypeCodeObjref::~TypeCodeObjref()
 {
+  list<TypeCodeObjref *>::iterator iter;
+  for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
+    (*iter)->decrRef();
+}
+
+TypeCode *TypeCodeObjref::clone() const
+{
+  return new TypeCodeObjref(*this);
 }
 
-const char * TypeCode_objref::id() const throw(Exception)
+void TypeCodeObjref::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
+{
+  throw Exception("Not implemented yet : YACS::Any for objs ref");
+}
+
+void TypeCodeObjref::destroyZippedAny(char *data) const
+{
+  throw Exception("Not implemented yet : YACS::Any for objs ref");
+}
+
+AnyPtr TypeCodeObjref::getOrBuildAnyFromZippedData(char *data) const
+{
+  throw Exception("Not implemented yet : YACS::Any for objs ref");
+}
+
+const char * TypeCodeObjref::id() const throw(Exception)
 {
   return _repoId.c_str();
 };
 
-const char * TypeCode_objref::name() const throw(Exception)
+const char * TypeCodeObjref::name() const throw(Exception)
 {
   return _name.c_str();
 }
 
-TypeCode_objref::TypeCode_objref(const char* repositoryId,
-                                const char* name,
-                                list<TypeCode_objref *> ltc)
-  : TypeCode(Objref)
+const char * TypeCodeObjref::shortName() const
+{
+  return _shortName.c_str();
+}
+
+TypeCodeObjref::TypeCodeObjref(const char* repositoryId,
+                                 const char* name,
+                                 const std::list<TypeCodeObjref *>& ltc) : TypeCode(Objref)
 {
   _repoId = repositoryId;
   _name = name;
+  string::size_type debut =_name.find_last_of('/');
+  if(debut == std::string::npos)_shortName= name;
+  else _shortName=_name.substr(debut+1);
   _listOfBases=ltc;
+  list<TypeCodeObjref *>::const_iterator iter;
+  for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
+    (*iter)->incrRef();
 }
 
-int TypeCode_objref::is_a(const char* id) throw(Exception)
+//! Check if this TypeCode is derived from a TypeCode with a given id
+/*!
+ *   \param id :  a given id
+ *   \return     1 if true, 0 if false
+ */
+int TypeCodeObjref::isA(const char* id) const throw(Exception)
 {
-  if(_repoId.c_str() == id)return 1;
-  list<TypeCode_objref *>::iterator iter;
+  if(_repoId == id)return 1;
+  list<TypeCodeObjref *>::const_iterator iter;
   for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
     {
-      if ((*iter)->is_a(id)) return 1;
+      if ((*iter)->isA(id)) return 1;
     }
   return 0;
 }
 
-int TypeCode_objref::is_a(TypeCode* tc) throw(Exception)
+//! Check if this TypeCode is derived from a given TypeCode
+/*!
+ *   \param tc : the given TypeCode
+ *   \return    1 if true, 0 if false
+ */
+int TypeCodeObjref::isA(const TypeCode* tc) const
 {
-  return is_a(tc->id());
+  return isA(tc->id());
 }
 
-// --- TypeCode_seq
+//! Check if this TypeCode is adaptable to a given TypeCode (tc)
+/*!
+ *   \param tc : the given TypeCode
+ *   \return    1 if true, 0 if false
+ */
+int TypeCodeObjref::isAdaptable(const TypeCode* tc) const
+{
+  if(_kind == tc->kind()) return isA(tc->id());
+  return 0;
+}
+
+TypeCodeObjref::TypeCodeObjref(const TypeCodeObjref& other):TypeCode(other),_name(other._name),
+                                                               _repoId(other._shortName),
+                                                               _listOfBases(other._listOfBases)
+{
+  list<TypeCodeObjref *>::const_iterator iter;
+  for(iter=other._listOfBases.begin();iter!=other._listOfBases.end();iter++)
+    (*iter)->incrRef();
+}
 
+// --- TypeCodeSeq
 
-TypeCode_seq::TypeCode_seq(const char* repositoryId,
-                          const char* name, 
-                          TypeCode *content)
-  : TypeCode(Sequence)
+
+//! Create a sequence type with a given name, a given id and a given contained type.
+/*!
+ *   \param repositoryId : the given id
+ *   \param name : the given name
+ *   \param content : the given contained TypeCode
+ */
+TypeCodeSeq::TypeCodeSeq(const char* repositoryId,
+                           const char* name, 
+                           const TypeCode *content) : TypeCode(Sequence), _content(content)
 {
   _repoId = repositoryId;
   _name = name;
-  _content= content;
+  string::size_type debut =_name.find_last_of('/');
+  if(debut == std::string::npos)_shortName= name;
+  else _shortName=_name.substr(debut+1);
+  _content->incrRef();
+}
+
+TypeCodeSeq::~TypeCodeSeq()
+{
+  ((TypeCode *)_content)->decrRef();
+}
+
+TypeCode *TypeCodeSeq::clone() const
+{
+  return new TypeCodeSeq(*this);
+}
+
+void TypeCodeSeq::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
+{
+  SequenceAny::putReprAtPlace(pt,val,this,deepCpy);
 }
 
-TypeCode_seq::~TypeCode_seq()
+void TypeCodeSeq::destroyZippedAny(char *data) const
 {
+  SequenceAny::destroyReprAtPlace(data,this);
 }
 
-const char * TypeCode_seq::id() const throw(Exception)
+AnyPtr TypeCodeSeq::getOrBuildAnyFromZippedData(char *data) const
+{
+  return SequenceAny::getOrBuildFromData(data,this);
+}
+
+const char * TypeCodeSeq::id() const throw(Exception)
 {
   return _repoId.c_str();
 }
 
-const char * TypeCode_seq::name() const throw(Exception)
+const char * TypeCodeSeq::name() const throw(Exception)
 {
   return _name.c_str();
 }
+const char * TypeCodeSeq::shortName() const
+{
+  return _shortName.c_str();
+}
 
-TypeCode * TypeCode_seq::content_type() const throw(Exception)
+const TypeCode * TypeCodeSeq::contentType() const throw(Exception)
 {
   return _content;
 }
 
-int TypeCode_seq::is_a(TypeCode* tc)
+int TypeCodeSeq::isA(const TypeCode* tc) const
+{
+  if(_kind == tc->kind())
+    return _content->isA(tc->contentType());
+  return 0;
+}
+
+//! Check if this TypeCode is adaptable to a given TypeCode (tc)
+/*!
+ *   \param tc : the given TypeCode
+ *   \return    1 if true, 0 if false
+ */
+int TypeCodeSeq::isAdaptable(const TypeCode* tc) const
 {
   if(_kind == tc->kind())
+    return contentType()->isAdaptable(tc->contentType());
+  return 0;
+}
+
+TypeCodeSeq::TypeCodeSeq(const TypeCodeSeq& tc):TypeCode(tc),
+                                                   _name(tc._name),_shortName(tc._shortName),
+                                                   _repoId(tc._repoId),
+                                                   _content(tc._content)
+{
+  _content->incrRef();
+}
+
+// --- TypeCodeArray
+
+
+//! Create an Array type with a given name, a given id and a given contained type.
+/*!
+ *   \param repositoryId : the given id
+ *   \param name : the given name
+ *   \param content : the given contained TypeCode
+ */
+TypeCodeArray::TypeCodeArray(const char* repositoryId,
+                             const char* name, 
+                             const TypeCode *content,
+                             unsigned staticLgth) : TypeCode(Array), _content(content),_staticLgth(staticLgth)
+{
+  _repoId = repositoryId;
+  _name = name;
+  string::size_type debut =_name.find_last_of('/');
+  if(debut == std::string::npos)_shortName= name;
+  else _shortName=_name.substr(debut+1);
+  _content->incrRef();
+}
+
+TypeCodeArray::~TypeCodeArray()
+{
+  ((TypeCode *)_content)->decrRef();
+}
+
+TypeCode *TypeCodeArray::clone() const
+{
+  return new TypeCodeArray(*this);
+}
+
+void TypeCodeArray::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
+{
+  ArrayAny::putReprAtPlace(pt,val,this,deepCpy);
+}
+
+void TypeCodeArray::destroyZippedAny(char *data) const
+{
+  ArrayAny::destroyReprAtPlace(data,this);
+}
+
+AnyPtr TypeCodeArray::getOrBuildAnyFromZippedData(char *data) const
+{
+  return ArrayAny::getOrBuildFromData(data,this);
+}
+
+const char * TypeCodeArray::id() const throw(Exception)
+{
+  return _repoId.c_str();
+}
+
+const char * TypeCodeArray::name() const throw(Exception)
+{
+  return _name.c_str();
+}
+const char * TypeCodeArray::shortName() const
+{
+  return _shortName.c_str();
+}
+
+unsigned TypeCodeArray::getStaticLgth() const
+{
+  return _staticLgth;
+}
+
+const TypeCode * TypeCodeArray::contentType() const throw(Exception)
+{
+  return _content;
+}
+
+int TypeCodeArray::isA(const TypeCode* tc) const
+{
+  if(_kind == tc->kind())
+    if(_content->isA(tc->contentType()))
+      {
+        const TypeCodeArray *tcC=dynamic_cast<const TypeCodeArray *>(tc);
+        if(tcC)
+          return tcC->getStaticLgth()==_staticLgth;
+        return 0;
+      }
+  return 0;
+}
+
+//! Check if this TypeCode is adaptable to a given TypeCode (tc)
+/*!
+ *   \param tc : the given TypeCode
+ *   \return    1 if true, 0 if false
+ */
+int TypeCodeArray::isAdaptable(const TypeCode* tc) const
+{
+  if(_kind == tc->kind())
+    return contentType()->isAdaptable(tc->contentType());
+  return 0;
+}
+
+TypeCodeArray::TypeCodeArray(const TypeCodeArray& tc):TypeCode(tc),
+                                                      _name(tc._name),_shortName(tc._shortName),
+                                                      _repoId(tc._repoId),
+                                                      _content(tc._content),
+                                                      _staticLgth(tc._staticLgth)
+{
+  _content->incrRef();
+}
+
+unsigned TypeCodeArray::getSizeInByteOfAnyReprInSeq() const
+{
+  return _staticLgth*_content->getSizeInByteOfAnyReprInSeq();
+}
+
+// --- TypeCodeStruct
+
+
+//! Create a struct type with a given name and a given id 
+/*!
+ *   \param repositoryId : the given id
+ *   \param name : the given name
+ */
+TypeCodeStruct::TypeCodeStruct(const char* repositoryId, 
+                         const char* name) : TypeCode(Struct), _name(name),_repoId(repositoryId)
+{
+  string::size_type debut =_name.find_last_of('/');
+  if(debut == std::string::npos)_shortName= name;
+  else _shortName=_name.substr(debut+1);
+}
+
+TypeCodeStruct::~TypeCodeStruct()
+{
+}
+
+TypeCode *TypeCodeStruct::clone() const
+{
+  return new TypeCodeStruct(*this);
+}
+
+TypeCodeStruct::TypeCodeStruct(const TypeCodeStruct& tc):TypeCode(tc),
+                                                         _name(tc._name),_shortName(tc._shortName),
+                                                         _repoId(tc._repoId)
+{
+}
+
+void TypeCodeStruct::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
+{
+  throw Exception("Not implemented yet : YACS::Any for struct");
+}
+
+void TypeCodeStruct::destroyZippedAny(char *data) const
+{
+  throw Exception("Not implemented yet : YACS::Any for struct");
+}
+
+AnyPtr TypeCodeStruct::getOrBuildAnyFromZippedData(char *data) const
+{
+  throw Exception("Not implemented yet : YACS::Any for struct");
+}
+
+const char * TypeCodeStruct::id() const throw(Exception)
+{
+  return _repoId.c_str();
+};
+
+const char * TypeCodeStruct::name() const throw(Exception)
+{
+  return _name.c_str();
+}
+
+const char * TypeCodeStruct::shortName() const
+{
+  return _shortName.c_str();
+}
+
+//! Check if this TypeCode is derived from a TypeCode with a given id
+/*!
+ *   \param id :  a given id
+ *   \return     1 if true, 0 if false
+ */
+int TypeCodeStruct::isA(const char* id) const throw(Exception)
+{
+  if(_repoId.c_str() == id)return 1;
+  return 0;
+}
+
+//! Check if this TypeCode is derived from a given TypeCode
+/*!
+ *   \param tc : the given TypeCode
+ *   \return    1 if true, 0 if false
+ */
+int TypeCodeStruct::isA(const TypeCode* tc) const 
+{
+  return isA(tc->id());
+}
+
+//! Check if this TypeCode is adaptable to a given TypeCode (tc)
+/*!
+ *   \param tc : the given TypeCode
+ *   \return    1 if true, 0 if false
+ */
+int TypeCodeStruct::isAdaptable(const TypeCode* tc) const
+{
+  if(_kind == tc->kind()) return isA(tc->id());
+  return 0;
+}
+
+void TypeCodeStruct::addMember(const std::string& name,TypeCode* tc)
+{
+  DEBTRACE(name << " " << tc->name());
+  std::vector< std::pair<std::string,TypeCode*> >::const_iterator iter;
+  for(iter=_members.begin();iter != _members.end(); iter++)
     {
-      if(_content->is_a(tc->content_type())) return 1;
+      if((*iter).first == name)
+        throw Exception("Struct member " + name + " already defined");
     }
-  return 0;
+  _members.push_back(std::pair<std::string,TypeCode*>(name,tc));
 }
+
+int TypeCodeStruct::memberCount() const
+{
+  return _members.size();
+}
+
+const char*  TypeCodeStruct::memberName(int index) const
+{
+  if(index > _members.size())
+    {
+      stringstream msg;
+      msg << "Struct size less than " << index;
+      msg << " : " << __FILE__ << ":" << __LINE__;
+      throw Exception(msg.str());
+    }
+  return _members[index].first.c_str();
+}
+
+TypeCode*  TypeCodeStruct::memberType(int index) const
+{
+  if(index > _members.size())
+    {
+      stringstream msg;
+      msg << "Struct size less than " << index;
+      msg << " : " << __FILE__ << ":" << __LINE__;
+      throw Exception(msg.str());
+    }
+  return _members[index].second;
+}
+
+