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
14template <class T> class CQuickArray;
15class SString;
16
17struct 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//*****************************************************************************
25static
26int GetFullLength( // Number of chars in full name.
27 const WCHAR *szNameSpace, // Namspace for value.
28 const WCHAR *szName); // Name of value.
29
30static
31int 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//*****************************************************************************
39static
40int IsValidName( // true if valid, false invalid.
41 const WCHAR *szName); // Name to parse.
42
43static
44int 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//*****************************************************************************
57static
58WCHAR *FindSep( // Pointer to separator or null.
59 const WCHAR *szPath); // The path to look in.
60
61static
62LPUTF8 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//*****************************************************************************
72static
73WCHAR *SplitInline( // Pointer to name portion.
74 __inout __inout_z WCHAR *szPath); // The path to split.
75
76static
77LPUTF8 SplitInline( // Pointer to name portion.
78 __inout __inout_z LPUTF8 szPath); // The path to split.
79
80static
81void 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
86static
87void 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//*****************************************************************************
97static
98int 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
105static
106int 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//*****************************************************************************
118static
119int 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
125static
126int 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
132static
133int 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
139static
140int 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
145static
146int 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
151static
152int 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
157static
158void 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//*****************************************************************************
166static
167bool 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
172static
173bool 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
181static
182int 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
187static
188int 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
194static
195void 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