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
29namespace MetaData
30{
31
32// --------------------------------------------------------------------------------------
33//
34// This class represents read-only #GUID heap with all utility methods.
35//
36class GuidHeapRO
37{
38 friend class GuidHeapRW;
39
40private:
41 //
42 // Private data
43 //
44
45 // The storage of guids.
46 StgPoolReadOnly m_GuidPool;
47
48public:
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
77public:
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//
110class GuidHeapRW
111{
112private:
113 //
114 // Private data
115 //
116
117 // The storage of guids.
118 StgGuidPool m_GuidPool;
119
120public:
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
175public:
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
223public:
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