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