1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | //***************************************************************************** |
5 | // NSUtilPriv.h |
6 | // |
7 | // Helpers for converting namespace separators. |
8 | // |
9 | //***************************************************************************** |
10 | |
11 | #ifndef __NSUTILPRIV_H__ |
12 | #define __NSUTILPRIV_H__ |
13 | |
14 | template <class T> class CQuickArray; |
15 | class SString; |
16 | |
17 | struct ns |
18 | { |
19 | |
20 | //***************************************************************************** |
21 | // Determine how many chars large a fully qualified name would be given the |
22 | // two parts of the name. The return value includes room for every character |
23 | // in both names, as well as room for the separator and a final terminator. |
24 | //***************************************************************************** |
25 | static |
26 | int GetFullLength( // Number of chars in full name. |
27 | const WCHAR *szNameSpace, // Namspace for value. |
28 | const WCHAR *szName); // Name of value. |
29 | |
30 | static |
31 | int GetFullLength( // Number of chars in full name. |
32 | LPCUTF8 szNameSpace, // Namspace for value. |
33 | LPCUTF8 szName); // Name of value. |
34 | |
35 | //***************************************************************************** |
36 | // Scan the given string to see if the name contains any invalid characters |
37 | // that are not allowed. |
38 | //***************************************************************************** |
39 | static |
40 | int IsValidName( // true if valid, false invalid. |
41 | const WCHAR *szName); // Name to parse. |
42 | |
43 | static |
44 | int IsValidName( // true if valid, false invalid. |
45 | LPCUTF8 szName); // Name to parse. |
46 | |
47 | |
48 | //***************************************************************************** |
49 | // Scan the string from the rear looking for the first valid separator. If |
50 | // found, return a pointer to it. Else return null. This code is smart enough |
51 | // to skip over special sequences, such as: |
52 | // a.b..ctor |
53 | // ^ |
54 | // | |
55 | // The ".ctor" is considered one token. |
56 | //***************************************************************************** |
57 | static |
58 | WCHAR *FindSep( // Pointer to separator or null. |
59 | const WCHAR *szPath); // The path to look in. |
60 | |
61 | static |
62 | LPUTF8 FindSep( // Pointer to separator or null. |
63 | LPCUTF8 szPath); // The path to look in. |
64 | |
65 | |
66 | //***************************************************************************** |
67 | // Take a path and find the last separator (nsFindSep), and then replace the |
68 | // separator with a '\0' and return a pointer to the name. So for example: |
69 | // a.b.c |
70 | // becomes two strings "a.b" and "c" and the return value points to "c". |
71 | //***************************************************************************** |
72 | static |
73 | WCHAR *SplitInline( // Pointer to name portion. |
74 | __inout __inout_z WCHAR *szPath); // The path to split. |
75 | |
76 | static |
77 | LPUTF8 SplitInline( // Pointer to name portion. |
78 | __inout __inout_z LPUTF8 szPath); // The path to split. |
79 | |
80 | static |
81 | void SplitInline( |
82 | __inout __inout_z LPWSTR szPath, // Path to split. |
83 | LPCWSTR &szNameSpace, // Return pointer to namespace. |
84 | LPCWSTR &szName); // Return pointer to name. |
85 | |
86 | static |
87 | void SplitInline( |
88 | __inout __inout_z LPUTF8 szPath, // Path to split. |
89 | LPCUTF8 &szNameSpace, // Return pointer to namespace. |
90 | LPCUTF8 &szName); // Return pointer to name. |
91 | |
92 | |
93 | //***************************************************************************** |
94 | // Split the last parsable element from the end of the string as the name, |
95 | // the first part as the namespace. |
96 | //***************************************************************************** |
97 | static |
98 | int SplitPath( // true ok, false trunction. |
99 | const WCHAR *szPath, // Path to split. |
100 | __out_ecount_opt (cchNameSpace) WCHAR *szNameSpace, // Output for namespace value. |
101 | int cchNameSpace, // Max chars for output. |
102 | __out_ecount_opt (cchName) WCHAR *szName, // Output for name. |
103 | int cchName); // Max chars for output. |
104 | |
105 | static |
106 | int SplitPath( // true ok, false trunction. |
107 | LPCUTF8 szPath, // Path to split. |
108 | __out_ecount_opt (cchNameSpace) LPUTF8 szNameSpace, // Output for namespace value. |
109 | int cchNameSpace, // Max chars for output. |
110 | __out_ecount_opt (cchName) LPUTF8 szName, // Output for name. |
111 | int cchName); // Max chars for output. |
112 | |
113 | |
114 | //***************************************************************************** |
115 | // Take two values and put them together in a fully qualified path using the |
116 | // correct separator. |
117 | //***************************************************************************** |
118 | static |
119 | int MakePath( // true ok, false truncation. |
120 | __out_ecount(cchChars) WCHAR *szOut, // output path for name. |
121 | int cchChars, // max chars for output path. |
122 | const WCHAR *szNameSpace, // Namespace. |
123 | const WCHAR *szName); // Name. |
124 | |
125 | static |
126 | int MakePath( // true ok, false truncation. |
127 | __out_ecount(cchChars) LPUTF8 szOut, // output path for name. |
128 | int cchChars, // max chars for output path. |
129 | LPCUTF8 szNameSpace, // Namespace. |
130 | LPCUTF8 szName); // Name. |
131 | |
132 | static |
133 | int MakePath( // true ok, false truncation. |
134 | __out_ecount(cchChars) WCHAR *szOut, // output path for name. |
135 | int cchChars, // max chars for output path. |
136 | LPCUTF8 szNameSpace, // Namespace. |
137 | LPCUTF8 szName); // Name. |
138 | |
139 | static |
140 | int MakePath( // true ok, false out of memory |
141 | CQuickBytes &qb, // Where to put results. |
142 | LPCUTF8 szNameSpace, // Namespace for name. |
143 | LPCUTF8 szName); // Final part of name. |
144 | |
145 | static |
146 | int MakePath( // true ok, false out of memory |
147 | CQuickArray<WCHAR> &qa, // Where to put results. |
148 | LPCUTF8 szNameSpace, // Namespace for name. |
149 | LPCUTF8 szName); // Final part of name. |
150 | |
151 | static |
152 | int MakePath( // true ok, false out of memory |
153 | CQuickBytes &qb, // Where to put results. |
154 | const WCHAR *szNameSpace, // Namespace for name. |
155 | const WCHAR *szName); // Final part of name. |
156 | |
157 | static |
158 | void MakePath( // throws on out of memory |
159 | SString &ssBuf, // Where to put results. |
160 | const SString &ssNameSpace, // Namespace for name. |
161 | const SString &ssName); // Final part of name. |
162 | |
163 | //***************************************************************************** |
164 | // Concatinate type names to assembly names |
165 | //***************************************************************************** |
166 | static |
167 | bool MakeAssemblyQualifiedName( // true if ok, false if out of memory |
168 | CQuickBytes &qb, // location to put result |
169 | const WCHAR *szTypeName, // Type name |
170 | const WCHAR *szAssemblyName); // Assembly Name |
171 | |
172 | static |
173 | bool MakeAssemblyQualifiedName( // true ok, false truncation |
174 | __out_ecount (dwBuffer) WCHAR* pBuffer, // Buffer to recieve the results |
175 | int dwBuffer, // Number of characters total in buffer |
176 | const WCHAR *szTypeName, // Namespace for name. |
177 | int dwTypeName, // Number of characters (not including null) |
178 | const WCHAR *szAssemblyName, // Final part of name. |
179 | int dwAssemblyName); // Number of characters (not including null) |
180 | |
181 | static |
182 | int MakeNestedTypeName( // true ok, false out of memory |
183 | CQuickBytes &qb, // Where to put results. |
184 | LPCUTF8 szEnclosingName, // Full name for enclosing type |
185 | LPCUTF8 szNestedName); // Full name for nested type |
186 | |
187 | static |
188 | int MakeNestedTypeName( // true ok, false truncation. |
189 | __out_ecount (cchChars) LPUTF8 szOut, // output path for name. |
190 | int cchChars, // max chars for output path. |
191 | LPCUTF8 szEnclosingName, // Full name for enclosing type |
192 | LPCUTF8 szNestedName); // Full name for nested type |
193 | |
194 | static |
195 | void MakeNestedTypeName( // throws on out of memory |
196 | SString &ssBuf, // output path for name. |
197 | const SString &ssEnclosingName, // Full name for enclosing type |
198 | const SString &ssNestedName); // Full name for nested type |
199 | }; // struct ns |
200 | |
201 | #ifndef NAMESPACE_SEPARATOR_CHAR |
202 | #define NAMESPACE_SEPARATOR_CHAR '.' |
203 | #define NAMESPACE_SEPARATOR_WCHAR W('.') |
204 | #define NAMESPACE_SEPARATOR_STR "." |
205 | #define NAMESPACE_SEPARATOR_WSTR W(".") |
206 | #define NAMESPACE_SEPARATOR_LEN 1 |
207 | #define ASSEMBLY_SEPARATOR_CHAR ',' |
208 | #define ASSEMBLY_SEPARATOR_WCHAR W(',') |
209 | #define ASSEMBLY_SEPARATOR_STR ", " |
210 | #define ASSEMBLY_SEPARATOR_WSTR W(", ") |
211 | #define ASSEMBLY_SEPARATOR_LEN 2 |
212 | #define BACKSLASH_CHAR '\\' |
213 | #define BACKSLASH_WCHAR W('\\') |
214 | #define NESTED_SEPARATOR_CHAR '+' |
215 | #define NESTED_SEPARATOR_WCHAR W('+') |
216 | #define NESTED_SEPARATOR_STR "+" |
217 | #define NESTED_SEPARATOR_WSTR W("+") |
218 | #endif |
219 | |
220 | #define EMPTY_STR "" |
221 | #define EMPTY_WSTR W("") |
222 | |
223 | #define MAKE_FULL_PATH_ON_STACK_UTF8(toptr, pnamespace, pname) \ |
224 | { \ |
225 | int __i##toptr = ns::GetFullLength(pnamespace, pname); \ |
226 | toptr = (char *) alloca(__i##toptr); \ |
227 | ns::MakePath(toptr, __i##toptr, pnamespace, pname); \ |
228 | } |
229 | |
230 | #define MAKE_FULL_PATH_ON_STACK_UNICODE(toptr, pnamespace, pname) \ |
231 | { \ |
232 | int __i##toptr = ns::GetFullLength(pnamespace, pname); \ |
233 | toptr = (WCHAR *) alloca(__i##toptr * sizeof(WCHAR)); \ |
234 | ns::MakePath(toptr, __i##toptr, pnamespace, pname); \ |
235 | } |
236 | |
237 | #define MAKE_FULLY_QUALIFIED_NAME(pszFullyQualifiedName, pszNameSpace, pszName) MAKE_FULL_PATH_ON_STACK_UTF8(pszFullyQualifiedName, pszNameSpace, pszName) |
238 | |
239 | #define MAKE_FULLY_QUALIFIED_MEMBER_NAME(ptr, pszNameSpace, pszClassName, pszMemberName, pszSig) \ |
240 | { \ |
241 | int __i##ptr = ns::GetFullLength(pszNameSpace, pszClassName); \ |
242 | __i##ptr += (pszMemberName ? (int) strlen(pszMemberName) : 0); \ |
243 | __i##ptr += (NAMESPACE_SEPARATOR_LEN * 2); \ |
244 | __i##ptr += (pszSig ? (int) strlen(pszSig) : 0); \ |
245 | ptr = (LPUTF8) alloca(__i##ptr); \ |
246 | ns::MakePath(ptr, __i##ptr, pszNameSpace, pszClassName); \ |
247 | if (pszMemberName) { \ |
248 | strcat_s(ptr, __i##ptr, NAMESPACE_SEPARATOR_STR); \ |
249 | strcat_s(ptr, __i##ptr, pszMemberName); \ |
250 | } \ |
251 | if (pszSig) { \ |
252 | if (! pszMemberName) \ |
253 | strcat_s(ptr, __i##ptr, NAMESPACE_SEPARATOR_STR); \ |
254 | strcat_s(ptr, __i##ptr, pszSig); \ |
255 | } \ |
256 | } |
257 | |
258 | #ifdef _PREFAST_ |
259 | // need to eliminate the expansion of MAKE_FULLY_QUALIFIED_MEMBER_NAME in prefast |
260 | // builds to prevent it complaining about the potential for NULLs to strlen and strcat |
261 | #undef MAKE_FULLY_QUALIFIED_MEMBER_NAME |
262 | // need to set ptr=NULL so we don't get a build error because ptr isn't inited in a couple cases |
263 | #define MAKE_FULLY_QUALIFIED_MEMBER_NAME(ptr, pszNameSpace, pszClassName, pszMemberName, pszSig) ptr=NULL; |
264 | #endif |
265 | |
266 | #endif |
267 | |