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