summaryrefslogtreecommitdiff
path: root/src/md/heaps/guidheap.h
blob: 57f0147871cb770018616c1be583ee569d3f9947 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// 
// File: GuidHeap.h
// 

// 
// Classes code:MetaData::GuidHeapRO and code:MetaData::GuidHeapRW represent #GUID heap.
// The #GUID heap stores size-prefixed data chunks (as defined in CLI ECMA specification). Elements are 
// indexed by code:#GuidHeapIndex.
// 
//#GuidHeapIndex
// Guid heap indexes are 1-based and they are really indexes, not offsets (as in string heap).
// The indexes correspond to:
//  * 0 ... invalid index, 
//  * 1 ... data offset 0, 
//  * 2 ... data offset sizeof(GUID), 
//  * n ... data offset (n-1)*sizeof(GUID).
// Note that this class provides only translation from 1-based index to 0-based index. The translation of 
// 0-based index to data offset is done in code:GuidHeapStorage::GetGuid.
// 
// ======================================================================================

#pragma once

#include "external.h"

namespace MetaData
{

// --------------------------------------------------------------------------------------
// 
// This class represents read-only #GUID heap with all utility methods.
// 
class GuidHeapRO
{
    friend class GuidHeapRW;
    
private:
    // 
    // Private data
    // 
    
    // The storage of guids.
    StgPoolReadOnly m_GuidPool;
    
public:
    // 
    // Initialization
    // 
    
    __checkReturn 
    inline HRESULT Initialize(
        DataBlob sourceData, 
        BOOL     fCopyData)
    {
        _ASSERTE(!fCopyData);
        return m_GuidPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize());
    }
    
#ifdef FEATURE_PREJIT
    // Can be called multiple times.
    inline void InitializeHotData(
        HotHeap hotHeap)
    {
        m_GuidPool.InitHotData(hotHeap);
    }
#endif //FEATURE_PREJIT
    
    // Destroys the guid heap and all its allocated data. Can run on uninitialized guid heap.
    inline void Delete()
    {
        return m_GuidPool.Uninit();
    }
    
public:
    // 
    // Getters
    // 
    
    // Gets pointer to guid (*ppGuid) at index (nIndex, see code:#GuidHeapIndex).
    // Returns error code for invalid index (0, or too large index) and sets *ppGuid to NULL.
    __checkReturn 
    inline HRESULT GetGuid(
                    UINT32           nIndex, 
        __deref_out GUID UNALIGNED **ppGuid)
    {
        return m_GuidPool.GetGuid(nIndex, ppGuid);
    }
    __checkReturn 
    inline HRESULT GetGuid(
                    UINT32                 nIndex, 
        __deref_out const GUID UNALIGNED **ppGuid) const
    {
        return const_cast<StgPoolReadOnly &>(m_GuidPool).GetGuid(nIndex, const_cast<GUID UNALIGNED **>(ppGuid));
    }
    
    inline UINT32 GetSize() const
    {
        return const_cast<StgPoolReadOnly &>(m_GuidPool).GetPoolSize();
    }
    
};  // class GuidHeapRO

// --------------------------------------------------------------------------------------
// 
// This class represents read-write #GUID heap with all utility methods.
// 
class GuidHeapRW
{
private:
    // 
    // Private data
    // 
    
    // The storage of guids.
    StgGuidPool m_GuidPool;
    
public:
    // 
    // Initialization
    // 
    
    __checkReturn 
    inline HRESULT InitializeEmpty(
                         UINT32 cbAllocationSize 
        COMMA_INDEBUG_MD(BOOL   debug_fIsReadWrite))
    {
        return m_GuidPool.InitNew(cbAllocationSize, 0);
    }
    __checkReturn 
    inline HRESULT InitializeEmpty_WithItemsCount(
                         UINT32 cbAllocationSize, 
                         UINT32 cItemsCount 
        COMMA_INDEBUG_MD(BOOL   debug_fIsReadWrite))
    {
        return m_GuidPool.InitNew(cbAllocationSize, cItemsCount);
    }
    __checkReturn 
    inline HRESULT Initialize(
        DataBlob sourceData, 
        BOOL     fCopyData)
    {
        return m_GuidPool.InitOnMem((void *)sourceData.GetDataPointer(), sourceData.GetSize(), !fCopyData);
    }
    
    __checkReturn 
    inline HRESULT InitializeFromGuidHeap(
        const GuidHeapRO *pSourceGuidHeap, 
        BOOL              fCopyData)
    {
        return m_GuidPool.InitOnMem(
            (void *)pSourceGuidHeap->m_GuidPool.GetSegData(), 
            pSourceGuidHeap->m_GuidPool.GetDataSize(), 
            !fCopyData);
    }
    __checkReturn 
    inline HRESULT InitializeFromGuidHeap(
        const GuidHeapRW *pSourceGuidHeap, 
        BOOL              fCopyData)
    {
        return m_GuidPool.InitOnMem(
            (void *)pSourceGuidHeap->m_GuidPool.GetSegData(), 
            pSourceGuidHeap->m_GuidPool.GetDataSize(), 
            !fCopyData);
    }
    
    // Destroys the guid heap and all its allocated data. Can run on uninitialized guid heap.
    inline void Delete()
    {
        return m_GuidPool.Uninit();
    }
    
public:
    // 
    // Getters
    // 
    
    __checkReturn 
    inline HRESULT GetGuid(
                    UINT32           nIndex, 
        __deref_out GUID UNALIGNED **ppGuid)
    {
        return m_GuidPool.GetGuid(nIndex, ppGuid);
    }
    __checkReturn 
    inline HRESULT GetGuid(
                    UINT32                 nIndex, 
        __deref_out const GUID UNALIGNED **ppGuid) const
    {
        return const_cast<StgGuidPool &>(m_GuidPool).GetGuid(nIndex, const_cast<GUID UNALIGNED **>(ppGuid));
    }
    
    // Gets size (in bytes) of the represented guid data. Note: the size is everytime aligned.
    inline UINT32 GetSize() const
    {
        _ASSERTE(m_GuidPool.GetRawSize() % sizeof(GUID) == 0);
        return m_GuidPool.GetRawSize();
    }
    
    // Returns TRUE if the guid heap is empty.
    inline BOOL IsEmpty() const
    {
        return const_cast<StgGuidPool &>(m_GuidPool).IsEmpty();
    }
    
    // Returns TRUE if the guid index (nIndex, see code:#GuidHeapIndex) is valid (i.e. is in the guid 
    // heap).
    // Note: index 0 is considered invalid.
    inline BOOL IsValidIndex(UINT32 nIndex) const
    {
        return const_cast<StgGuidPool &>(m_GuidPool).IsValidCookie(nIndex);
    }
    
    __checkReturn 
    inline HRESULT SaveToStream(
        __in IStream *pStream) const
    {
        return const_cast<StgGuidPool &>(m_GuidPool).PersistToStream(pStream);
    }
    
public:
    // 
    // Heap modifications
    // 
    
    // Adds guid (*pGuid) to the end of the heap.
    // Returns S_OK and index (*pnIndex, see code:#GuidHeapIndex) of added GUID.
    // Returns error code otherwise (and fills *pnIndex with 0 - an invalid GUID index).
    __checkReturn 
    inline HRESULT AddGuid(
        __in  const GUID *pGuid, 
        __out UINT32     *pnIndex)
    {
        return m_GuidPool.AddGuid(pGuid, pnIndex);
    }
    
    // Adds data from *pSourceGuidHeap starting at index (nStartSourceIndex) to the guid heap.
    // Returns S_OK (even if the source is empty) or error code.
    __checkReturn 
    HRESULT AddGuidHeap(
        const GuidHeapRW *pSourceGuidHeap, 
        UINT32            nStartSourceIndex)
    {
        return m_GuidPool.CopyPool(
            nStartSourceIndex, 
            &pSourceGuidHeap->m_GuidPool);
    } // GuidHeapRW::AddGuidHeap
    
    __checkReturn 
    inline HRESULT MakeWritable()
    {
        return m_GuidPool.ConvertToRW();
    }
    
};  // class GuidHeapRW

};  // namespace MetaData