windows-nt/Source/XPSP1/NT/base/win32/fusion/inc/stringpool.h
2020-09-26 16:20:57 +08:00

176 lines
4.8 KiB
C++

#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