1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #include <DotNetNames.h>
6 #include <ctype.h>
7 #include <cstring>
8 
9 using namespace std;
10 
11 namespace Slice
12 {
13 
14 namespace DotNet
15 {
16 
17 struct Node
18 {
19     const char** names;
20     const Node** parents;
21 };
22 
23 static const char* ObjectNames[] =
24                     {
25                         "Equals", "Finalize", "GetHashCode", "GetType",
26                         "MemberwiseClone", "ReferenceEquals", "ToString", 0
27                     };
28 static const Node* ObjectParents[] =
29                     {
30                         0
31                     };
32 static const Node ObjectNode =
33                     {
34                         ObjectNames, &ObjectParents[0]
35                     };
36 
37 static const char* ICloneableNames[] =
38                     {
39                         "Clone", 0
40                     };
41 static const Node* ICloneableParents[] =
42                     {
43                         &ObjectNode, 0
44                     };
45 static const Node ICloneableNode =
46                     {
47                         ICloneableNames, &ICloneableParents[0]
48                     };
49 
50 static const char* ExceptionNames[] =
51                     {
52                         "Data", "GetBaseException", "GetObjectData", "HelpLink", "HResult", "InnerException",
53                         "Message", "Source", "StackTrace", "TargetSite", 0
54                     };
55 static const Node* ExceptionParents[] =
56                     {
57                         &ObjectNode, 0
58                     };
59 static const Node ExceptionNode =
60                     {
61                         ExceptionNames, &ExceptionParents[0]
62                     };
63 
64 //
65 // Must be kept in same order as definition of BaseType in header file!
66 //
67 static const Node* nodes[] =
68                     {
69                         &ObjectNode, &ICloneableNode, &ExceptionNode
70                     };
71 
72 static bool
ciEquals(const string & s,const char * p)73 ciEquals(const string& s, const char* p)
74 {
75     if(s.size() != strlen(p))
76     {
77         return false;
78     }
79     string::const_iterator i = s.begin();
80     while(i != s.end())
81     {
82         if(tolower(static_cast<unsigned char>(*i++)) != tolower(static_cast<unsigned char>(*p++)))
83         {
84             return false;
85         }
86     }
87     return true;
88 }
89 
90 const char* manglePrefix = "ice_";
91 const char* mangleSuffix = "_";
92 
93 static bool
mangle(const string & s,const Node * np,string & newName)94 mangle(const string& s, const Node* np, string& newName)
95 {
96     const char** namep = np->names;
97     while(*namep)
98     {
99         if(ciEquals(s, *namep))
100         {
101             newName = manglePrefix + s + mangleSuffix;
102             return true;
103         }
104         ++namep;
105     }
106     const Node** parentp = np->parents;
107     while(*parentp)
108     {
109         if(mangle(s, *parentp, newName))
110         {
111             return true;
112         }
113         ++parentp;
114     }
115     return false;
116 }
117 
118 }
119 
120 }
121 
122 string
mangleName(const string & s,int baseTypes)123 Slice::DotNet::mangleName(const string& s, int baseTypes)
124 {
125     if(baseTypes == 0)
126     {
127         return s;
128     }
129     string newName;
130     for(unsigned int mask = 1, i=0; mask < END; mask <<= 1, ++i)
131     {
132         if(baseTypes & mask)
133         {
134             if(mangle(s, nodes[i], newName))
135             {
136                 return newName;
137             }
138         }
139     }
140     return s;
141 }
142