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/* a type parameter list */
6
7#ifndef TYPAR_H
8#define TYPAR_H
9#include "binstr.h"
10
11extern unsigned int g_uCodePage;
12
13class TyParDescr
14{
15public:
16 TyParDescr()
17 {
18 m_pbsBounds = NULL;
19 m_wzName = NULL;
20 m_dwAttrs = 0;
21 };
22 ~TyParDescr()
23 {
24 delete m_pbsBounds;
25 delete [] m_wzName;
26 m_lstCA.RESET(true);
27 };
28 void Init(BinStr* bounds, LPCUTF8 name, DWORD attrs)
29 {
30 m_pbsBounds = bounds;
31 ULONG cTemp = (ULONG)strlen(name)+1;
32 WCHAR *pwzName;
33 m_wzName = pwzName = new WCHAR[cTemp];
34 if(pwzName)
35 {
36 memset(pwzName,0,sizeof(WCHAR)*cTemp);
37 WszMultiByteToWideChar(g_uCodePage,0,name,-1,pwzName,cTemp);
38 }
39 m_dwAttrs = attrs;
40 };
41 BinStr* Bounds() { return m_pbsBounds; };
42 LPCWSTR Name() { return m_wzName; };
43 DWORD Attrs() { return m_dwAttrs; };
44 CustomDescrList* CAList() { return &m_lstCA; };
45private:
46 BinStr* m_pbsBounds;
47 LPCWSTR m_wzName;
48 DWORD m_dwAttrs;
49 CustomDescrList m_lstCA;
50};
51
52class TyParList {
53public:
54 TyParList(DWORD a, BinStr* b, LPCUTF8 n, TyParList* nx = NULL)
55 {
56 bound = (b == NULL) ? new BinStr() : b;
57 bound->appendInt32(0); // zero terminator
58 attrs = a; name = n; next = nx;
59 };
60 ~TyParList()
61 {
62 if( bound) delete bound;
63
64 // To avoid excessive stack usage (especially in debug builds), we break the next chain
65 // and delete as we traverse the link list
66 TyParList *pCur = next;
67 while (pCur != NULL)
68 {
69 TyParList *pTmp = pCur->next;
70 pCur->next = NULL;
71 delete pCur;
72 pCur = pTmp;
73 }
74 };
75 int Count()
76 {
77 TyParList* tp = this;
78 int n;
79 for(n = 1; (tp = tp->next) != NULL; n++);
80 return n;
81 };
82 int IndexOf(LPCUTF8 name)
83 {
84 TyParList* tp = this;
85 int n;
86 int ret = -1;
87 for(n=0; tp != NULL; n++, tp = tp->next)
88 {
89 if(tp->name == NULL)
90 {
91 if(name == NULL) ret = n;
92 }
93 else
94 {
95 if(name == NULL) continue;
96 if(0 == strcmp(name,tp->name)) ret = n;
97 }
98 }
99 return ret;
100 };
101
102#ifdef _PREFAST_
103#pragma warning(push)
104#pragma warning(disable:6211) // "Leaking memory 'b' due to an exception. Consider using a local catch block to clean up memory"
105#endif /*_PREFAST_ */
106
107 int ToArray(BinStr ***bounds, LPCWSTR** names, DWORD **attrs)
108 {
109 int n = Count();
110 BinStr **b = new BinStr* [n];
111 LPCWSTR *nam = new LPCWSTR [n];
112 DWORD *attr = attrs ? new DWORD [n] : NULL;
113 TyParList *tp = this;
114 int i = 0;
115 while (tp)
116 {
117 ULONG cTemp = (ULONG)strlen(tp->name)+1;
118 WCHAR* wzDllName = new WCHAR [cTemp];
119 // Convert name to UNICODE
120 memset(wzDllName,0,sizeof(WCHAR)*cTemp);
121 WszMultiByteToWideChar(g_uCodePage,0,tp->name,-1,wzDllName,cTemp);
122 nam[i] = (LPCWSTR)wzDllName;
123 b[i] = tp->bound;
124 if (attr)
125 attr[i] = tp->attrs;
126 tp->bound = 0; // to avoid deletion by destructor
127 i++;
128 tp = tp->next;
129 }
130 *bounds = b;
131 *names = nam;
132 if (attrs)
133 *attrs = attr;
134 return n;
135 };
136
137#ifdef _PREFAST_
138#pragma warning(pop)
139#endif /*_PREFAST_*/
140
141 int ToArray(TyParDescr **ppTPD)
142 {
143 int n = Count();
144 TyParDescr *pTPD = NULL;
145 if(n)
146 {
147 pTPD = new TyParDescr[n];
148 if(pTPD)
149 {
150 int i = 0;
151 TyParList *tp = this;
152 while (tp)
153 {
154 pTPD[i].Init(tp->bound,tp->name,tp->attrs);
155 tp->bound = 0; // to avoid deletion by destructor
156 i++;
157 tp = tp->next;
158 }
159 }
160 }
161 *ppTPD = pTPD;
162 return n;
163 };
164 TyParList* Next() { return next; };
165 BinStr* Bound() { return bound; };
166private:
167 BinStr* bound;
168 LPCUTF8 name;
169 TyParList* next;
170 DWORD attrs;
171};
172
173typedef TyParList* pTyParList;
174
175#endif
176
177