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