summaryrefslogtreecommitdiff
path: root/src/md/heaps
diff options
context:
space:
mode:
Diffstat (limited to 'src/md/heaps')
-rw-r--r--src/md/heaps/.gitmirror1
-rw-r--r--src/md/heaps/blobheap.h324
-rw-r--r--src/md/heaps/export.h18
-rw-r--r--src/md/heaps/external.h22
-rw-r--r--src/md/heaps/guidheap.h259
-rw-r--r--src/md/heaps/stringheap.h307
6 files changed, 931 insertions, 0 deletions
diff --git a/src/md/heaps/.gitmirror b/src/md/heaps/.gitmirror
new file mode 100644
index 0000000000..f507630f94
--- /dev/null
+++ b/src/md/heaps/.gitmirror
@@ -0,0 +1 @@
+Only contents of this folder, excluding subfolders, will be mirrored by the Git-TFS Mirror. \ No newline at end of file
diff --git a/src/md/heaps/blobheap.h b/src/md/heaps/blobheap.h
new file mode 100644
index 0000000000..8765537bd8
--- /dev/null
+++ b/src/md/heaps/blobheap.h
@@ -0,0 +1,324 @@
+// 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: BlobHeap.h
+//
+
+//
+// Classes code:MetaData::BlobHeapRO and code:MetaData::BlobHeapRW represent #Blob heap.
+// The #Blob heap stores size-prefixed data chunks (as defined in CLI ECMA specification). Elements are
+// indexed by code:#BlobHeapIndex.
+//
+//#BlobHeapIndex
+// Blob heap indexes are 0-based. They are stored the same way in the table columns (i.e. there is no
+// 0-based vs. 1-based index difference as in table record indexes code:TableRecordStorage).
+//
+// ======================================================================================
+
+#pragma once
+
+#include "external.h"
+
+namespace MetaData
+{
+
+// --------------------------------------------------------------------------------------
+//
+// This class represents read-only #Blob heap with all utility methods.
+//
+class BlobHeapRO
+{
+ friend class BlobHeapRW;
+
+private:
+ //
+ // Private data
+ //
+
+ // The storage of blobs.
+ StgBlobPoolReadOnly m_BlobPool;
+
+public:
+ //
+ // Initialization
+ //
+
+ __checkReturn
+ HRESULT Initialize(
+ DataBlob sourceData,
+ BOOL fCopyData)
+ {
+ _ASSERTE(!fCopyData);
+ return m_BlobPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize());
+ }
+
+#ifdef FEATURE_PREJIT
+ // Can be called multiple times.
+ inline void InitializeHotData(
+ HotHeap hotHeap)
+ {
+ m_BlobPool.InitHotData(hotHeap);
+ }
+#endif //FEATURE_PREJIT
+
+ inline void Delete()
+ {
+ return m_BlobPool.Uninit();
+ }
+
+public:
+ //
+ // Getters
+ //
+
+ __checkReturn
+ inline HRESULT GetBlob(
+ UINT32 nIndex,
+ __out DataBlob *pData)
+ {
+ return m_BlobPool.GetBlob(nIndex, pData);
+ }
+
+ __checkReturn
+ inline HRESULT GetAllData(
+ __inout DataBlob *pData)
+ {
+ return m_BlobPool.GetDataReadOnly(0, pData);
+ }
+
+ // Gets raw size (in bytes) of the represented blob data.
+ inline UINT32 GetUnalignedSize() const
+ {
+ return m_BlobPool.GetPoolSize();
+ }
+
+ // Returns TRUE if the blob index (nIndex, see code:#BlobHeapIndex) is valid (i.e. in the blob
+ // heap).
+ inline BOOL IsValidIndex(UINT32 nIndex) const
+ {
+ return const_cast<StgBlobPoolReadOnly &>(m_BlobPool).IsValidCookie(nIndex);
+ }
+
+}; // class BlobHeapRO
+
+// --------------------------------------------------------------------------------------
+//
+// This class represents read-write #Blob heap with all utility methods.
+//
+class BlobHeapRW
+{
+private:
+ //
+ // Private data
+ //
+
+ // The storage of blobs.
+ StgBlobPool m_BlobPool;
+
+public:
+ //
+ // Initialization
+ //
+
+ __checkReturn
+ HRESULT InitializeEmpty(
+ UINT32 cbAllocationSize
+ COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite))
+ {
+ return m_BlobPool.InitNew(cbAllocationSize, 0, TRUE);
+ }
+ __checkReturn
+ HRESULT InitializeEmpty_WithItemsCount(
+ UINT32 cbAllocationSize,
+ UINT32 cItemsCount
+ COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite))
+ {
+ return m_BlobPool.InitNew(cbAllocationSize, cItemsCount, TRUE);
+ }
+ __checkReturn
+ HRESULT InitializeEmpty_WithoutDefaultEmptyBlob(
+ UINT32 cbAllocationSize
+ COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite))
+ {
+ return m_BlobPool.InitNew(cbAllocationSize, 0, FALSE);
+ }
+
+ __checkReturn
+ HRESULT Initialize(
+ DataBlob sourceData,
+ BOOL fCopyData)
+ {
+ return m_BlobPool.InitOnMem((void *)sourceData.GetDataPointer(), sourceData.GetSize(), !fCopyData);
+ }
+ __checkReturn
+ HRESULT InitializeFromBlobHeap(
+ const BlobHeapRO *pSourceBlobHeap,
+ BOOL fCopyData)
+ {
+ return m_BlobPool.InitOnMem(
+ (void *)pSourceBlobHeap->m_BlobPool.GetSegData(),
+ pSourceBlobHeap->m_BlobPool.GetDataSize(),
+ !fCopyData);
+ }
+ __checkReturn
+ HRESULT InitializeFromBlobHeap(
+ const BlobHeapRW *pSourceBlobHeap,
+ BOOL fCopyData)
+ {
+ return m_BlobPool.InitOnMem(
+ (void *)pSourceBlobHeap->m_BlobPool.GetSegData(),
+ pSourceBlobHeap->m_BlobPool.GetDataSize(),
+ !fCopyData);
+ }
+
+ // Destroys the blob heap and all its allocated data. Can run on uninitialized blob heap.
+ inline void Delete()
+ {
+ return m_BlobPool.Uninit();
+ }
+
+public:
+ //
+ // Getters
+ //
+
+ __checkReturn
+ inline HRESULT GetBlob(
+ UINT32 nIndex,
+ __out DataBlob *pData)
+ {
+ return m_BlobPool.GetBlob(nIndex, pData);
+ }
+
+ // Gets the blob with its size-prefix at index (nIndex, see code:#BlobHeapIndex), or returns error.
+ //
+ // Returns S_OK and the data (*pData) at index (nIndex). The end of the data marks the end of the blob.
+ // Returns error code otherwise (and clears *pData).
+ //
+ // User of this API shouldn't access memory behind the data buffer (*pData).
+ __checkReturn
+ inline HRESULT GetBlobWithSizePrefix(
+ UINT32 nIndex,
+ __out DataBlob *pData)
+ {
+ return m_BlobPool.GetBlobWithSizePrefix(nIndex, pData);
+ }
+
+ // Gets raw size (in bytes) of the represented blob data. Doesn't align the size as code:GetAlignedSize.
+ inline UINT32 GetUnalignedSize() const
+ {
+ return m_BlobPool.GetRawSize();
+ }
+ // Gets size (in bytes) aligned up to 4-bytes of the represented blob data.
+ // Fills *pcbSize with 0 on error.
+ __checkReturn
+ inline HRESULT GetAlignedSize(
+ __out UINT32 *pcbSize) const
+ {
+ return m_BlobPool.GetSaveSize(pcbSize);
+ }
+ // Returns TRUE if the blob heap is empty (even if it contains only default empty blob).
+ inline BOOL IsEmpty() const
+ {
+ return const_cast<StgBlobPool &>(m_BlobPool).IsEmpty();
+ }
+
+ // Returns TRUE if the blob index (nIndex, see code:#BlobHeapIndex) is valid (i.e. in the blob
+ // heap).
+ inline BOOL IsValidIndex(UINT32 nIndex) const
+ {
+ return const_cast<StgBlobPool &>(m_BlobPool).IsValidCookie(nIndex);
+ }
+
+ __checkReturn
+ HRESULT SaveToStream_Aligned(
+ UINT32 nStartIndex,
+ __in IStream *pStream) const
+ {
+ if (nStartIndex == 0)
+ {
+ return const_cast<StgBlobPool &>(m_BlobPool).PersistToStream(pStream);
+ }
+
+ if (nStartIndex == m_BlobPool.GetRawSize())
+ {
+ _ASSERTE(!m_BlobPool.HaveEdits());
+ return S_OK;
+ }
+ _ASSERTE(m_BlobPool.HaveEdits());
+ _ASSERTE(nStartIndex == m_BlobPool.GetOffsetOfEdit());
+ return const_cast<StgBlobPool &>(m_BlobPool).PersistPartialToStream(pStream, nStartIndex);
+ }
+
+public:
+ //
+ // Heap modifications
+ //
+
+ __checkReturn
+ inline HRESULT AddBlob(
+ DataBlob data,
+ __out UINT32 *pnIndex)
+ {
+ return m_BlobPool.AddBlob(&data, pnIndex);
+ }
+
+ __checkReturn
+ HRESULT AddBlobHeap(
+ const BlobHeapRW *pSourceBlobHeap,
+ UINT32 nStartSourceIndex)
+ {
+ return m_BlobPool.CopyPool(
+ nStartSourceIndex,
+ &pSourceBlobHeap->m_BlobPool);
+ } // BlobHeapRW::AddBlobHeap
+
+ __checkReturn
+ inline HRESULT MakeWritable()
+ {
+ return m_BlobPool.ConvertToRW();
+ }
+
+public:
+ //
+ // Tracking of heap modifications for EnC
+ //
+
+ //#EnCSessionTracking
+ // EnC session starts automatically with initialization (code:Initialize or code:InitializeEmpty) or by
+ // user's explicit call to code:StartNewEnCSession. The heap stores its actual data size, so we can find
+ // out if some data were added later.
+
+ // Gets heap size (in bytes) from the beginning of the last EnC session (code:#EnCSessionTracking).
+ inline UINT32 GetEnCSessionStartHeapSize() const
+ {
+ if (m_BlobPool.HaveEdits())
+ {
+ return m_BlobPool.GetOffsetOfEdit();
+ }
+
+ return m_BlobPool.GetRawSize();
+ }
+ // Starts new EnC session (code:#EnCSessionTracking).
+ inline void StartNewEnCSession()
+ {
+ m_BlobPool.ResetOffsetOfEdit();
+ }
+ // Gets size (in bytes) aligned to 4-bytes of adds made from the beginning of the last EnC session.
+ __checkReturn
+ inline HRESULT GetEnCSessionAddedHeapSize_Aligned(
+ __out UINT32 *pcbSize) const
+ {
+ if (m_BlobPool.HaveEdits())
+ {
+ return m_BlobPool.GetEditSaveSize(pcbSize);
+ }
+
+ *pcbSize = 0;
+ return S_OK;
+ }
+
+}; // class BlobHeapRW
+
+}; // namespace MetaData
diff --git a/src/md/heaps/export.h b/src/md/heaps/export.h
new file mode 100644
index 0000000000..b14023706d
--- /dev/null
+++ b/src/md/heaps/export.h
@@ -0,0 +1,18 @@
+// 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: export.h
+//
+
+//
+// Popular types defined in MetaData\Heaps directory.
+// It's supposed to be included from other (MetaData) subcomponents, not from this directory.
+//
+// ======================================================================================
+
+#pragma once
+
+#include "stringheap.h"
+#include "blobheap.h"
+#include "guidheap.h"
diff --git a/src/md/heaps/external.h b/src/md/heaps/external.h
new file mode 100644
index 0000000000..9b5362c761
--- /dev/null
+++ b/src/md/heaps/external.h
@@ -0,0 +1,22 @@
+// 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: external.h
+//
+
+//
+// External types used in MetaData\Heaps subcomponent classes.
+// This file is used for precompiled headers, so it has to be included at the beginning of every .cpp in
+// this directory.
+//
+// ======================================================================================
+
+#pragma once
+
+#include "../external.h"
+#include "../export.h"
+
+#include <stgpool.h>
+#include <metamodelpub.h>
+#include <utilcode.h>
diff --git a/src/md/heaps/guidheap.h b/src/md/heaps/guidheap.h
new file mode 100644
index 0000000000..57f0147871
--- /dev/null
+++ b/src/md/heaps/guidheap.h
@@ -0,0 +1,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
diff --git a/src/md/heaps/stringheap.h b/src/md/heaps/stringheap.h
new file mode 100644
index 0000000000..b5353a12fd
--- /dev/null
+++ b/src/md/heaps/stringheap.h
@@ -0,0 +1,307 @@
+// 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: StringHeap.h
+//
+
+//
+// Classes code:MetaData::StringHeapRO and code:MetaData::StringHeapRW represent #String heap.
+// The #String heap stores null-terminated UTF-8 strings (as defined in CLI ECMA specification). Elements
+// are indexed by code:#StringHeapIndex.
+//
+//#StringHeapIndex
+// String heap indexes are 0-based. They are stored the same way in the table columns (i.e. there is no
+// 0-based vs. 1-based index difference as in table record indexes code:TableRecordStorage).
+//
+// ======================================================================================
+
+#pragma once
+
+#include "external.h"
+
+namespace MetaData
+{
+
+// --------------------------------------------------------------------------------------
+//
+// This class represents read-only #String heap with all utility methods.
+//
+class StringHeapRO
+{
+ friend class StringHeapRW;
+
+private:
+ //
+ // Private data
+ //
+
+ // The storage of strings.
+ StgPoolReadOnly m_StringPool;
+
+public:
+ //
+ // Initialization
+ //
+
+ __checkReturn
+ inline HRESULT Initialize(
+ DataBlob sourceData,
+ BOOL fCopyData)
+ {
+ _ASSERTE(!fCopyData);
+ return m_StringPool.InitOnMemReadOnly((void *)sourceData.GetDataPointer(), sourceData.GetSize());
+ }
+
+#ifdef FEATURE_PREJIT
+ // Can be called multiple times.
+ inline void InitializeHotData(
+ HotHeap hotHeap)
+ {
+ m_StringPool.InitHotData(hotHeap);
+ }
+#endif //FEATURE_PREJIT
+
+ inline void Delete()
+ {
+ return m_StringPool.Uninit();
+ }
+
+public:
+ //
+ // Getters
+ //
+
+ __checkReturn
+ inline HRESULT GetString(
+ UINT32 nIndex,
+ __deref_out_z LPCSTR *pszString) const
+ {
+ return const_cast<StgPoolReadOnly &>(m_StringPool).GetString(
+ nIndex,
+ pszString);
+ }
+
+ // Gets raw size (in bytes) of the represented strings.
+ inline UINT32 GetUnalignedSize() const
+ {
+ return m_StringPool.GetPoolSize();
+ }
+
+}; // class StringHeapRO
+
+// --------------------------------------------------------------------------------------
+//
+// This class represents read-write #String heap with all utility methods.
+//
+class StringHeapRW
+{
+private:
+ //
+ // Private data
+ //
+
+ // The storage of strings.
+ StgStringPool m_StringPool;
+
+public:
+ //
+ // Initialization
+ //
+
+ __checkReturn
+ inline HRESULT InitializeEmpty(
+ UINT32 cbAllocationSize
+ COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite))
+ {
+ return m_StringPool.InitNew(cbAllocationSize, 0);
+ }
+ __checkReturn
+ inline HRESULT InitializeEmpty_WithItemsCount(
+ UINT32 cbAllocationSize,
+ UINT32 cItemsCount
+ COMMA_INDEBUG_MD(BOOL debug_fIsReadWrite))
+ {
+ return m_StringPool.InitNew(cbAllocationSize, cItemsCount);
+ }
+ __checkReturn
+ inline HRESULT Initialize(
+ DataBlob sourceData,
+ BOOL fCopyData)
+ {
+ return m_StringPool.InitOnMem((void *)sourceData.GetDataPointer(), sourceData.GetSize(), !fCopyData);
+ }
+ __checkReturn
+ inline HRESULT InitializeFromStringHeap(
+ const StringHeapRO *pSourceStringHeap,
+ BOOL fCopyData)
+ {
+ return m_StringPool.InitOnMem(
+ (void *)pSourceStringHeap->m_StringPool.GetSegData(),
+ pSourceStringHeap->m_StringPool.GetDataSize(),
+ !fCopyData);
+ }
+ __checkReturn
+ inline HRESULT InitializeFromStringHeap(
+ const StringHeapRW *pSourceStringHeap,
+ BOOL fCopyData)
+ {
+ return m_StringPool.InitOnMem(
+ (void *)pSourceStringHeap->m_StringPool.GetSegData(),
+ pSourceStringHeap->m_StringPool.GetDataSize(),
+ !fCopyData);
+ }
+
+ // Destroys the string heap and all its allocated data. Can run on uninitialized string heap.
+ inline void Delete()
+ {
+ return m_StringPool.Uninit();
+ }
+
+public:
+ //
+ // Getters
+ //
+
+ __checkReturn
+ inline HRESULT GetString(
+ UINT32 nIndex,
+ __deref_out_z LPCSTR *pszString) const
+ {
+ return const_cast<StgStringPool &>(m_StringPool).GetString(
+ nIndex,
+ pszString);
+ }
+
+ // Gets raw size (in bytes) of the represented strings. Doesn't align the size as code:GetAlignedSize.
+ inline UINT32 GetUnalignedSize() const
+ {
+ return m_StringPool.GetRawSize();
+ }
+ // Gets size (in bytes) aligned up to 4-bytes of the represented strings.
+ // Fills *pcbSize with 0 on error.
+ __checkReturn
+ inline HRESULT GetAlignedSize(
+ __out UINT32 *pcbSize) const
+ {
+ return m_StringPool.GetSaveSize(pcbSize);
+ }
+ // Returns TRUE if the string heap is empty (even if it contains only default empty string).
+ inline BOOL IsEmpty() const
+ {
+ return const_cast<StgStringPool &>(m_StringPool).IsEmpty();
+ }
+
+ // Returns TRUE if the string index (nIndex, see code:#StringHeapIndex) is valid (i.e. in the string
+ // heap).
+ inline BOOL IsValidIndex(UINT32 nIndex) const
+ {
+ return const_cast<StgStringPool &>(m_StringPool).IsValidCookie(nIndex);
+ }
+
+ __checkReturn
+ inline HRESULT SaveToStream_Aligned(
+ UINT32 nStartIndex,
+ __in IStream *pStream) const
+ {
+ if (nStartIndex == 0)
+ {
+ return const_cast<StgStringPool &>(m_StringPool).PersistToStream(pStream);
+ }
+
+ if (nStartIndex == m_StringPool.GetRawSize())
+ {
+ _ASSERTE(!m_StringPool.HaveEdits());
+ return S_OK;
+ }
+ _ASSERTE(m_StringPool.HaveEdits());
+ _ASSERTE(nStartIndex == m_StringPool.GetOffsetOfEdit());
+ return const_cast<StgStringPool &>(m_StringPool).PersistPartialToStream(pStream, nStartIndex);
+ }
+
+public:
+ //
+ // Heap modifications
+ //
+
+ // Adds null-terminated UTF-8 string (szString) to the end of the heap (incl. its null-terminator).
+ // Returns S_OK and index of added string (*pnIndex).
+ // Returns error code otherwise (and fills *pnIndex with 0).
+ __checkReturn
+ inline HRESULT AddString(
+ __in_z LPCSTR szString,
+ __out UINT32 *pnIndex)
+ {
+ return m_StringPool.AddString(szString, pnIndex);
+ }
+ // Adds null-terminated UTF-16 string (wszString) to the end of the heap (incl. its null-terminator).
+ // Returns S_OK and index of added string (*pnIndex).
+ // Returns error code otherwise (and fills *pnIndex with 0).
+ __checkReturn
+ inline HRESULT AddStringW(
+ __in_z LPCWSTR wszString,
+ __out UINT32 *pnIndex)
+ {
+ return m_StringPool.AddStringW(wszString, pnIndex);
+ }
+
+ // Adds data from *pSourceStringHeap starting at index (nStartSourceIndex) to the string heap.
+ // Returns S_OK (even if the source is empty) or error code.
+ __checkReturn
+ inline HRESULT AddStringHeap(
+ const StringHeapRW *pSourceStringHeap,
+ UINT32 nStartSourceIndex)
+ {
+ return m_StringPool.CopyPool(
+ nStartSourceIndex,
+ &pSourceStringHeap->m_StringPool);
+ } // StringHeapRW::AddStringHeap
+
+ __checkReturn
+ inline HRESULT MakeWritable()
+ {
+ return m_StringPool.ConvertToRW();
+ }
+
+public:
+ //
+ // Tracking of heap modifications for EnC
+ //
+
+ //#EnCSessionTracking
+ // EnC session starts automatically with initialization (code:Initialize or code:InitializeEmpty) or by
+ // user's explicit call to code:StartNewEnCSession. The heap stores its actual data size, so we can find
+ // out if some data were added later.
+
+ // Gets heap size (in bytes) from the beginning of the last EnC session (code:#EnCSessionTracking).
+ inline UINT32 GetEnCSessionStartHeapSize() const
+ {
+ if (m_StringPool.HaveEdits())
+ {
+ return m_StringPool.GetOffsetOfEdit();
+ }
+
+ return m_StringPool.GetRawSize();
+ }
+ // Starts new EnC session (code:#EnCSessionTracking).
+ inline void StartNewEnCSession()
+ {
+ m_StringPool.ResetOffsetOfEdit();
+ }
+ // Gets size (in bytes) aligned to 4-bytes of adds made from the beginning of the last EnC session.
+ __checkReturn
+ inline HRESULT GetEnCSessionAddedHeapSize_Aligned(
+ __out UINT32 *pcbSize) const
+ {
+ if (m_StringPool.HaveEdits())
+ {
+ return m_StringPool.GetEditSaveSize(pcbSize);
+ }
+
+ *pcbSize = 0;
+ return S_OK;
+ }
+
+}; // class StringHeapRW
+
+}; // namespace MetaData