+// Copyright (C) 2006-2016 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
#include "TypeCode.hxx"
#include <sstream>
#include <iostream>
+#include <cstring>
//#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" };
+const char *TypeCode::KIND_STR_REPR []={ "None", "double", "int", "string", "bool", "Objref", "Sequence", "Array","Struct" };
// --- TypeCode
return AtomAny::getOrBuildFromData(data,this);
}
-const char * TypeCode::name() const throw(Exception)
+const char * TypeCode::name() const throw(YACS::Exception)
{
//throw Exception("No name");
return id();
return id();
}
-const char * TypeCode::id() const throw(Exception)
+const char * TypeCode::id() const throw(YACS::Exception)
{
switch(_kind)
{
case Double:
- return "Double";
+ return "double";
case Int:
- return "Int";
+ return "int";
case String:
- return "String";
+ return "string";
case Bool:
- return "Bool";
+ return "bool";
default:
return "";
}
}
-int TypeCode::isA(const char* id) const throw(Exception)
+int TypeCode::isA(const char* id) const throw(YACS::Exception)
{
throw Exception("Not implemented for this type");
}
}
}
+//! Check if this TypeCode can be used in place of tc
+/*!
+ * this TypeCode is equivalent to tc if they have the same kind
+ *
+ * \param tc : the TypeCode to compare
+ */
+int TypeCode::isEquivalent(const TypeCode* tc) const
+{
+ if(_kind == tc->kind()) return 1;
+ return 0;
+}
+
unsigned TypeCode::getSizeInByteOfAnyReprInSeq() const
{
switch(_kind)
}
}
-const TypeCode * TypeCode::contentType() const throw(Exception)
+const TypeCode * TypeCode::contentType() const throw(YACS::Exception)
{
throw Exception("No content type");
};
const char* name,
TypeCode *content)
{
+ std::string typname;
+ if(std::string(name)=="")
+ {
+ typname="seq"+std::string(content->name());
+ name=typname.c_str();
+ }
+ if(std::string(id)=="")
+ id=name;
return new TypeCodeSeq(id, name,content);
};
//! static factory of struct type given an id and a name
return new TypeCodeStruct(id, name);
};
+TypeCodeComposed::TypeCodeComposed(const TypeCodeComposed& other):TypeCode(other),
+ _name(other._name),_repoId(other._repoId),
+ _shortName(other._shortName)
+{
+}
+
+TypeCodeComposed::TypeCodeComposed(DynType kind, const char* repositoryId, const char* name):TypeCode(kind),
+ _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);
+}
// --- TypeCodeObjref
TypeCodeObjref::TypeCodeObjref(const char* repositoryId,
- const char* name) : TypeCode(Objref)
+ const char* name) : TypeCodeComposed(Objref,repositoryId,name)
{
- _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);
}
throw Exception("Not implemented yet : YACS::Any for objs ref");
}
-const char * TypeCodeObjref::id() const throw(Exception)
+const char * TypeCodeObjref::id() const throw(YACS::Exception)
{
return _repoId.c_str();
};
-const char * TypeCodeObjref::name() const throw(Exception)
+const char * TypeCodeObjref::name() const throw(YACS::Exception)
{
return _name.c_str();
}
}
TypeCodeObjref::TypeCodeObjref(const char* repositoryId,
- const char* name,
- const std::list<TypeCodeObjref *>& ltc) : TypeCode(Objref)
+ const char* name,
+ const std::list<TypeCodeObjref *>& ltc) : TypeCodeComposed(Objref,repositoryId,name)
{
- _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++)
* \param id : a given id
* \return 1 if true, 0 if false
*/
-int TypeCodeObjref::isA(const char* id) const throw(Exception)
+int TypeCodeObjref::isA(const char* id) const throw(YACS::Exception)
{
if(_repoId == id)return 1;
list<TypeCodeObjref *>::const_iterator iter;
return 0;
}
-TypeCodeObjref::TypeCodeObjref(const TypeCodeObjref& other):TypeCode(other),_name(other._name),
- _repoId(other._shortName),
- _listOfBases(other._listOfBases)
+//! Check if this TypeCode can be used in place of tc
+/*!
+ * this TypeCode is equivalent to tc if they have the same kind
+ *
+ * \param tc : the TypeCode to compare
+ */
+int TypeCodeObjref::isEquivalent(const TypeCode* tc) const
+{
+ if(_kind != tc->kind())return 0;
+ if(_repoId == tc->id())return 1;
+ return 0;
+}
+
+TypeCodeObjref::TypeCodeObjref(const TypeCodeObjref& other):TypeCodeComposed(other),
+ _listOfBases(other._listOfBases)
{
list<TypeCodeObjref *>::const_iterator iter;
for(iter=other._listOfBases.begin();iter!=other._listOfBases.end();iter++)
* \param content : the given contained TypeCode
*/
TypeCodeSeq::TypeCodeSeq(const char* repositoryId,
- const char* name,
- const TypeCode *content) : TypeCode(Sequence), _content(content)
+ const char* name,
+ const TypeCode *content) : TypeCodeComposed(Sequence,repositoryId,name), _content(content)
{
- _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();
}
SequenceAny::destroyReprAtPlace(data,this);
}
+unsigned TypeCodeSeq::getSizeInByteOfAnyReprInSeq() const
+{
+ return sizeof(void*);
+}
+
AnyPtr TypeCodeSeq::getOrBuildAnyFromZippedData(char *data) const
{
return SequenceAny::getOrBuildFromData(data,this);
}
-const char * TypeCodeSeq::id() const throw(Exception)
+const char * TypeCodeSeq::id() const throw(YACS::Exception)
{
return _repoId.c_str();
}
-const char * TypeCodeSeq::name() const throw(Exception)
+const char * TypeCodeSeq::name() const throw(YACS::Exception)
{
return _name.c_str();
}
return _shortName.c_str();
}
-const TypeCode * TypeCodeSeq::contentType() const throw(Exception)
+const TypeCode * TypeCodeSeq::contentType() const throw(YACS::Exception)
{
return _content;
}
return 0;
}
-TypeCodeSeq::TypeCodeSeq(const TypeCodeSeq& tc):TypeCode(tc),
- _name(tc._name),_shortName(tc._shortName),
- _repoId(tc._repoId),
- _content(tc._content)
+//! Check if this TypeCode can be used in place of tc
+/*!
+ * this TypeCode is equivalent to tc if they have the same kind
+ *
+ * \param tc : the TypeCode to compare
+ */
+int TypeCodeSeq::isEquivalent(const TypeCode* tc) const
+{
+ if(_kind == tc->kind())
+ return _content->isEquivalent(tc->contentType());
+ return 0;
+}
+
+TypeCodeSeq::TypeCodeSeq(const TypeCodeSeq& tc):TypeCodeComposed(tc),
+ _content(tc._content)
{
_content->incrRef();
}
* \param repositoryId : the given id
* \param name : the given name
* \param content : the given contained TypeCode
+ * \param staticLgth : the length
*/
TypeCodeArray::TypeCodeArray(const char* repositoryId,
const char* name,
const TypeCode *content,
- unsigned staticLgth) : TypeCode(Array), _content(content),_staticLgth(staticLgth)
+ unsigned staticLgth) : TypeCodeComposed(Array,repositoryId,name), _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();
}
return ArrayAny::getOrBuildFromData(data,this);
}
-const char * TypeCodeArray::id() const throw(Exception)
+const char * TypeCodeArray::id() const throw(YACS::Exception)
{
return _repoId.c_str();
}
-const char * TypeCodeArray::name() const throw(Exception)
+const char * TypeCodeArray::name() const throw(YACS::Exception)
{
return _name.c_str();
}
return _staticLgth;
}
-const TypeCode * TypeCodeArray::contentType() const throw(Exception)
+const TypeCode * TypeCodeArray::contentType() const throw(YACS::Exception)
{
return _content;
}
return 0;
}
-TypeCodeArray::TypeCodeArray(const TypeCodeArray& tc):TypeCode(tc),
- _name(tc._name),_shortName(tc._shortName),
- _repoId(tc._repoId),
+//! Check if this TypeCode can be used in place of tc
+/*!
+ * this TypeCode is equivalent to tc if they have the same kind
+ *
+ * \param tc : the TypeCode to compare
+ */
+int TypeCodeArray::isEquivalent(const TypeCode* tc) const
+{
+ if(_kind == tc->kind())
+ return _content->isEquivalent(tc->contentType());
+ return 0;
+}
+
+TypeCodeArray::TypeCodeArray(const TypeCodeArray& tc):TypeCodeComposed(tc),
_content(tc._content),
_staticLgth(tc._staticLgth)
{
* \param name : the given name
*/
TypeCodeStruct::TypeCodeStruct(const char* repositoryId,
- const char* name) : TypeCode(Struct), _name(name),_repoId(repositoryId)
+ const char* name) : TypeCodeComposed(Struct,repositoryId,name)
{
- string::size_type debut =_name.find_last_of('/');
- if(debut == std::string::npos)_shortName= name;
- else _shortName=_name.substr(debut+1);
}
TypeCodeStruct::~TypeCodeStruct()
{
+ for(vector< pair<string,TypeCode*> >::iterator iter=_members.begin();iter!=_members.end();iter++)
+ (*iter).second->decrRef();
}
TypeCode *TypeCodeStruct::clone() const
return new TypeCodeStruct(*this);
}
-TypeCodeStruct::TypeCodeStruct(const TypeCodeStruct& tc):TypeCode(tc),
- _name(tc._name),_shortName(tc._shortName),
- _repoId(tc._repoId)
+TypeCodeStruct::TypeCodeStruct(const TypeCodeStruct& tc):TypeCodeComposed(tc),_members(tc._members)
{
+ for(vector< std::pair<std::string,TypeCode*> >::iterator iter=_members.begin();iter!=_members.end();iter++)
+ (*iter).second->incrRef();
}
void TypeCodeStruct::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
{
- throw Exception("Not implemented yet : YACS::Any for struct");
+ StructAny::putReprAtPlace(pt,val,this,deepCpy);
}
void TypeCodeStruct::destroyZippedAny(char *data) const
{
- throw Exception("Not implemented yet : YACS::Any for struct");
+ StructAny::destroyReprAtPlace(data,this);
}
AnyPtr TypeCodeStruct::getOrBuildAnyFromZippedData(char *data) const
{
- throw Exception("Not implemented yet : YACS::Any for struct");
+ return StructAny::getOrBuildFromData(data,this);
}
-const char * TypeCodeStruct::id() const throw(Exception)
+const char * TypeCodeStruct::id() const throw(YACS::Exception)
{
return _repoId.c_str();
};
-const char * TypeCodeStruct::name() const throw(Exception)
+const char * TypeCodeStruct::name() const throw(YACS::Exception)
{
return _name.c_str();
}
return _shortName.c_str();
}
+unsigned TypeCodeStruct::getSizeInByteOfAnyReprInSeq() const
+{
+ unsigned ret=0;
+ for(vector< pair<string,TypeCode*> >::const_iterator iter=_members.begin();iter!=_members.end();iter++)
+ ret+=(*iter).second->getSizeInByteOfAnyReprInSeq();
+ return ret;
+}
+
+const TypeCode *TypeCodeStruct::contentType() const throw(YACS::Exception)
+{
+ const char what[]="Content type is specified by giving a key.";
+ throw Exception(what);
+}
+
//! 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)
+int TypeCodeStruct::isA(const char* id) const throw(YACS::Exception)
{
- if(_repoId.c_str() == id)return 1;
+ if(_repoId == id)return 1;
return 0;
}
*/
int TypeCodeStruct::isA(const TypeCode* tc) const
{
- return isA(tc->id());
+ if(_kind != tc->kind()) return 0;
+ if(_repoId == tc->id())return 1;
+ int nMember=memberCount();
+ if(nMember != ((TypeCodeStruct*)tc)->memberCount())return 0;
+ for(int i=0;i<nMember;i++)
+ {
+ const char * name=memberName(i);
+ if(strcmp(memberName(i),((TypeCodeStruct*)tc)->memberName(i)) != 0)return 0;
+ if(!memberType(i)->isA(((TypeCodeStruct*)tc)->memberType(i)))return 0;
+ }
+ return 1;
}
//! Check if this TypeCode is adaptable to a given TypeCode (tc)
*/
int TypeCodeStruct::isAdaptable(const TypeCode* tc) const
{
- if(_kind == tc->kind()) return isA(tc->id());
- return 0;
+ if (_kind != tc->kind()) return 0;
+ if (_repoId == tc->id()) return 1;
+ int nMember = memberCount();
+ if (nMember != ((TypeCodeStruct*)tc)->memberCount()) return 0;
+ for (int i=0 ; i<nMember ; i++)
+ {
+ const char * name = memberName(i);
+ if (strcmp(memberName(i), ((TypeCodeStruct*)tc)->memberName(i)) != 0) return 0;
+ if (!memberType(i)->isAdaptable(((TypeCodeStruct*)tc)->memberType(i))) return 0;
+ }
+ return 1;
+}
+
+//! Check if this TypeCode can be used in place of tc
+/*!
+ * this TypeCode is equivalent to tc if they have the same kind
+ *
+ * \param tc : the TypeCode to compare
+ */
+int TypeCodeStruct::isEquivalent(const TypeCode* tc) const
+{
+ if(_kind != tc->kind()) return 0;
+ int nMember=memberCount();
+ if(nMember != ((TypeCodeStruct*)tc)->memberCount())return 0;
+ for(int i=0;i<nMember;i++)
+ {
+ const char * name=memberName(i);
+ if(strcmp(memberName(i),((TypeCodeStruct*)tc)->memberName(i)) != 0)return 0;
+ if(!memberType(i)->isEquivalent(((TypeCodeStruct*)tc)->memberType(i)))return 0;
+ }
+ return 1;
}
void TypeCodeStruct::addMember(const std::string& name,TypeCode* tc)
throw Exception("Struct member " + name + " already defined");
}
_members.push_back(std::pair<std::string,TypeCode*>(name,tc));
+ tc->incrRef();
+}
+
+//! Get typecode of struct member given its name
+/*!
+ * If name is not an existing key, 0 is returned.
+ * \param name : the member name
+ * \param offset : Out parameter, that specified the location of start of data discriminated by name key.
+ * \return the member TypeCode
+ */
+const TypeCode *TypeCodeStruct::getMember(const std::string& name, unsigned& offset) const
+{
+ std::vector< std::pair<std::string,TypeCode*> >::const_iterator iter;
+ offset=0;
+ for(iter=_members.begin();iter != _members.end(); iter++)
+ {
+ if((*iter).first==name)
+ return (*iter).second;
+ offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
+ }
+ return 0;
}
int TypeCodeStruct::memberCount() const