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 | // File: GuidHeap.h |
6 | // |
7 | |
8 | // |
9 | // Classes code:MetaData::GuidHeapRO and code:MetaData::GuidHeapRW represent #GUID heap. |
10 | // The #GUID heap stores size-prefixed data chunks (as defined in CLI ECMA specification). Elements are |
11 | // indexed by code:#GuidHeapIndex. |
12 | // |
13 | //#GuidHeapIndex |
14 | // Guid heap indexes are 1-based and they are really indexes, not offsets (as in string heap). |
15 | // The indexes correspond to: |
16 | // * 0 ... invalid index, |
17 | // * 1 ... data offset 0, |
18 | // * 2 ... data offset sizeof(GUID), |
19 | // * n ... data offset (n-1)*sizeof(GUID). |
20 | // Note that this class provides only translation from 1-based index to 0-based index. The translation of |
21 | // 0-based index to data offset is done in code:GuidHeapStorage::GetGuid. |
22 | // |
23 | // ====================================================================================== |
24 | |
25 | #pragma once |
26 | |
27 | #include "external.h" |
28 | |
29 | namespace MetaData |
30 | { |
31 | |
32 | // -------------------------------------------------------------------------------------- |
33 | // |
34 | // This class represents read-only #GUID heap with all utility methods. |
35 | // |
36 | class GuidHeapRO |
37 | { |
38 | friend class GuidHeapRW; |
39 | |
40 | private: |
41 | // |
42 | // Private data |
43 | // |
44 | |
45 | // The storage of guids. |
46 | StgPoolReadOnly m_GuidPool; |
47 | |
48 | public: |
49 | // |
50 | // Initialization |
51 | // |
52 | |
53 | __checkReturn |
54 | inline HRESULT Initialize( |
55 | DataBlob sourceData, |
56 | BOOL fCopyData) |
57 | { |
58 | _ASSERTE(!fCopyData); |
59 | return m_GuidPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize()); |
60 | } |
61 | |
62 | #ifdef FEATURE_PREJIT |
63 | // Can be called multiple times. |
64 | inline void InitializeHotData( |
65 | HotHeap hotHeap) |
66 | { |
67 | m_GuidPool.InitHotData(hotHeap); |
68 | } |
69 | #endif //FEATURE_PREJIT |
70 | |
71 | // Destroys the guid heap and all its allocated data. Can run on uninitialized guid heap. |
72 | inline void Delete() |
73 | { |
74 | return m_GuidPool.Uninit(); |
75 | } |
76 | |
77 | public: |
78 | // |
79 | // Getters |
80 | // |
81 | |
82 | // Gets pointer to guid (*ppGuid) at index (nIndex, see code:#GuidHeapIndex). |
83 | // Returns error code for invalid index (0, or too large index) and sets *ppGuid to NULL. |
84 | __checkReturn |
85 | inline HRESULT GetGuid( |
86 | UINT32 nIndex, |
87 | __deref_out GUID UNALIGNED **ppGuid) |
88 | { |
89 | return m_GuidPool.GetGuid(nIndex, ppGuid); |
90 | } |
91 | __checkReturn |
92 | inline HRESULT GetGuid( |
93 | UINT32 nIndex, |
94 | __deref_out const GUID UNALIGNED **ppGuid) const |
95 | { |
96 | return const_cast<StgPoolReadOnly &>(m_GuidPool).GetGuid(nIndex, const_cast<GUID UNALIGNED **>(ppGuid)); |
97 | } |
98 | |
99 | inline UINT32 GetSize() const |
100 | { |
101 | return const_cast<StgPoolReadOnly &>(m_GuidPool).GetPoolSize(); |
102 | } |
103 | |
104 | }; // class GuidHeapRO |
105 | |
106 | // -------------------------------------------------------------------------------------- |
107 | // |
108 | // This class represents read-write #GUID heap with all utility methods. |
109 | // |
110 | class GuidHeapRW |
111 | { |
112 | private: |
113 | // |
114 | // Private data |
115 | // |
116 | |
117 | // The storage of guids. |
118 | StgGuidPool m_GuidPool; |
119 | |
120 | public: |
121 | // |
122 | // Initialization |
123 | // |
124 | |
125 | __checkReturn |
126 | inline HRESULT InitializeEmpty( |
127 | UINT32 cbAllocationSize |
128 | COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite)) |
129 | { |
130 | return m_GuidPool.InitNew(cbAllocationSize, 0); |
131 | } |
132 | __checkReturn |
133 | inline HRESULT InitializeEmpty_WithItemsCount( |
134 | UINT32 cbAllocationSize, |
135 | UINT32 cItemsCount |
136 | COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite)) |
137 | { |
138 | return m_GuidPool.InitNew(cbAllocationSize, cItemsCount); |
139 | } |
140 | __checkReturn |
141 | inline HRESULT Initialize( |
142 | DataBlob sourceData, |
143 | BOOL fCopyData) |
144 | { |
145 | return m_GuidPool.InitOnMem((void *)sourceData.GetDataPointer(), sourceData.GetSize(), !fCopyData); |
146 | } |
147 | |
148 | __checkReturn |
149 | inline HRESULT InitializeFromGuidHeap( |
150 | const GuidHeapRO *pSourceGuidHeap, |
151 | BOOL fCopyData) |
152 | { |
153 | return m_GuidPool.InitOnMem( |
154 | (void *)pSourceGuidHeap->m_GuidPool.GetSegData(), |
155 | pSourceGuidHeap->m_GuidPool.GetDataSize(), |
156 | !fCopyData); |
157 | } |
158 | __checkReturn |
159 | inline HRESULT InitializeFromGuidHeap( |
160 | const GuidHeapRW *pSourceGuidHeap, |
161 | BOOL fCopyData) |
162 | { |
163 | return m_GuidPool.InitOnMem( |
164 | (void *)pSourceGuidHeap->m_GuidPool.GetSegData(), |
165 | pSourceGuidHeap->m_GuidPool.GetDataSize(), |
166 | !fCopyData); |
167 | } |
168 | |
169 | // Destroys the guid heap and all its allocated data. Can run on uninitialized guid heap. |
170 | inline void Delete() |
171 | { |
172 | return m_GuidPool.Uninit(); |
173 | } |
174 | |
175 | public: |
176 | // |
177 | // Getters |
178 | // |
179 | |
180 | __checkReturn |
181 | inline HRESULT GetGuid( |
182 | UINT32 nIndex, |
183 | __deref_out GUID UNALIGNED **ppGuid) |
184 | { |
185 | return m_GuidPool.GetGuid(nIndex, ppGuid); |
186 | } |
187 | __checkReturn |
188 | inline HRESULT GetGuid( |
189 | UINT32 nIndex, |
190 | __deref_out const GUID UNALIGNED **ppGuid) const |
191 | { |
192 | return const_cast<StgGuidPool &>(m_GuidPool).GetGuid(nIndex, const_cast<GUID UNALIGNED **>(ppGuid)); |
193 | } |
194 | |
195 | // Gets size (in bytes) of the represented guid data. Note: the size is everytime aligned. |
196 | inline UINT32 GetSize() const |
197 | { |
198 | _ASSERTE(m_GuidPool.GetRawSize() % sizeof(GUID) == 0); |
199 | return m_GuidPool.GetRawSize(); |
200 | } |
201 | |
202 | // Returns TRUE if the guid heap is empty. |
203 | inline BOOL IsEmpty() const |
204 | { |
205 | return const_cast<StgGuidPool &>(m_GuidPool).IsEmpty(); |
206 | } |
207 | |
208 | // Returns TRUE if the guid index (nIndex, see code:#GuidHeapIndex) is valid (i.e. is in the guid |
209 | // heap). |
210 | // Note: index 0 is considered invalid. |
211 | inline BOOL IsValidIndex(UINT32 nIndex) const |
212 | { |
213 | return const_cast<StgGuidPool &>(m_GuidPool).IsValidCookie(nIndex); |
214 | } |
215 | |
216 | __checkReturn |
217 | inline HRESULT SaveToStream( |
218 | __in IStream *pStream) const |
219 | { |
220 | return const_cast<StgGuidPool &>(m_GuidPool).PersistToStream(pStream); |
221 | } |
222 | |
223 | public: |
224 | // |
225 | // Heap modifications |
226 | // |
227 | |
228 | // Adds guid (*pGuid) to the end of the heap. |
229 | // Returns S_OK and index (*pnIndex, see code:#GuidHeapIndex) of added GUID. |
230 | // Returns error code otherwise (and fills *pnIndex with 0 - an invalid GUID index). |
231 | __checkReturn |
232 | inline HRESULT AddGuid( |
233 | __in const GUID *pGuid, |
234 | __out UINT32 *pnIndex) |
235 | { |
236 | return m_GuidPool.AddGuid(pGuid, pnIndex); |
237 | } |
238 | |
239 | // Adds data from *pSourceGuidHeap starting at index (nStartSourceIndex) to the guid heap. |
240 | // Returns S_OK (even if the source is empty) or error code. |
241 | __checkReturn |
242 | HRESULT AddGuidHeap( |
243 | const GuidHeapRW *pSourceGuidHeap, |
244 | UINT32 nStartSourceIndex) |
245 | { |
246 | return m_GuidPool.CopyPool( |
247 | nStartSourceIndex, |
248 | &pSourceGuidHeap->m_GuidPool); |
249 | } // GuidHeapRW::AddGuidHeap |
250 | |
251 | __checkReturn |
252 | inline HRESULT MakeWritable() |
253 | { |
254 | return m_GuidPool.ConvertToRW(); |
255 | } |
256 | |
257 | }; // class GuidHeapRW |
258 | |
259 | }; // namespace MetaData |
260 | |