1 
2 #include <iostream>
3 #include <cstring>
4 #include <cstdlib>
5 #include <algorithm>
6 #include <iostream>
7 using namespace std;
8 
9 #include <ossim/base/ossimRtti.h>
10 
11 static const RTTITypeinfo* RTTI_base_null_type[] = { 0 };
12 
13 const RTTITypeinfo* RTTIdyntypeid::a[] = { 0 };
14 
15 const RTTITypeinfo RTTITypeinfo::null_type = RTTITypeinfo("NULL", RTTI_base_null_type,0,0);
16 
add_subtype(const RTTITypeinfo * t)17 void RTTITypeinfo::add_subtype(const RTTITypeinfo* t)		//Adds t as last RTTITypeinfo in the
18 {
19   subtypes.push_back(t);
20   ns = subtypes.size();
21 							//'subtypes' list. For this, the
22 /*   const RTTITypeinfo** ptr = new const RTTITypeinfo*[ns+1];		//list is realloc'd with one extra entry.
23    int i; for(i=0;i<ns;i++) ptr[i] = subtypes[i];
24    ptr[i] = t;
25    ns++;
26    delete[] subtypes;
27    subtypes = ptr;
28    */
29 }
30 
del_subtype(const RTTITypeinfo * t)31 void RTTITypeinfo::del_subtype(const RTTITypeinfo* t) //Searches for t in the subtypes list
32 {
33    if ( subtypes.size() > 0 )
34    {
35       SubtypesConstVector::iterator iter = std::find(subtypes.begin(), subtypes.end(), t);
36       if(iter != subtypes.end())
37       {
38          subtypes.erase(iter);
39 
40          // "ns" is private member of RTTITypeinfo
41          ns = subtypes.size();
42       }
43    }
44 
45  //of this and removes it, if found.
46 
47 //   int i; for(i=0;i<ns && subtypes[i]!=t;i++);
48 //   if (i<ns)
49 //     for(;i<ns-1;i++) subtypes[i] = subtypes[i+1];
50 }
51 
RTTITypeinfo(const char * name,const RTTITypeinfo * bb[],void * (* f1)(int,void *),void * (* f2)())52 RTTITypeinfo::RTTITypeinfo(const char* name,
53                            const RTTITypeinfo* bb[],
54                            void* (*f1)(int,void*),
55                            void* (*f2)())
56 {
57   n = "";
58   if(name) n = name;
59   b = bb; //ns = 0; subtypes = 0;		//Create default RTTITypeinfo
60   cast    = f1;								//Attach casting func
61   new_obj = f2;								//Attach creation func
62   int i = 0;
63   for(i=0;b[i];i++)							//Add this as subtype to all its basetypes
64      ((RTTITypeinfo**)b)[i]->add_subtype(this);				//REMARK: Harmless const castaway
65 }
66 
getname() const67 const char* RTTITypeinfo::getname() const
68 {
69   return n.c_str();
70 }
71 
72 
~RTTITypeinfo()73 RTTITypeinfo::~RTTITypeinfo()
74 {
75 //   if(n)
76 //   {
77 //      free(n);
78 //      n = NULL;
79 //   }
80    int i = 0;
81    for(i=0;b[i];i++)
82    {
83       //Del this subtype from all its basetypes
84       ((RTTITypeinfo**)b)[i]->del_subtype(this); //REMARK: Harmless const castaway
85    }
86 }
87 
has_base(const RTTITypeinfo * p) const88 int RTTITypeinfo::has_base(const RTTITypeinfo* p) const
89 {
90   int i = 0;
91    for(i=0;b[i];i++)							//for all bases of this...
92       if (p->same(b[i]) || b[i]->has_base(p)) return 1;				//match found, return 1 or no match, search deeper
93    return 0;									//no match at all, return 0
94 }
95 
create(const RTTITypeinfo * bt,const char * c) const96 void* RTTITypeinfo::create(const RTTITypeinfo* bt, const char* c) const	//Tries to create an obj of type-name
97 {										//given by char*. Searches for this type in the
98    void* p = 0; int i;								//type-DAG rooted by this, creates it and returns
99 										//it as cast to 'bt', where bt is either this or a
100 										//direct base of this.
101    if (!strcmp(c,getname()))								//Want to create an obj of this type ?
102       p = (new_obj)? new_obj() : 0;						//Yes, do it if this type is instantiable.
103    else										//No, try with subclasses...
104       for(i=0;i<ns && !((p=subtypes[i]->create(this,c)));i++);			//Succeeded creating on ith subclass branch ?
105    if (!p) return 0;								//Couldn't create it in any way, abort.
106    if (bt==this) i = -1;							//Must cast to this's own type (i==-1)
107    else for(i=0;b[i] && b[i]!=bt;i++);						//Search to which base of this we should cast
108 									        //Found: cast to ith base of this
109    return cast(i,p);								//Cast to ith base of to this, return as void*
110 }
111 
find_baseclass(const char * name) const112 RTTItypeid RTTItypeid::find_baseclass(const char* name)const
113 {
114    if(strcmp(name, getname())==0)
115    {
116       return *this;
117    }
118    else if(num_baseclasses() == 0)
119    {
120       if(strcmp(name, getname()) == 0)
121       {
122          return *this;
123       }
124       return null_type();
125    }
126    else
127    {
128       int index = 0;
129 
130       while(index < num_baseclasses())
131       {
132          RTTItypeid typeId = baseclass(index);
133          if(typeId == *this)
134          {
135 	   return *this;//null_type();
136          }
137          if(strcmp(name, typeId.getname()) == 0)
138          {
139             return *this;
140          }
141          ++index;
142       }
143       index = 0;
144       while(index < num_baseclasses())
145       {
146          RTTItypeid typeId = baseclass(index);
147          if(typeId.find_baseclass(name) == typeId.null_type())
148          {
149             ++index;
150          }
151          else
152          {
153             return typeId;
154          }
155       }
156    }
157    return null_type();
158 }
159