Salome HOME
Use pyobj type in optimizer loop.
[modules/yacs.git] / src / engine / TypeCode.cxx
1 // Copyright (C) 2006-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "TypeCode.hxx"
21 #include <sstream>
22 #include <iostream>
23 #include <cstring>
24
25 //#define _DEVDEBUG_
26 #include "YacsTrace.hxx"
27
28 using namespace YACS::ENGINE;
29 using namespace std;
30
31 const char *TypeCode::KIND_STR_REPR []={ "None", "double", "int", "string", "bool", "Objref", "Sequence", "Array","Struct" };
32
33 // --- TypeCode
34
35 TypeCode::TypeCode(DynType kind):_kind(kind)
36 {
37 }
38
39 TypeCode::TypeCode(const TypeCode& tc):_kind(tc._kind)
40 {
41 }
42
43 TypeCode::~TypeCode()
44 {
45 }
46
47 DynType TypeCode::kind() const
48 {
49   return _kind;
50 }
51
52 TypeCode *TypeCode::clone() const
53 {
54   return new TypeCode(*this);
55 }
56
57 void TypeCode::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
58 {
59   AtomAny::putReprAtPlace(pt,val,this,deepCpy);
60 }
61
62 void TypeCode::destroyZippedAny(char *data) const
63 {
64   AtomAny::destroyReprAtPlace(data,this);
65 }
66
67 AnyPtr TypeCode::getOrBuildAnyFromZippedData(char *data) const
68 {
69   return AtomAny::getOrBuildFromData(data,this);
70 }
71
72 const char * TypeCode::name() const throw(YACS::Exception)
73 {
74   return id();
75 }
76
77 const char * TypeCode::shortName() const
78 {
79   return id();
80 }
81
82 const char * TypeCode::id() const throw(YACS::Exception)
83 {
84   switch(_kind)
85     {
86     case Double:
87       return "double";
88     case Int:
89       return "int";
90     case String:
91       return "string";
92     case Bool:
93       return "bool";
94     default:
95       return "";
96     }
97 }
98
99 int TypeCode::isA(const char* id) const throw(YACS::Exception)
100 {
101   throw Exception("Not implemented for this type");
102 }
103
104 int TypeCode::isA(const TypeCode* tc) const 
105 {
106   if(_kind == tc->kind()) return 1;
107   return 0;
108 }
109
110 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
111 /*!
112  * this TypeCode is adaptable to tc if tc type can be converted to this type
113  *
114  *   \param tc : the TypeCode that must be convertible to this
115  */
116 int TypeCode::isAdaptable(const TypeCode* tc) const
117 {
118   switch(_kind)
119     {
120     case Double:
121       if (tc->kind() == Double) return 1;
122       if (tc->kind() == Int) return 1;
123       return 0;
124     case Int:
125       if (tc->kind() == Int) return 1;
126       return 0;
127     case String:
128       if (tc->kind() == String) return 1;
129       return 0;
130     case Bool:
131       if (tc->kind() == Bool) return 1;
132       if (tc->kind() == Int) return 1;
133       return 0;
134     default:
135       //objref, sequence, ...
136       return 0;
137     }
138 }
139
140 std::string TypeCode::getPrintStr() const
141 {
142   return id();
143 }
144
145 //! Check if this TypeCode can be used in place of tc
146 /*!
147  * this TypeCode is equivalent to tc if they have the same kind
148  *
149  *   \param tc : the TypeCode to compare
150  */
151 int TypeCode::isEquivalent(const TypeCode* tc) const 
152 {
153   if(_kind == tc->kind()) return 1;
154   return 0;
155 }
156
157 unsigned TypeCode::getSizeInByteOfAnyReprInSeq() const
158 {
159   switch(_kind)
160     {
161     case Double:
162       return sizeof(double);
163     case Int:
164       return sizeof(int);
165     case String:
166       return sizeof(StringOnHeap *);
167     case Bool:
168       return sizeof(bool);
169     default:
170       return sizeof(void *);
171     }
172 }
173
174 const TypeCode * TypeCode::contentType() const throw(YACS::Exception)
175 {
176   throw Exception("No content type");
177 };
178
179 static inline int validChar0(char c)
180 {
181   return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
182 }
183
184 static inline int validNextChar(char c)
185 {
186   return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
187           (c >= '0' && c <= '9') || (c == '_') || (c == '/'));
188 }
189
190 static void checkValidName(const char* name)
191 {
192   int ok = 1;
193   if (*name) 
194     {
195       if (!validChar0(*name++)) ok = 0;
196       for(; ok && *name; name++) if (!validNextChar(*name)) ok = 0; 
197     }
198   if (!ok)throw YACS::Exception("Invalid Name");
199 }
200
201 const char *TypeCode::getKindRepr(DynType kind)
202 {
203   return KIND_STR_REPR[(int)kind];
204 }
205
206 const TypeCode *TypeCode::subContentType(int lev) const
207 {
208   if(lev<0)
209     throw YACS::Exception("subContentType: Invalid input val !");
210   if(lev==0)
211     return this;
212   const TypeCode *ret(this);
213   for(int i=0;i<lev;i++)
214     {
215       const TypeCode *cand(ret->contentType());
216       if(!cand)
217         throw YACS::Exception("subContentType : Invalid input val 2 !");
218       ret=cand;
219     }
220   return ret;
221 }
222
223 const char * TypeCode::getKindRepr() const
224 {
225   return KIND_STR_REPR[(int)_kind];
226 }
227
228 //! static factory of object reference type given an id and a name
229 TypeCode * TypeCode::interfaceTc(const char* id,
230                                   const char* name)
231 {
232   checkValidName(name);
233   return new TypeCodeObjref(id, name);
234 };
235
236 //! static factory of object reference type given an id, a name and a list of base types
237 /*!
238  *   \param id :  the id
239  *   \param name :  the name
240  *   \param ltc :  the list of base types
241  *
242  *   The name must be a valid one (throw Exception is not)
243  */
244 TypeCode * TypeCode::interfaceTc(const char* id,
245                                   const char* name,
246                                   const std::list<TypeCodeObjref *>& ltc)
247 {
248   checkValidName(name);
249   return new TypeCodeObjref(id, name,ltc);
250 }
251
252
253 //! static factory of sequence type given an id, a name and a content type
254 TypeCode * TypeCode::sequenceTc(const char* id,
255                                  const char* name,
256                                  TypeCode *content)
257 {
258   std::string typname;
259   if(std::string(name)=="")
260     {
261       typname="seq"+std::string(content->name());
262       name=typname.c_str();
263     }
264   if(std::string(id)=="")
265     id=name;
266   return new TypeCodeSeq(id, name,content);
267 };
268 //! static factory of struct type given an id and a name 
269 TypeCode * TypeCode::structTc(const char* id,
270                                  const char* name)
271 {
272   return new TypeCodeStruct(id, name);
273 };
274
275 TypeCodeComposed::TypeCodeComposed(const TypeCodeComposed& other):TypeCode(other),
276                                                                   _name(other._name),_repoId(other._repoId),
277                                                                   _shortName(other._shortName)
278 {
279 }
280
281 TypeCodeComposed::TypeCodeComposed(DynType kind, const char* repositoryId, const char* name):TypeCode(kind),
282                                                                                              _repoId(repositoryId),_name(name)
283 {
284   string::size_type debut =_name.find_last_of('/');
285   if(debut == std::string::npos)
286     _shortName= name;
287   else
288     _shortName=_name.substr(debut+1);
289 }
290
291 // --- TypeCodeObjref
292
293
294 TypeCodeObjref::TypeCodeObjref(const char* repositoryId, 
295                                const char* name) : TypeCodeComposed(Objref,repositoryId,name)
296 {
297 }
298
299
300 TypeCodeObjref::~TypeCodeObjref()
301 {
302   list<TypeCodeObjref *>::iterator iter;
303   for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
304     (*iter)->decrRef();
305 }
306
307 TypeCode *TypeCodeObjref::clone() const
308 {
309   return new TypeCodeObjref(*this);
310 }
311
312 void TypeCodeObjref::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
313 {
314   AtomAny::putReprAtPlace(pt,val,this,deepCpy);
315 }
316
317 void TypeCodeObjref::destroyZippedAny(char *data) const
318 {
319   AtomAny::destroyReprAtPlace(data,this);
320 }
321
322 AnyPtr TypeCodeObjref::getOrBuildAnyFromZippedData(char *data) const
323 {
324   return AtomAny::getOrBuildFromData(data,this);
325 }
326
327 const char * TypeCodeObjref::id() const throw(YACS::Exception)
328 {
329   return _repoId.c_str();
330 };
331
332 const char * TypeCodeObjref::name() const throw(YACS::Exception)
333 {
334   return _name.c_str();
335 }
336
337 const char * TypeCodeObjref::shortName() const
338 {
339   return _shortName.c_str();
340 }
341
342 TypeCodeObjref::TypeCodeObjref(const char* repositoryId,
343                                const char* name,
344                                const std::list<TypeCodeObjref *>& ltc) : TypeCodeComposed(Objref,repositoryId,name)
345 {
346   _listOfBases=ltc;
347   list<TypeCodeObjref *>::const_iterator iter;
348   for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
349     (*iter)->incrRef();
350 }
351
352 //! Check if this TypeCode is derived from a TypeCode with a given id
353 /*!
354  *   \param id :  a given id
355  *   \return     1 if true, 0 if false
356  */
357 int TypeCodeObjref::isA(const char* id) const throw(YACS::Exception)
358 {
359   if(_repoId == id)return 1;
360   list<TypeCodeObjref *>::const_iterator iter;
361   for(iter=_listOfBases.begin();iter != _listOfBases.end(); iter++)
362     {
363       if ((*iter)->isA(id)) return 1;
364     }
365   return 0;
366 }
367
368 //! Check if this TypeCode is derived from a given TypeCode
369 /*!
370  *   \param tc : the given TypeCode
371  *   \return    1 if true, 0 if false
372  */
373 int TypeCodeObjref::isA(const TypeCode* tc) const
374 {
375   return isA(tc->id());
376 }
377
378 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
379 /*!
380  *   \param tc : the given TypeCode
381  *   \return    1 if true, 0 if false
382  */
383 int TypeCodeObjref::isAdaptable(const TypeCode* tc) const
384 {
385   if(_kind == tc->kind()) return isA(tc->id());
386   return 0;
387 }
388
389 //! Check if this TypeCode can be used in place of tc
390 /*!
391  * this TypeCode is equivalent to tc if they have the same kind
392  *
393  *   \param tc : the TypeCode to compare
394  */
395 int TypeCodeObjref::isEquivalent(const TypeCode* tc) const 
396 {
397   if(_kind != tc->kind())return 0;
398   if(_repoId == tc->id())return 1;
399   return 0;
400 }
401
402 TypeCodeObjref::TypeCodeObjref(const TypeCodeObjref& other):TypeCodeComposed(other),
403                                                             _listOfBases(other._listOfBases)
404 {
405   list<TypeCodeObjref *>::const_iterator iter;
406   for(iter=other._listOfBases.begin();iter!=other._listOfBases.end();iter++)
407     (*iter)->incrRef();
408 }
409
410 // --- TypeCodeSeq
411
412
413 //! Create a sequence type with a given name, a given id and a given contained type.
414 /*!
415  *   \param repositoryId : the given id
416  *   \param name : the given name
417  *   \param content : the given contained TypeCode
418  */
419 TypeCodeSeq::TypeCodeSeq(const char* repositoryId,
420                          const char* name, 
421                          const TypeCode *content) : TypeCodeComposed(Sequence,repositoryId,name), _content(content)
422 {
423   _content->incrRef();
424 }
425
426 TypeCodeSeq::~TypeCodeSeq()
427 {
428   ((TypeCode *)_content)->decrRef();
429 }
430
431 TypeCode *TypeCodeSeq::clone() const
432 {
433   return new TypeCodeSeq(*this);
434 }
435
436 void TypeCodeSeq::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
437 {
438   SequenceAny::putReprAtPlace(pt,val,this,deepCpy);
439 }
440
441 void TypeCodeSeq::destroyZippedAny(char *data) const
442 {
443   SequenceAny::destroyReprAtPlace(data,this);
444 }
445
446 unsigned TypeCodeSeq::getSizeInByteOfAnyReprInSeq() const
447 {
448   return sizeof(void*);
449 }
450
451 AnyPtr TypeCodeSeq::getOrBuildAnyFromZippedData(char *data) const
452 {
453   return SequenceAny::getOrBuildFromData(data,this);
454 }
455
456 const char * TypeCodeSeq::id() const throw(YACS::Exception)
457 {
458   return _repoId.c_str();
459 }
460
461 const char * TypeCodeSeq::name() const throw(YACS::Exception)
462 {
463   return _name.c_str();
464 }
465 const char * TypeCodeSeq::shortName() const
466 {
467   return _shortName.c_str();
468 }
469
470 std::string TypeCodeSeq::getPrintStr() const
471 {
472   std::ostringstream oss; oss << "seq[" << contentType()->getPrintStr() << "]";
473   return oss.str();
474 }
475
476 const TypeCode * TypeCodeSeq::contentType() const throw(YACS::Exception)
477 {
478   return _content;
479 }
480
481 int TypeCodeSeq::isA(const TypeCode* tc) const
482 {
483   if(_kind == tc->kind())
484     return _content->isA(tc->contentType());
485   return 0;
486 }
487
488 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
489 /*!
490  *   \param tc : the given TypeCode
491  *   \return    1 if true, 0 if false
492  */
493 int TypeCodeSeq::isAdaptable(const TypeCode* tc) const
494 {
495   if(_kind == tc->kind())
496     return contentType()->isAdaptable(tc->contentType());
497   return 0;
498 }
499
500 //! Check if this TypeCode can be used in place of tc
501 /*!
502  * this TypeCode is equivalent to tc if they have the same kind
503  *
504  *   \param tc : the TypeCode to compare
505  */
506 int TypeCodeSeq::isEquivalent(const TypeCode* tc) const 
507 {
508   if(_kind == tc->kind())
509     return _content->isEquivalent(tc->contentType());
510   return 0;
511 }
512
513 TypeCodeSeq::TypeCodeSeq(const TypeCodeSeq& tc):TypeCodeComposed(tc),
514                                                 _content(tc._content)
515 {
516   _content->incrRef();
517 }
518
519 // --- TypeCodeArray
520
521
522 //! Create an Array type with a given name, a given id and a given contained type.
523 /*!
524  *   \param repositoryId : the given id
525  *   \param name : the given name
526  *   \param content : the given contained TypeCode
527  *   \param staticLgth : the length
528  */
529 TypeCodeArray::TypeCodeArray(const char* repositoryId,
530                              const char* name, 
531                              const TypeCode *content,
532                              unsigned staticLgth) : TypeCodeComposed(Array,repositoryId,name), _content(content),_staticLgth(staticLgth)
533 {
534   _content->incrRef();
535 }
536
537 TypeCodeArray::~TypeCodeArray()
538 {
539   ((TypeCode *)_content)->decrRef();
540 }
541
542 TypeCode *TypeCodeArray::clone() const
543 {
544   return new TypeCodeArray(*this);
545 }
546
547 void TypeCodeArray::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
548 {
549   ArrayAny::putReprAtPlace(pt,val,this,deepCpy);
550 }
551
552 void TypeCodeArray::destroyZippedAny(char *data) const
553 {
554   ArrayAny::destroyReprAtPlace(data,this);
555 }
556
557 AnyPtr TypeCodeArray::getOrBuildAnyFromZippedData(char *data) const
558 {
559   return ArrayAny::getOrBuildFromData(data,this);
560 }
561
562 const char * TypeCodeArray::id() const throw(YACS::Exception)
563 {
564   return _repoId.c_str();
565 }
566
567 const char * TypeCodeArray::name() const throw(YACS::Exception)
568 {
569   return _name.c_str();
570 }
571 const char * TypeCodeArray::shortName() const
572 {
573   return _shortName.c_str();
574 }
575
576 unsigned TypeCodeArray::getStaticLgth() const
577 {
578   return _staticLgth;
579 }
580
581 const TypeCode * TypeCodeArray::contentType() const throw(YACS::Exception)
582 {
583   return _content;
584 }
585
586 int TypeCodeArray::isA(const TypeCode* tc) const
587 {
588   if(_kind == tc->kind())
589     if(_content->isA(tc->contentType()))
590       {
591         const TypeCodeArray *tcC=dynamic_cast<const TypeCodeArray *>(tc);
592         if(tcC)
593           return tcC->getStaticLgth()==_staticLgth;
594         return 0;
595       }
596   return 0;
597 }
598
599 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
600 /*!
601  *   \param tc : the given TypeCode
602  *   \return    1 if true, 0 if false
603  */
604 int TypeCodeArray::isAdaptable(const TypeCode* tc) const
605 {
606   if(_kind == tc->kind())
607     return contentType()->isAdaptable(tc->contentType());
608   return 0;
609 }
610
611 //! Check if this TypeCode can be used in place of tc
612 /*!
613  * this TypeCode is equivalent to tc if they have the same kind
614  *
615  *   \param tc : the TypeCode to compare
616  */
617 int TypeCodeArray::isEquivalent(const TypeCode* tc) const 
618 {
619   if(_kind == tc->kind())
620     return _content->isEquivalent(tc->contentType());
621   return 0;
622 }
623
624 TypeCodeArray::TypeCodeArray(const TypeCodeArray& tc):TypeCodeComposed(tc),
625                                                       _content(tc._content),
626                                                       _staticLgth(tc._staticLgth)
627 {
628   _content->incrRef();
629 }
630
631 unsigned TypeCodeArray::getSizeInByteOfAnyReprInSeq() const
632 {
633   return _staticLgth*_content->getSizeInByteOfAnyReprInSeq();
634 }
635
636 // --- TypeCodeStruct
637
638
639 //! Create a struct type with a given name and a given id 
640 /*!
641  *   \param repositoryId : the given id
642  *   \param name : the given name
643  */
644 TypeCodeStruct::TypeCodeStruct(const char* repositoryId, 
645                                const char* name) : TypeCodeComposed(Struct,repositoryId,name)
646 {
647 }
648
649 TypeCodeStruct::~TypeCodeStruct()
650 {
651   for(vector< pair<string,TypeCode*> >::iterator iter=_members.begin();iter!=_members.end();iter++)
652     (*iter).second->decrRef();
653 }
654
655 TypeCode *TypeCodeStruct::clone() const
656 {
657   return new TypeCodeStruct(*this);
658 }
659
660 TypeCodeStruct::TypeCodeStruct(const TypeCodeStruct& tc):TypeCodeComposed(tc),_members(tc._members)
661 {
662   for(vector< std::pair<std::string,TypeCode*> >::iterator iter=_members.begin();iter!=_members.end();iter++)
663     (*iter).second->incrRef();
664 }
665
666 void TypeCodeStruct::putReprAtPlace(char *pt, const char *val, bool deepCpy) const
667 {
668   StructAny::putReprAtPlace(pt,val,this,deepCpy);
669 }
670
671 void TypeCodeStruct::destroyZippedAny(char *data) const
672 {
673   StructAny::destroyReprAtPlace(data,this);
674 }
675
676 AnyPtr TypeCodeStruct::getOrBuildAnyFromZippedData(char *data) const
677 {
678   return StructAny::getOrBuildFromData(data,this);
679 }
680
681 const char * TypeCodeStruct::id() const throw(YACS::Exception)
682 {
683   return _repoId.c_str();
684 };
685
686 const char * TypeCodeStruct::name() const throw(YACS::Exception)
687 {
688   return _name.c_str();
689 }
690
691 const char * TypeCodeStruct::shortName() const
692 {
693   return _shortName.c_str();
694 }
695
696 unsigned TypeCodeStruct::getSizeInByteOfAnyReprInSeq() const
697 {
698   unsigned ret=0;
699   for(vector< pair<string,TypeCode*> >::const_iterator iter=_members.begin();iter!=_members.end();iter++)
700     ret+=(*iter).second->getSizeInByteOfAnyReprInSeq();
701   return ret;
702 }
703
704 const TypeCode *TypeCodeStruct::contentType() const throw(YACS::Exception)
705 {
706   const char what[]="Content type is specified by giving a key.";
707   throw Exception(what);
708 }
709
710 //! Check if this TypeCode is derived from a TypeCode with a given id
711 /*!
712  *   \param id :  a given id
713  *   \return     1 if true, 0 if false
714  */
715 int TypeCodeStruct::isA(const char* id) const throw(YACS::Exception)
716 {
717   if(_repoId == id)return 1;
718   return 0;
719 }
720
721 //! Check if this TypeCode is derived from a given TypeCode
722 /*!
723  *   \param tc : the given TypeCode
724  *   \return    1 if true, 0 if false
725  */
726 int TypeCodeStruct::isA(const TypeCode* tc) const 
727 {
728   if(_kind != tc->kind()) return 0;
729   if(_repoId == tc->id())return 1;
730   int nMember=memberCount();
731   if(nMember != ((TypeCodeStruct*)tc)->memberCount())return 0;
732   for(int i=0;i<nMember;i++)
733     {
734        const char * name=memberName(i);
735        if(strcmp(memberName(i),((TypeCodeStruct*)tc)->memberName(i)) != 0)return 0;
736        if(!memberType(i)->isA(((TypeCodeStruct*)tc)->memberType(i)))return 0;
737     }
738   return 1;
739 }
740
741 //! Check if this TypeCode is adaptable to a given TypeCode (tc)
742 /*!
743  *   \param tc : the given TypeCode
744  *   \return    1 if true, 0 if false
745  */
746 int TypeCodeStruct::isAdaptable(const TypeCode* tc) const
747 {
748   if (_kind != tc->kind()) return 0;
749   if (_repoId == tc->id()) return 1;
750   int nMember = memberCount();
751   if (nMember != ((TypeCodeStruct*)tc)->memberCount()) return 0;
752   for (int i=0 ; i<nMember ; i++)
753     {
754       const char * name = memberName(i);
755       if (strcmp(memberName(i), ((TypeCodeStruct*)tc)->memberName(i)) != 0) return 0;
756       if (!memberType(i)->isAdaptable(((TypeCodeStruct*)tc)->memberType(i))) return 0;
757     }
758   return 1;
759 }
760
761 //! Check if this TypeCode can be used in place of tc
762 /*!
763  * this TypeCode is equivalent to tc if they have the same kind
764  *
765  *   \param tc : the TypeCode to compare
766  */
767 int TypeCodeStruct::isEquivalent(const TypeCode* tc) const 
768 {
769   if(_kind != tc->kind()) return 0;
770   int nMember=memberCount();
771   if(nMember != ((TypeCodeStruct*)tc)->memberCount())return 0;
772   for(int i=0;i<nMember;i++)
773     {
774        const char * name=memberName(i);
775        if(strcmp(memberName(i),((TypeCodeStruct*)tc)->memberName(i)) != 0)return 0;
776        if(!memberType(i)->isEquivalent(((TypeCodeStruct*)tc)->memberType(i)))return 0;
777     }
778   return 1;
779 }
780
781 void TypeCodeStruct::addMember(const std::string& name,TypeCode* tc)
782 {
783   DEBTRACE(name << " " << tc->name());
784   std::vector< std::pair<std::string,TypeCode*> >::const_iterator iter;
785   for(iter=_members.begin();iter != _members.end(); iter++)
786     {
787       if((*iter).first == name)
788         throw Exception("Struct member " + name + " already defined");
789     }
790   _members.push_back(std::pair<std::string,TypeCode*>(name,tc));
791   tc->incrRef();
792 }
793
794 //! Get typecode of struct member given its name
795 /*!
796  * If name is not an existing key, 0 is returned.
797  * \param name : the member name
798  * \param offset : Out parameter, that specified the location of start of data discriminated by name key.
799  * \return the member TypeCode
800  */
801 const TypeCode *TypeCodeStruct::getMember(const std::string& name, unsigned& offset) const
802 {
803   std::vector< std::pair<std::string,TypeCode*> >::const_iterator iter;
804   offset=0;
805   for(iter=_members.begin();iter != _members.end(); iter++)
806     {
807       if((*iter).first==name)
808         return (*iter).second;
809       offset+=(*iter).second->getSizeInByteOfAnyReprInSeq();
810     }
811   return 0;
812 }
813
814 int TypeCodeStruct::memberCount() const
815 {
816   return _members.size();
817 }
818
819 const char*  TypeCodeStruct::memberName(int index) const
820 {
821   if(index > _members.size())
822     {
823       stringstream msg;
824       msg << "Struct size less than " << index;
825       msg << " : " << __FILE__ << ":" << __LINE__;
826       throw Exception(msg.str());
827     }
828   return _members[index].first.c_str();
829 }
830
831 TypeCode*  TypeCodeStruct::memberType(int index) const
832 {
833   if(index > _members.size())
834     {
835       stringstream msg;
836       msg << "Struct size less than " << index;
837       msg << " : " << __FILE__ << ":" << __LINE__;
838       throw Exception(msg.str());
839     }
840   return _members[index].second;
841 }
842
843