|
|
#if !defined(_FUSION_INC_STRINGPOOL_H_INCLUDED_)
#define _FUSION_INC_STRINGPOOL_H_INCLUDED_
#pragma once
#include <windows.h>
#include "debmacro.h"
#include "fusiondeque.h"
#include "fusionbuffer.h"
#include "util.h"
#include "sxsapi.h"
//
// Design notes:
//
// This string pool class is intended to manage an un-reference-counted
// pool of strings. Adding something to the pool leaves it there until
// the pool is destroyed; this makes it useful for things like syntax
// trees where many of the elements will have duplicate strings, but
// you would never want to actually keep one of these around for the
// lifetime of the process or DLL.
//
class CStringPool; class CStringPoolEntry; class CStringPoolEntryClump; class CStringPoolHeap; class CStringPoolHeapSegment;
class CStringPoolHeapSegment { public: CStringPoolHeapSegment() : m_cchUsed(0) { } ~CStringPoolHeapSegment() { }
BOOL Initialize(); BOOL Initialize(const WCHAR *StringIn, ULONG Cch, const WCHAR *&rpStringOut); BOOL TryAllocString(const WCHAR *StringIn, ULONG Cch, const WCHAR *&rpStringOut);
inline static ULONG CchMax() { return 4096; }
CDequeLinkage m_leLinks; WCHAR m_rgchBuffer[4096]; ULONG m_cchUsed; };
class CStringPoolSingletonString { public: CStringPoolSingletonString() : m_prgwch(NULL) { } ~CStringPoolSingletonString() { if (m_prgwch != NULL) { FUSION_DELETE_ARRAY(m_prgwch); m_prgwch = NULL; } }
BOOL Initialize(const WCHAR *StringIn, ULONG Cch, const WCHAR *&rpStringOut);
WCHAR *m_prgwch; CDequeLinkage m_leLinks; };
class CStringPoolHeap { public: CStringPoolHeap() { } ~CStringPoolHeap() { CSxsPreserveLastError ple; m_dequeSegments.Clear<CStringPoolHeap>(this, CStringPoolHeap::ClearSegment); m_dequeSingletons.Clear<CStringPoolHeap>(this, CStringPoolHeap::ClearSingleton); ple.Restore(); }
BOOL Initialize(); BOOL DupString(const WCHAR *StringIn, ULONG Cch, const WCHAR *&rpStringOut);
VOID ClearSegment(CStringPoolHeapSegment *p) const { FUSION_DELETE_SINGLETON(p); } VOID ClearSingleton(CStringPoolSingletonString *p) const { FUSION_DELETE_SINGLETON(p); }
CDeque<CStringPoolHeapSegment, FIELD_OFFSET(CStringPoolHeapSegment, m_leLinks)> m_dequeSegments; CDeque<CStringPoolSingletonString, FIELD_OFFSET(CStringPoolSingletonString, m_leLinks)> m_dequeSingletons;
private: CStringPoolHeap(const CStringPoolHeap &r); // intentionally not implemented
void operator =(const CStringPoolHeap &r); // intentionally not implemented
};
class CStringPoolEntry : public _SXS_XML_STRING { friend CStringPoolEntryClump;
public: CStringPoolEntry() { // Initialize members in base type...
this->Flags = 0; this->PseudoKey = 0; this->Length = 0; this->Buffer = NULL; } ~CStringPoolEntry() { }
BOOL Initialize(const WCHAR *StringIn, ULONG CchIn, ULONG ulPsuedoKey, CStringPoolHeap &rStringPoolHeap); };
class CStringPoolEntryClump { friend CStringPool;
public: CStringPoolEntryClump() : m_prgEntries(NULL), m_cEntriesAllocated(0), m_cEntriesUsed(0) { } ~CStringPoolEntryClump();
BOOL Initialize(ULONG cEntriesToAllocate = 32);
enum FindOrAddDisposition { eInvalid, eFound, eAdded, eNoRoom };
BOOL FindOrAddEntry( const WCHAR *StringIn, ULONG CchIn, ULONG ulPseudoKey, CStringPoolHeap &rStringHeap, ULONG &rulPosition, FindOrAddDisposition &rdisposition, const CStringPoolEntry *&rpEntry );
ULONG EntriesAllocate() const { return m_cEntriesAllocated; } ULONG EntriesUsed() const { return m_cEntriesUsed; }
BOOL FillInStringArray(ULONG nArraySize, SXS_XML_STRING *prgStrings, ULONG iCurrent, ULONG &rcWritten);
//protected:
CStringPoolEntry *m_prgEntries; ULONG m_cEntriesAllocated; ULONG m_cEntriesUsed; CDequeLinkage m_leEntryChain; };
class CStringPool { public: CStringPool() : m_fInitialized(false), m_cEntries(0) { } ~CStringPool();
BOOL Initialize();
BOOL Canonicalize( const WCHAR *StringIn, ULONG CchIn, ULONG ulPseudoKey, ULONG &rulPosition, const WCHAR *&rStringOut );
BOOL GetEntryCount() const { return m_cEntries; } BOOL FillInStringArray(ULONG nArraySize, SXS_XML_STRING *prgStrings, ULONG &rcWritten);
protected: bool m_fInitialized; ULONG m_cEntries;
VOID ClearDequeEntry(CStringPoolEntryClump *p) const { FUSION_DELETE_SINGLETON(p); }
CStringPoolHeap m_StringHeap; CDeque<CStringPoolEntryClump, FIELD_OFFSET(CStringPoolEntryClump, m_leEntryChain)> m_dequeEntryClumps;
private: CStringPool(const CStringPool &); // intentionally not implemented
void operator =(const CStringPool &r); // intentionally not implemented
};
#endif
|