Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #ifndef _FX_BASIC_H_
      8 #define _FX_BASIC_H_
      9 #ifndef _FX_SYSTEM_H_
     10 #include "fx_system.h"
     11 #endif
     12 #ifndef _FX_MEMORY_H_
     13 #include "fx_memory.h"
     14 #endif
     15 #ifndef _FX_STRING_H_
     16 #include "fx_string.h"
     17 #endif
     18 #ifndef _FX_STREAM_H_
     19 #include "fx_stream.h"
     20 #endif
     21 class CFX_BinaryBuf : public CFX_Object
     22 {
     23 public:
     24 
     25     CFX_BinaryBuf(IFX_Allocator* pAllocator = NULL);
     26 
     27     CFX_BinaryBuf(FX_STRSIZE size, IFX_Allocator* pAllocator = NULL);
     28 
     29     ~CFX_BinaryBuf();
     30 
     31     void					Clear();
     32 
     33     void					EstimateSize(FX_STRSIZE size, FX_STRSIZE alloc_step = 0);
     34 
     35     void					AppendBlock(const void* pBuf, FX_STRSIZE size);
     36 
     37     void					AppendFill(FX_BYTE byte, FX_STRSIZE count);
     38 
     39     void					AppendString(FX_BSTR str)
     40     {
     41         AppendBlock(str.GetPtr(), str.GetLength());
     42     }
     43 
     44     inline void				AppendByte(FX_BYTE byte)
     45     {
     46         if (m_AllocSize <= m_DataSize) {
     47             ExpandBuf(1);
     48         }
     49         m_pBuffer[m_DataSize++] = byte;
     50     }
     51 
     52     void					InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size);
     53 
     54     void					AttachData(void* pBuf, FX_STRSIZE size);
     55 
     56     void					CopyData(const void* pBuf, FX_STRSIZE size);
     57 
     58     void					TakeOver(CFX_BinaryBuf& other);
     59 
     60     void					Delete(int start_index, int count);
     61 
     62     FX_LPBYTE				GetBuffer() const
     63     {
     64         return m_pBuffer;
     65     }
     66 
     67     FX_STRSIZE				GetSize() const
     68     {
     69         return m_DataSize;
     70     }
     71 
     72     CFX_ByteStringC			GetByteString() const;
     73     void					GetByteStringL(CFX_ByteStringL &str) const;
     74 
     75     void					DetachBuffer();
     76 
     77     IFX_Allocator*			m_pAllocator;
     78 protected:
     79 
     80     FX_STRSIZE				m_AllocStep;
     81 
     82     FX_LPBYTE				m_pBuffer;
     83 
     84     FX_STRSIZE				m_DataSize;
     85 
     86     FX_STRSIZE				m_AllocSize;
     87 
     88     void					ExpandBuf(FX_STRSIZE size);
     89 };
     90 class CFX_ByteTextBuf : public CFX_BinaryBuf
     91 {
     92 public:
     93 
     94     CFX_ByteTextBuf(IFX_Allocator* pAllocator = NULL) : CFX_BinaryBuf(pAllocator) {}
     95 
     96     void					operator = (FX_BSTR str);
     97 
     98     void					AppendChar(int ch)
     99     {
    100         AppendByte((FX_BYTE)ch);
    101     }
    102 
    103     CFX_ByteTextBuf&		operator << (int i);
    104 
    105     CFX_ByteTextBuf&		operator << (FX_DWORD i);
    106 
    107     CFX_ByteTextBuf&		operator << (double f);
    108 
    109     CFX_ByteTextBuf&		operator << (FX_BSTR lpsz);
    110 
    111     CFX_ByteTextBuf&		operator << (const CFX_ByteTextBuf& buf);
    112 
    113     FX_STRSIZE				GetLength() const
    114     {
    115         return m_DataSize;
    116     }
    117 };
    118 class CFX_WideTextBuf : public CFX_BinaryBuf
    119 {
    120 public:
    121 
    122     CFX_WideTextBuf(IFX_Allocator* pAllocator = NULL) : CFX_BinaryBuf(pAllocator) {}
    123 
    124     void					operator = (FX_LPCWSTR lpsz);
    125 
    126     void					operator = (FX_WSTR str);
    127 
    128     void					AppendChar(FX_WCHAR wch);
    129 
    130     CFX_WideTextBuf&		operator << (int i);
    131 
    132     CFX_WideTextBuf&		operator << (double f);
    133 
    134     CFX_WideTextBuf&		operator << (FX_LPCWSTR lpsz);
    135 
    136     CFX_WideTextBuf&		operator << (FX_WSTR str);
    137     CFX_WideTextBuf&		operator << (const CFX_WideString &str);
    138 
    139     CFX_WideTextBuf&		operator << (const CFX_WideTextBuf& buf);
    140 
    141     FX_STRSIZE				GetLength() const
    142     {
    143         return m_DataSize / sizeof(FX_WCHAR);
    144     }
    145 
    146     FX_LPWSTR				GetBuffer() const
    147     {
    148         return (FX_LPWSTR)m_pBuffer;
    149     }
    150 
    151     void					Delete(int start_index, int count)
    152     {
    153         CFX_BinaryBuf::Delete(start_index * sizeof(FX_WCHAR), count * sizeof(FX_WCHAR));
    154     }
    155 
    156     CFX_WideStringC			GetWideString() const;
    157     void					GetWideStringL(CFX_WideStringL& wideText) const;
    158 };
    159 class CFX_ArchiveSaver : public CFX_Object
    160 {
    161 public:
    162 
    163     CFX_ArchiveSaver(IFX_Allocator* pAllocator = NULL) : m_SavingBuf(pAllocator), m_pStream(NULL) {}
    164 
    165     CFX_ArchiveSaver&		operator << (FX_BYTE i);
    166 
    167     CFX_ArchiveSaver&		operator << (int i);
    168 
    169     CFX_ArchiveSaver&		operator << (FX_DWORD i);
    170 
    171     CFX_ArchiveSaver&		operator << (FX_FLOAT i);
    172 
    173     CFX_ArchiveSaver&		operator << (double i);
    174 
    175     CFX_ArchiveSaver&		operator << (FX_BSTR bstr);
    176 
    177     CFX_ArchiveSaver&		operator << (FX_LPCWSTR bstr);
    178 
    179     CFX_ArchiveSaver&		operator << (const CFX_WideString& wstr);
    180 
    181     void					Write(const void* pData, FX_STRSIZE dwSize);
    182 
    183     FX_INTPTR				GetLength()
    184     {
    185         return m_SavingBuf.GetSize();
    186     }
    187 
    188     FX_LPCBYTE				GetBuffer()
    189     {
    190         return m_SavingBuf.GetBuffer();
    191     }
    192 
    193     void					SetStream(IFX_FileStream* pStream)
    194     {
    195         m_pStream = pStream;
    196     }
    197 protected:
    198 
    199     CFX_BinaryBuf			m_SavingBuf;
    200 
    201     IFX_FileStream*			m_pStream;
    202 };
    203 class CFX_ArchiveLoader : public CFX_Object
    204 {
    205 public:
    206 
    207     CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize);
    208 
    209     CFX_ArchiveLoader&		operator >> (FX_BYTE& i);
    210 
    211     CFX_ArchiveLoader&		operator >> (int& i);
    212 
    213     CFX_ArchiveLoader&		operator >> (FX_DWORD& i);
    214 
    215     CFX_ArchiveLoader&		operator >> (FX_FLOAT& i);
    216 
    217     CFX_ArchiveLoader&		operator >> (double& i);
    218 
    219     CFX_ArchiveLoader&		operator >> (CFX_ByteString& bstr);
    220 
    221     CFX_ArchiveLoader&		operator >> (CFX_WideString& wstr);
    222 
    223     FX_BOOL					IsEOF();
    224 
    225     FX_BOOL					Read(void* pBuf, FX_DWORD dwSize);
    226 protected:
    227 
    228     FX_DWORD				m_LoadingPos;
    229 
    230     FX_LPCBYTE				m_pLoadingBuf;
    231 
    232     FX_DWORD				m_LoadingSize;
    233 };
    234 class IFX_BufferArchive
    235 {
    236 public:
    237 
    238     IFX_BufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator = NULL);
    239 
    240 
    241     virtual void			Clear();
    242 
    243 
    244     FX_BOOL					Flush();
    245 
    246 
    247     FX_INT32				AppendBlock(const void* pBuf, size_t size);
    248 
    249     FX_INT32				AppendByte(FX_BYTE byte);
    250 
    251     FX_INT32				AppendDWord(FX_DWORD i);
    252 
    253 
    254     FX_INT32				AppendString(FX_BSTR lpsz);
    255 
    256 protected:
    257 
    258     virtual	FX_BOOL			DoWork(const void* pBuf, size_t size) = 0;
    259 
    260 
    261     IFX_Allocator*			m_pAllocator;
    262 
    263     FX_STRSIZE				m_BufSize;
    264 
    265     FX_LPBYTE				m_pBuffer;
    266 
    267     FX_STRSIZE				m_Length;
    268 };
    269 class CFX_FileBufferArchive : public IFX_BufferArchive, public CFX_Object
    270 {
    271 public:
    272     CFX_FileBufferArchive(FX_STRSIZE size = 32768, IFX_Allocator* pAllocator = NULL);
    273     ~CFX_FileBufferArchive();
    274     virtual void			Clear();
    275 
    276     FX_BOOL					AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover = FALSE);
    277 
    278     FX_BOOL					AttachFile(FX_LPCWSTR filename);
    279 
    280     FX_BOOL					AttachFile(FX_LPCSTR filename);
    281 private:
    282 
    283     virtual FX_BOOL			DoWork(const void* pBuf, size_t size);
    284 
    285     IFX_StreamWrite			*m_pFile;
    286 
    287     FX_BOOL					m_bTakeover;
    288 };
    289 struct CFX_CharMap {
    290 
    291     static CFX_CharMap*		GetDefaultMapper(FX_INT32 codepage = 0);
    292 
    293 
    294     CFX_WideString	(*m_GetWideString)(CFX_CharMap* pMap, const CFX_ByteString& bstr);
    295 
    296     CFX_ByteString	(*m_GetByteString)(CFX_CharMap* pMap, const CFX_WideString& wstr);
    297 
    298     FX_INT32		(*m_GetCodePage)();
    299 };
    300 class CFX_UTF8Decoder
    301 {
    302 public:
    303 
    304     CFX_UTF8Decoder(IFX_Allocator* pAllocator = NULL) : m_Buffer(pAllocator)
    305     {
    306         m_PendingBytes = 0;
    307     }
    308 
    309     void			Clear();
    310 
    311     void			Input(FX_BYTE byte);
    312 
    313     void			AppendChar(FX_DWORD ch);
    314 
    315     void			ClearStatus()
    316     {
    317         m_PendingBytes = 0;
    318     }
    319 
    320     CFX_WideStringC	GetResult() const
    321     {
    322         return m_Buffer.GetWideString();
    323     }
    324     void			GetResult(CFX_WideStringL &result) const
    325     {
    326         m_Buffer.GetWideStringL(result);
    327     }
    328 protected:
    329 
    330     int				m_PendingBytes;
    331 
    332     FX_DWORD		m_PendingChar;
    333 
    334     CFX_WideTextBuf	m_Buffer;
    335 };
    336 class CFX_UTF8Encoder
    337 {
    338 public:
    339 
    340     CFX_UTF8Encoder(IFX_Allocator* pAllocator = NULL) : m_Buffer(pAllocator)
    341     {
    342         m_UTF16First = 0;
    343     }
    344 
    345     void			Input(FX_WCHAR unicode);
    346 
    347     void			AppendStr(FX_BSTR str)
    348     {
    349         m_UTF16First = 0;
    350         m_Buffer << str;
    351     }
    352 
    353     CFX_ByteStringC	GetResult() const
    354     {
    355         return m_Buffer.GetByteString();
    356     }
    357     void			GetResult(CFX_ByteStringL &result) const
    358     {
    359         m_Buffer.GetByteStringL(result);
    360     }
    361 protected:
    362 
    363     CFX_ByteTextBuf	m_Buffer;
    364 
    365     FX_DWORD		m_UTF16First;
    366 };
    367 CFX_ByteString FX_UrlEncode(const CFX_WideString& wsUrl);
    368 CFX_WideString FX_UrlDecode(const CFX_ByteString& bsUrl);
    369 CFX_ByteString FX_EncodeURI(const CFX_WideString& wsURI);
    370 CFX_WideString FX_DecodeURI(const CFX_ByteString& bsURI);
    371 class CFX_BasicArray : public CFX_Object
    372 {
    373 public:
    374 
    375     IFX_Allocator*	m_pAllocator;
    376 protected:
    377 
    378     CFX_BasicArray(int unit_size, IFX_Allocator* pAllocator = NULL);
    379 
    380     ~CFX_BasicArray();
    381 
    382     FX_BOOL			SetSize(int nNewSize, int nGrowBy);
    383 
    384     FX_BOOL			Append(const CFX_BasicArray& src);
    385 
    386     FX_BOOL			Copy(const CFX_BasicArray& src);
    387 
    388     FX_LPBYTE		InsertSpaceAt(int nIndex, int nCount);
    389 
    390     FX_BOOL			RemoveAt(int nIndex, int nCount);
    391 
    392     FX_BOOL			InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray);
    393 
    394     const void*		GetDataPtr(int index) const;
    395 protected:
    396 
    397     FX_LPBYTE		m_pData;
    398 
    399     int				m_nSize;
    400 
    401     int				m_nMaxSize;
    402 
    403     int				m_nGrowBy;
    404 
    405     int				m_nUnitSize;
    406 };
    407 template<class TYPE>
    408 class CFX_ArrayTemplate : public CFX_BasicArray
    409 {
    410 public:
    411 
    412     CFX_ArrayTemplate(IFX_Allocator* pAllocator = NULL) : CFX_BasicArray(sizeof(TYPE), pAllocator) {}
    413 
    414     int			GetSize() const
    415     {
    416         return m_nSize;
    417     }
    418 
    419     int			GetUpperBound() const
    420     {
    421         return m_nSize - 1;
    422     }
    423 
    424     FX_BOOL		SetSize(int nNewSize, int nGrowBy = -1)
    425     {
    426         return CFX_BasicArray::SetSize(nNewSize, nGrowBy);
    427     }
    428 
    429     void		RemoveAll()
    430     {
    431         SetSize(0, -1);
    432     }
    433 
    434     const TYPE	GetAt(int nIndex) const
    435     {
    436         if (nIndex < 0 || nIndex >= m_nSize) {
    437             return (const TYPE&)(*(volatile const TYPE*)NULL);
    438         }
    439         return ((const TYPE*)m_pData)[nIndex];
    440     }
    441 
    442     FX_BOOL		SetAt(int nIndex, TYPE newElement)
    443     {
    444         if (nIndex < 0 || nIndex >= m_nSize) {
    445             return FALSE;
    446         }
    447         ((TYPE*)m_pData)[nIndex] = newElement;
    448         return TRUE;
    449     }
    450 
    451     TYPE&		ElementAt(int nIndex)
    452     {
    453         if (nIndex < 0 || nIndex >= m_nSize) {
    454             return *(TYPE*)NULL;
    455         }
    456         return ((TYPE*)m_pData)[nIndex];
    457     }
    458 
    459     const TYPE*	GetData() const
    460     {
    461         return (const TYPE*)m_pData;
    462     }
    463 
    464     TYPE*		GetData()
    465     {
    466         return (TYPE*)m_pData;
    467     }
    468 
    469     FX_BOOL		SetAtGrow(int nIndex, TYPE newElement)
    470     {
    471         if (nIndex < 0) {
    472             return FALSE;
    473         }
    474         if (nIndex >= m_nSize)
    475             if (!SetSize(nIndex + 1, -1)) {
    476                 return FALSE;
    477             }
    478         ((TYPE*)m_pData)[nIndex] = newElement;
    479         return TRUE;
    480     }
    481 
    482     FX_BOOL		Add(TYPE newElement)
    483     {
    484         if (m_nSize < m_nMaxSize) {
    485             m_nSize ++;
    486         } else if (!SetSize(m_nSize + 1, -1)) {
    487             return FALSE;
    488         }
    489         ((TYPE*)m_pData)[m_nSize - 1] = newElement;
    490         return TRUE;
    491     }
    492 
    493     FX_BOOL		Append(const CFX_ArrayTemplate& src)
    494     {
    495         return CFX_BasicArray::Append(src);
    496     }
    497 
    498     FX_BOOL		Copy(const CFX_ArrayTemplate& src)
    499     {
    500         return CFX_BasicArray::Copy(src);
    501     }
    502 
    503     TYPE*		GetDataPtr(int index)
    504     {
    505         return (TYPE*)CFX_BasicArray::GetDataPtr(index);
    506     }
    507 
    508     TYPE*		AddSpace()
    509     {
    510         return (TYPE*)CFX_BasicArray::InsertSpaceAt(m_nSize, 1);
    511     }
    512 
    513     TYPE*		InsertSpaceAt(int nIndex, int nCount)
    514     {
    515         return (TYPE*)CFX_BasicArray::InsertSpaceAt(nIndex, nCount);
    516     }
    517 
    518     const TYPE	operator[](int nIndex) const
    519     {
    520         if (nIndex < 0 || nIndex >= m_nSize) {
    521             *(volatile char*)0 = '\0';
    522         }
    523         return ((const TYPE*)m_pData)[nIndex];
    524     }
    525 
    526     TYPE&		operator[](int nIndex)
    527     {
    528         if (nIndex < 0 || nIndex >= m_nSize) {
    529             *(volatile char*)0 = '\0';
    530         }
    531         return ((TYPE*)m_pData)[nIndex];
    532     }
    533 
    534     FX_BOOL		InsertAt(int nIndex, TYPE newElement, int nCount = 1)
    535     {
    536         if (!InsertSpaceAt(nIndex, nCount)) {
    537             return FALSE;
    538         }
    539         while (nCount--) {
    540             ((TYPE*)m_pData)[nIndex++] = newElement;
    541         }
    542         return TRUE;
    543     }
    544 
    545     FX_BOOL		RemoveAt(int nIndex, int nCount = 1)
    546     {
    547         return CFX_BasicArray::RemoveAt(nIndex, nCount);
    548     }
    549 
    550     FX_BOOL		InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray)
    551     {
    552         return CFX_BasicArray::InsertAt(nStartIndex, pNewArray);
    553     }
    554 
    555     int			Find(TYPE data, int iStart = 0) const
    556     {
    557         if (iStart < 0) {
    558             return -1;
    559         }
    560         for (; iStart < (int)m_nSize; iStart ++)
    561             if (((TYPE*)m_pData)[iStart] == data) {
    562                 return iStart;
    563             }
    564         return -1;
    565     }
    566 };
    567 typedef CFX_ArrayTemplate<FX_BYTE>		CFX_ByteArray;
    568 typedef CFX_ArrayTemplate<FX_WORD>		CFX_WordArray;
    569 typedef CFX_ArrayTemplate<FX_DWORD>		CFX_DWordArray;
    570 typedef CFX_ArrayTemplate<void*>		CFX_PtrArray;
    571 typedef CFX_ArrayTemplate<FX_FILESIZE>	CFX_FileSizeArray;
    572 typedef CFX_ArrayTemplate<FX_FLOAT>		CFX_FloatArray;
    573 typedef CFX_ArrayTemplate<FX_INT32>		CFX_Int32Array;
    574 template <class ObjectClass>
    575 class CFX_ObjectArray : public CFX_BasicArray
    576 {
    577 public:
    578 
    579     CFX_ObjectArray(IFX_Allocator* pAllocator = NULL) : CFX_BasicArray(sizeof(ObjectClass), pAllocator) {}
    580 
    581     ~CFX_ObjectArray()
    582     {
    583         RemoveAll();
    584     }
    585 
    586     void			Add(const ObjectClass& data)
    587     {
    588         new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(data);
    589     }
    590 
    591     ObjectClass&	Add()
    592     {
    593         return *(ObjectClass*) new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass();
    594     }
    595 
    596     void*			AddSpace()
    597     {
    598         return InsertSpaceAt(m_nSize, 1);
    599     }
    600 
    601     FX_INT32		Append(const CFX_ObjectArray& src, FX_INT32 nStart = 0, FX_INT32 nCount = -1)
    602     {
    603         if (nCount == 0) {
    604             return 0;
    605         }
    606         FX_INT32 nSize = src.GetSize();
    607         if (!nSize) {
    608             return 0;
    609         }
    610         FXSYS_assert(nStart > -1 && nStart < nSize);
    611         if (nCount < 0) {
    612             nCount = nSize;
    613         }
    614         if (nStart + nCount > nSize) {
    615             nCount = nSize - nStart;
    616         }
    617         if (nCount < 1) {
    618             return 0;
    619         }
    620         nSize = m_nSize;
    621         InsertSpaceAt(m_nSize, nCount);
    622         ObjectClass* pStartObj = (ObjectClass*)GetDataPtr(nSize);
    623         nSize = nStart + nCount;
    624         for (FX_INT32 i = nStart; i < nSize; i ++, pStartObj++) {
    625             new ((void*)pStartObj) ObjectClass(src[i]);
    626         }
    627         return nCount;
    628     }
    629 
    630     FX_INT32		Copy(const CFX_ObjectArray& src, FX_INT32 nStart = 0, FX_INT32 nCount = -1)
    631     {
    632         if (nCount == 0) {
    633             return 0;
    634         }
    635         FX_INT32 nSize = src.GetSize();
    636         if (!nSize) {
    637             return 0;
    638         }
    639         FXSYS_assert(nStart > -1 && nStart < nSize);
    640         if (nCount < 0) {
    641             nCount = nSize;
    642         }
    643         if (nStart + nCount > nSize) {
    644             nCount = nSize - nStart;
    645         }
    646         if (nCount < 1) {
    647             return 0;
    648         }
    649         RemoveAll();
    650         SetSize(nCount, -1);
    651         ObjectClass* pStartObj = (ObjectClass*)m_pData;
    652         nSize = nStart + nCount;
    653         for (FX_INT32 i = nStart; i < nSize; i ++, pStartObj++) {
    654             new ((void*)pStartObj) ObjectClass(src[i]);
    655         }
    656         return nCount;
    657     }
    658 
    659     int				GetSize() const
    660     {
    661         return m_nSize;
    662     }
    663 
    664     ObjectClass&	operator[] (int index) const
    665     {
    666         FXSYS_assert(index < m_nSize);
    667         return *(ObjectClass*)CFX_BasicArray::GetDataPtr(index);
    668     }
    669 
    670     ObjectClass*	GetDataPtr(int index)
    671     {
    672         return (ObjectClass*)CFX_BasicArray::GetDataPtr(index);
    673     }
    674 
    675     void			RemoveAt(int index)
    676     {
    677         FXSYS_assert(index < m_nSize);
    678         ((ObjectClass*)GetDataPtr(index))->~ObjectClass();
    679         CFX_BasicArray::RemoveAt(index, 1);
    680     }
    681 
    682     void			RemoveAll()
    683     {
    684         for (int i = 0; i < m_nSize; i ++) {
    685             ((ObjectClass*)GetDataPtr(i))->~ObjectClass();
    686         }
    687         CFX_BasicArray::SetSize(0, -1);
    688     }
    689 };
    690 typedef CFX_ObjectArray<CFX_ByteString> CFX_ByteStringArray;
    691 typedef CFX_ObjectArray<CFX_WideString> CFX_WideStringArray;
    692 class CFX_BaseSegmentedArray : public CFX_Object
    693 {
    694 public:
    695 
    696     CFX_BaseSegmentedArray(int unit_size = 1, int segment_units = 512, int index_size = 8, IFX_Allocator* pAllocator = NULL);
    697 
    698     ~CFX_BaseSegmentedArray();
    699 
    700     void	SetUnitSize(int unit_size, int segment_units, int index_size = 8);
    701 
    702     void*	Add();
    703 
    704     void*	GetAt(int index) const;
    705 
    706     void	RemoveAll();
    707 
    708     void	Delete(int index, int count = 1);
    709 
    710     int		GetSize() const
    711     {
    712         return m_DataSize;
    713     }
    714 
    715     int		GetSegmentSize() const
    716     {
    717         return m_SegmentSize;
    718     }
    719 
    720     int		GetUnitSize() const
    721     {
    722         return m_UnitSize;
    723     }
    724 
    725     void*	Iterate(FX_BOOL (*callback)(void* param, void* pData), void* param) const;
    726 
    727     IFX_Allocator*	m_pAllocator;
    728 private:
    729 
    730     int				m_UnitSize;
    731 
    732     short			m_SegmentSize;
    733 
    734     FX_BYTE			m_IndexSize;
    735 
    736     FX_BYTE			m_IndexDepth;
    737 
    738     int				m_DataSize;
    739 
    740     void*			m_pIndex;
    741     void**	GetIndex(int seg_index) const;
    742     void*	IterateIndex(int level, int& start, void** pIndex, FX_BOOL (*callback)(void* param, void* pData), void* param) const;
    743     void*	IterateSegment(FX_LPCBYTE pSegment, int count, FX_BOOL (*callback)(void* param, void* pData), void* param) const;
    744 };
    745 template <class ElementType>
    746 class CFX_SegmentedArray : public CFX_BaseSegmentedArray
    747 {
    748 public:
    749 
    750     CFX_SegmentedArray(int segment_units, int index_size = 8, IFX_Allocator* pAllocator = NULL)
    751         : CFX_BaseSegmentedArray(sizeof(ElementType), segment_units, index_size, pAllocator)
    752     {}
    753 
    754     void	Add(ElementType data)
    755     {
    756         *(ElementType*)CFX_BaseSegmentedArray::Add() = data;
    757     }
    758 
    759     ElementType& operator [] (int index)
    760     {
    761         return *(ElementType*)CFX_BaseSegmentedArray::GetAt(index);
    762     }
    763 };
    764 template <class DataType, int FixedSize>
    765 class CFX_FixedBufGrow : public CFX_Object
    766 {
    767 public:
    768     CFX_FixedBufGrow(IFX_Allocator* pAllocator = NULL)
    769         : m_pAllocator(pAllocator)
    770         , m_pData(NULL)
    771     {}
    772     CFX_FixedBufGrow(int data_size, IFX_Allocator* pAllocator = NULL)
    773         : m_pAllocator(pAllocator)
    774         , m_pData(NULL)
    775     {
    776         if (data_size > FixedSize) {
    777             m_pData = FX_Allocator_Alloc(m_pAllocator, DataType, data_size);
    778         } else {
    779             FXSYS_memset32(m_Data, 0, sizeof(DataType)*FixedSize);
    780         }
    781     }
    782     void SetDataSize(int data_size)
    783     {
    784         if (m_pData) {
    785             FX_Allocator_Free(m_pAllocator, m_pData);
    786         }
    787         m_pData = NULL;
    788         if (data_size > FixedSize) {
    789             m_pData = FX_Allocator_Alloc(m_pAllocator, DataType, data_size);
    790         } else {
    791             FXSYS_memset32(m_Data, 0, sizeof(DataType)*FixedSize);
    792         }
    793     }
    794     ~CFX_FixedBufGrow()
    795     {
    796         if (m_pData) {
    797             FX_Allocator_Free(m_pAllocator, m_pData);
    798         }
    799     }
    800     operator DataType*()
    801     {
    802         return m_pData ? m_pData : m_Data;
    803     }
    804 private:
    805     IFX_Allocator*	m_pAllocator;
    806     DataType		m_Data[FixedSize];
    807     DataType*		m_pData;
    808 };
    809 template <class DataType>
    810 class CFX_TempBuf
    811 {
    812 public:
    813     CFX_TempBuf(int size, IFX_Allocator* pAllocator = NULL) : m_pAllocator(pAllocator)
    814     {
    815         m_pData = FX_Allocator_Alloc(m_pAllocator, DataType, size);
    816     }
    817     ~CFX_TempBuf()
    818     {
    819         if (m_pData) {
    820             FX_Allocator_Free(m_pAllocator, m_pData);
    821         }
    822     }
    823     DataType&	operator[](int i)
    824     {
    825         FXSYS_assert(m_pData != NULL);
    826         return m_pData[i];
    827     }
    828     operator DataType*()
    829     {
    830         return m_pData;
    831     }
    832 private:
    833     IFX_Allocator*	m_pAllocator;
    834     DataType*		m_pData;
    835 };
    836 class CFX_MapPtrToPtr : public CFX_Object
    837 {
    838 protected:
    839 
    840     struct CAssoc {
    841 
    842         CAssoc* pNext;
    843 
    844         void* key;
    845 
    846         void* value;
    847     };
    848 public:
    849 
    850     CFX_MapPtrToPtr(int nBlockSize = 10, IFX_Allocator* pAllocator = NULL);
    851 
    852     ~CFX_MapPtrToPtr();
    853 
    854     int GetCount() const
    855     {
    856         return m_nCount;
    857     }
    858 
    859     FX_BOOL IsEmpty() const
    860     {
    861         return m_nCount == 0;
    862     }
    863 
    864     FX_BOOL Lookup(void* key, void*& rValue) const;
    865 
    866     void* GetValueAt(void* key) const;
    867 
    868     void*& operator[](void* key);
    869 
    870     void SetAt(void* key, void* newValue)
    871     {
    872         (*this)[key] = newValue;
    873     }
    874 
    875     FX_BOOL RemoveKey(void* key);
    876 
    877     void RemoveAll();
    878 
    879     FX_POSITION GetStartPosition() const
    880     {
    881         return (m_nCount == 0) ? NULL : (FX_POSITION) - 1;
    882     }
    883 
    884     void GetNextAssoc(FX_POSITION& rNextPosition, void*& rKey, void*& rValue) const;
    885 
    886     FX_DWORD GetHashTableSize() const
    887     {
    888         return m_nHashTableSize;
    889     }
    890 
    891     void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE);
    892 protected:
    893 
    894     IFX_Allocator*	m_pAllocator;
    895 
    896     CAssoc** m_pHashTable;
    897 
    898     FX_DWORD m_nHashTableSize;
    899 
    900     int m_nCount;
    901 
    902     CAssoc* m_pFreeList;
    903 
    904     struct CFX_Plex* m_pBlocks;
    905 
    906     int m_nBlockSize;
    907 
    908     FX_DWORD HashKey(void* key) const;
    909 
    910     CAssoc* NewAssoc();
    911 
    912     void FreeAssoc(CAssoc* pAssoc);
    913 
    914     CAssoc* GetAssocAt(void* key, FX_DWORD& hash) const;
    915 };
    916 template <class KeyType, class ValueType>
    917 class CFX_MapPtrTemplate : public CFX_MapPtrToPtr
    918 {
    919 public:
    920 
    921     CFX_MapPtrTemplate(IFX_Allocator* pAllocator = NULL) : CFX_MapPtrToPtr(10, pAllocator) {}
    922 
    923     FX_BOOL	Lookup(KeyType key, ValueType& rValue) const
    924     {
    925         FX_LPVOID pValue = NULL;
    926         if (!CFX_MapPtrToPtr::Lookup((void*)(FX_UINTPTR)key, pValue)) {
    927             return FALSE;
    928         }
    929         rValue = (ValueType)(FX_UINTPTR)pValue;
    930         return TRUE;
    931     }
    932 
    933     ValueType& operator[](KeyType key)
    934     {
    935         return (ValueType&)CFX_MapPtrToPtr::operator []((void*)(FX_UINTPTR)key);
    936     }
    937 
    938     void SetAt(KeyType key, ValueType newValue)
    939     {
    940         CFX_MapPtrToPtr::SetAt((void*)(FX_UINTPTR)key, (void*)(FX_UINTPTR)newValue);
    941     }
    942 
    943     FX_BOOL	RemoveKey(KeyType key)
    944     {
    945         return CFX_MapPtrToPtr::RemoveKey((void*)(FX_UINTPTR)key);
    946     }
    947 
    948     void GetNextAssoc(FX_POSITION& rNextPosition, KeyType& rKey, ValueType& rValue) const
    949     {
    950         void* pKey = NULL;
    951         void* pValue = NULL;
    952         CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue);
    953         rKey = (KeyType)(FX_UINTPTR)pKey;
    954         rValue = (ValueType)(FX_UINTPTR)pValue;
    955     }
    956 };
    957 class CFX_CMapDWordToDWord : public CFX_Object
    958 {
    959 public:
    960 
    961     CFX_CMapDWordToDWord(IFX_Allocator* pAllocator = NULL) : m_Buffer(pAllocator) {}
    962 
    963     FX_BOOL			Lookup(FX_DWORD key, FX_DWORD& value) const;
    964 
    965     void			SetAt(FX_DWORD key, FX_DWORD value);
    966 
    967     void			EstimateSize(FX_DWORD size, FX_DWORD grow_by);
    968 
    969     FX_POSITION		GetStartPosition() const;
    970 
    971     void			GetNextAssoc(FX_POSITION& pos, FX_DWORD& key, FX_DWORD& value) const;
    972 protected:
    973 
    974     CFX_BinaryBuf	m_Buffer;
    975 };
    976 class CFX_MapByteStringToPtr : public CFX_Object
    977 {
    978 protected:
    979 
    980     struct CAssoc {
    981 
    982         CAssoc* pNext;
    983 
    984         FX_DWORD nHashValue;
    985 
    986         CFX_ByteString key;
    987 
    988         void* value;
    989     };
    990 public:
    991 
    992     CFX_MapByteStringToPtr(int nBlockSize = 10, IFX_Allocator* pAllocator = NULL);
    993 
    994     int GetCount() const
    995     {
    996         return m_nCount;
    997     }
    998 
    999     FX_BOOL IsEmpty() const
   1000     {
   1001         return m_nCount == 0;
   1002     }
   1003 
   1004     FX_BOOL Lookup(FX_BSTR key, void*& rValue) const;
   1005 
   1006     void*& operator[](FX_BSTR key);
   1007 
   1008     void SetAt(FX_BSTR key, void* newValue)
   1009     {
   1010         (*this)[key] = newValue;
   1011     }
   1012 
   1013     FX_BOOL RemoveKey(FX_BSTR key);
   1014 
   1015     void RemoveAll();
   1016 
   1017     FX_POSITION GetStartPosition() const
   1018     {
   1019         return (m_nCount == 0) ? NULL : (FX_POSITION) - 1;
   1020     }
   1021 
   1022     void GetNextAssoc(FX_POSITION& rNextPosition, CFX_ByteString& rKey, void*& rValue) const;
   1023 
   1024     FX_LPVOID		GetNextValue(FX_POSITION& rNextPosition) const;
   1025 
   1026     FX_DWORD GetHashTableSize() const
   1027     {
   1028         return m_nHashTableSize;
   1029     }
   1030 
   1031     void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE);
   1032 
   1033     FX_DWORD HashKey(FX_BSTR key) const;
   1034 protected:
   1035 
   1036     IFX_Allocator*	m_pAllocator;
   1037 
   1038     CAssoc** m_pHashTable;
   1039 
   1040     FX_DWORD m_nHashTableSize;
   1041 
   1042     int m_nCount;
   1043 
   1044     CAssoc* m_pFreeList;
   1045 
   1046     struct CFX_Plex* m_pBlocks;
   1047 
   1048     int m_nBlockSize;
   1049 
   1050     CAssoc* NewAssoc();
   1051 
   1052     void FreeAssoc(CAssoc* pAssoc);
   1053 
   1054     CAssoc* GetAssocAt(FX_BSTR key, FX_DWORD& hash) const;
   1055 public:
   1056 
   1057     ~CFX_MapByteStringToPtr();
   1058 };
   1059 class CFX_CMapByteStringToPtr : public CFX_Object
   1060 {
   1061 public:
   1062 
   1063     CFX_CMapByteStringToPtr(IFX_Allocator* pAllocator = NULL);
   1064 
   1065     ~CFX_CMapByteStringToPtr();
   1066 
   1067     void			RemoveAll();
   1068 
   1069     FX_POSITION		GetStartPosition() const;
   1070 
   1071     void			GetNextAssoc(FX_POSITION& rNextPosition, CFX_ByteString& rKey, void*& rValue) const;
   1072 
   1073     FX_LPVOID		GetNextValue(FX_POSITION& rNextPosition) const;
   1074 
   1075     FX_BOOL			Lookup(FX_BSTR key, void*& rValue) const;
   1076 
   1077     void			SetAt(FX_BSTR key, void* value);
   1078 
   1079     void			RemoveKey(FX_BSTR key);
   1080 
   1081     int				GetCount() const;
   1082 
   1083     void			AddValue(FX_BSTR key, void* pValue);
   1084 private:
   1085 
   1086     CFX_BaseSegmentedArray			m_Buffer;
   1087 };
   1088 class CFX_PtrList : public CFX_Object
   1089 {
   1090 protected:
   1091 
   1092     struct CNode {
   1093 
   1094         CNode* pNext;
   1095 
   1096         CNode* pPrev;
   1097 
   1098         void* data;
   1099     };
   1100 public:
   1101 
   1102     CFX_PtrList(int nBlockSize = 10, IFX_Allocator* pAllocator = NULL);
   1103 
   1104     FX_POSITION GetHeadPosition() const
   1105     {
   1106         return (FX_POSITION)m_pNodeHead;
   1107     }
   1108 
   1109     FX_POSITION GetTailPosition() const
   1110     {
   1111         return (FX_POSITION)m_pNodeTail;
   1112     }
   1113 
   1114     void*	GetNext(FX_POSITION& rPosition) const
   1115     {
   1116         CNode* pNode = (CNode*) rPosition;
   1117         rPosition = (FX_POSITION) pNode->pNext;
   1118         return pNode->data;
   1119     }
   1120 
   1121     void*	GetPrev(FX_POSITION& rPosition) const
   1122     {
   1123         CNode* pNode = (CNode*) rPosition;
   1124         rPosition = (FX_POSITION) pNode->pPrev;
   1125         return pNode->data;
   1126     }
   1127 
   1128     FX_POSITION	GetNextPosition(FX_POSITION pos) const
   1129     {
   1130         return ((CNode*)pos)->pNext;
   1131     }
   1132 
   1133     FX_POSITION	GetPrevPosition(FX_POSITION pos) const
   1134     {
   1135         return ((CNode*)pos)->pPrev;
   1136     }
   1137 
   1138     void*	GetAt(FX_POSITION rPosition) const
   1139     {
   1140         CNode* pNode = (CNode*) rPosition;
   1141         return pNode->data;
   1142     }
   1143 
   1144     int		GetCount() const
   1145     {
   1146         return m_nCount;
   1147     }
   1148 
   1149     FX_POSITION	AddTail(void* newElement);
   1150 
   1151     FX_POSITION AddHead(void* newElement);
   1152 
   1153     void	SetAt(FX_POSITION pos, void* newElement)
   1154     {
   1155         CNode* pNode = (CNode*) pos;
   1156         pNode->data = newElement;
   1157     }
   1158 
   1159     FX_POSITION InsertAfter(FX_POSITION pos, void* newElement);
   1160 
   1161     FX_POSITION Find(void* searchValue, FX_POSITION startAfter = NULL ) const;
   1162 
   1163     FX_POSITION FindIndex(int index) const;
   1164 
   1165     void	RemoveAt(FX_POSITION pos);
   1166 
   1167     void	RemoveAll();
   1168 protected:
   1169 
   1170     IFX_Allocator*	m_pAllocator;
   1171 
   1172     CNode* m_pNodeHead;
   1173 
   1174     CNode* m_pNodeTail;
   1175 
   1176     int m_nCount;
   1177 
   1178     CNode* m_pNodeFree;
   1179 
   1180     struct CFX_Plex* m_pBlocks;
   1181 
   1182     int m_nBlockSize;
   1183 
   1184     CNode* NewNode(CNode* pPrev, CNode* pNext);
   1185 
   1186     void FreeNode(CNode* pNode);
   1187 public:
   1188 
   1189     ~CFX_PtrList();
   1190 };
   1191 typedef void (*PD_CALLBACK_FREEDATA)(FX_LPVOID pData);
   1192 struct FX_PRIVATEDATA {
   1193 
   1194     void					FreeData();
   1195 
   1196     FX_LPVOID				m_pModuleId;
   1197 
   1198     FX_LPVOID				m_pData;
   1199 
   1200     PD_CALLBACK_FREEDATA	m_pCallback;
   1201 
   1202     FX_BOOL					m_bSelfDestruct;
   1203 };
   1204 class CFX_PrivateData
   1205 {
   1206 public:
   1207 
   1208     CFX_PrivateData(IFX_Allocator* pAllocator = NULL) : m_DataList(pAllocator) {}
   1209 
   1210     ~CFX_PrivateData();
   1211 
   1212     void					ClearAll();
   1213 
   1214     void					SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback);
   1215 
   1216     void					SetPrivateObj(FX_LPVOID module_id, CFX_DestructObject* pObj);
   1217 
   1218     FX_LPVOID				GetPrivateData(FX_LPVOID module_id);
   1219 
   1220     FX_BOOL					LookupPrivateData(FX_LPVOID module_id, FX_LPVOID &pData) const
   1221     {
   1222         if (!module_id) {
   1223             return FALSE;
   1224         }
   1225         FX_DWORD nCount = m_DataList.GetSize();
   1226         for (FX_DWORD n = 0; n < nCount; n ++) {
   1227             if (m_DataList[n].m_pModuleId == module_id) {
   1228                 pData = m_DataList[n].m_pData;
   1229                 return TRUE;
   1230             }
   1231         }
   1232         return FALSE;
   1233     }
   1234 
   1235     FX_BOOL					RemovePrivateData(FX_LPVOID module_id);
   1236 protected:
   1237 
   1238     CFX_ArrayTemplate<FX_PRIVATEDATA>	m_DataList;
   1239 
   1240     void					AddData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback, FX_BOOL bSelfDestruct);
   1241 };
   1242 class CFX_BitStream : public CFX_Object
   1243 {
   1244 public:
   1245 
   1246     void				Init(FX_LPCBYTE pData, FX_DWORD dwSize);
   1247 
   1248 
   1249     FX_DWORD			GetBits(FX_DWORD nBits);
   1250 
   1251     void				ByteAlign();
   1252 
   1253     FX_BOOL				IsEOF()
   1254     {
   1255         return m_BitPos >= m_BitSize;
   1256     }
   1257 
   1258     void				SkipBits(FX_DWORD nBits)
   1259     {
   1260         m_BitPos += nBits;
   1261     }
   1262 
   1263     void				Rewind()
   1264     {
   1265         m_BitPos = 0;
   1266     }
   1267 protected:
   1268 
   1269     FX_DWORD			m_BitPos;
   1270 
   1271     FX_DWORD			m_BitSize;
   1272 
   1273     FX_LPCBYTE			m_pData;
   1274 };
   1275 template <class ObjClass> class CFX_CountRef : public CFX_Object
   1276 {
   1277 public:
   1278 
   1279     typedef CFX_CountRef<ObjClass> Ref;
   1280 
   1281     class CountedObj : public ObjClass
   1282     {
   1283     public:
   1284 
   1285         CountedObj() {}
   1286 
   1287         CountedObj(const CountedObj& src) : ObjClass(src) {}
   1288 
   1289         int			m_RefCount;
   1290     };
   1291 
   1292     CFX_CountRef()
   1293     {
   1294         m_pObject = NULL;
   1295     }
   1296 
   1297     CFX_CountRef(const Ref& ref)
   1298     {
   1299         m_pObject = ref.m_pObject;
   1300         if (m_pObject) {
   1301             m_pObject->m_RefCount ++;
   1302         }
   1303     }
   1304 
   1305     ~CFX_CountRef()
   1306     {
   1307         if (!m_pObject) {
   1308             return;
   1309         }
   1310         m_pObject->m_RefCount --;
   1311         if (m_pObject->m_RefCount <= 0) {
   1312             delete m_pObject;
   1313         }
   1314     }
   1315 
   1316     ObjClass*			New()
   1317     {
   1318         if (m_pObject) {
   1319             m_pObject->m_RefCount --;
   1320             if (m_pObject->m_RefCount <= 0) {
   1321                 delete m_pObject;
   1322             }
   1323             m_pObject = NULL;
   1324         }
   1325         m_pObject = FX_NEW CountedObj;
   1326         if (!m_pObject) {
   1327             return NULL;
   1328         }
   1329         m_pObject->m_RefCount = 1;
   1330         return m_pObject;
   1331     }
   1332 
   1333     void				operator = (const Ref& ref)
   1334     {
   1335         if (ref.m_pObject) {
   1336             ref.m_pObject->m_RefCount ++;
   1337         }
   1338         if (m_pObject) {
   1339             m_pObject->m_RefCount --;
   1340             if (m_pObject->m_RefCount <= 0) {
   1341                 delete m_pObject;
   1342             }
   1343         }
   1344         m_pObject = ref.m_pObject;
   1345     }
   1346 
   1347     void				operator = (void* p)
   1348     {
   1349         FXSYS_assert(p == 0);
   1350         if (m_pObject == NULL) {
   1351             return;
   1352         }
   1353         m_pObject->m_RefCount --;
   1354         if (m_pObject->m_RefCount <= 0) {
   1355             delete m_pObject;
   1356         }
   1357         m_pObject = NULL;
   1358     }
   1359 
   1360     const ObjClass*		GetObject() const
   1361     {
   1362         return m_pObject;
   1363     }
   1364 
   1365     operator			const ObjClass*() const
   1366     {
   1367         return m_pObject;
   1368     }
   1369 
   1370     FX_BOOL				IsNull() const
   1371     {
   1372         return m_pObject == NULL;
   1373     }
   1374 
   1375     FX_BOOL				NotNull() const
   1376     {
   1377         return m_pObject != NULL;
   1378     }
   1379 
   1380     ObjClass*			GetModify()
   1381     {
   1382         if (m_pObject == NULL) {
   1383             m_pObject = FX_NEW CountedObj;
   1384             if (m_pObject) {
   1385                 m_pObject->m_RefCount = 1;
   1386             }
   1387         } else if (m_pObject->m_RefCount > 1) {
   1388             m_pObject->m_RefCount --;
   1389             CountedObj* pOldObject = m_pObject;
   1390             m_pObject = NULL;
   1391             m_pObject = FX_NEW CountedObj(*pOldObject);
   1392             if (m_pObject) {
   1393                 m_pObject->m_RefCount = 1;
   1394             }
   1395         }
   1396         return m_pObject;
   1397     }
   1398 
   1399     void				SetNull()
   1400     {
   1401         if (m_pObject == NULL) {
   1402             return;
   1403         }
   1404         m_pObject->m_RefCount --;
   1405         if (m_pObject->m_RefCount <= 0) {
   1406             delete m_pObject;
   1407         }
   1408         m_pObject = NULL;
   1409     }
   1410 
   1411     FX_BOOL				operator == (const Ref& ref) const
   1412     {
   1413         return m_pObject == ref.m_pObject;
   1414     }
   1415 protected:
   1416 
   1417     CountedObj*			m_pObject;
   1418 };
   1419 class IFX_Pause
   1420 {
   1421 public:
   1422 
   1423     virtual FX_BOOL	NeedToPauseNow() = 0;
   1424 };
   1425 class CFX_DataFilter : public CFX_Object
   1426 {
   1427 public:
   1428 
   1429     virtual ~CFX_DataFilter();
   1430 
   1431     void			SetDestFilter(CFX_DataFilter* pFilter);
   1432 
   1433     FX_BOOL			IsEOF() const
   1434     {
   1435         return m_bEOF;
   1436     }
   1437 
   1438     FX_DWORD		GetSrcPos()
   1439     {
   1440         return m_SrcPos;
   1441     }
   1442 
   1443     void			FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf);
   1444 
   1445     void			FilterFinish(CFX_BinaryBuf& dest_buf);
   1446 protected:
   1447 
   1448     CFX_DataFilter();
   1449     virtual void	v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) = 0;
   1450     virtual void	v_FilterFinish(CFX_BinaryBuf& dest_buf) = 0;
   1451     void			ReportEOF(FX_DWORD left_input);
   1452 
   1453     FX_BOOL			m_bEOF;
   1454 
   1455     FX_DWORD		m_SrcPos;
   1456 
   1457     CFX_DataFilter*	m_pDestFilter;
   1458 };
   1459 template <class T>
   1460 class CFX_SmartPointer
   1461 {
   1462 public:
   1463     CFX_SmartPointer(T *pObj) : m_pObj(pObj) {}
   1464     ~CFX_SmartPointer()
   1465     {
   1466         m_pObj->Release();
   1467     }
   1468     operator T*(void)
   1469     {
   1470         return m_pObj;
   1471     }
   1472     T&		operator *(void)
   1473     {
   1474         return *m_pObj;
   1475     }
   1476     T*		operator ->(void)
   1477     {
   1478         return m_pObj;
   1479     }
   1480 protected:
   1481     T *m_pObj;
   1482 };
   1483 #define FX_DATALIST_LENGTH	1024
   1484 template<size_t unit>
   1485 class CFX_SortListArray : public CFX_Object
   1486 {
   1487 protected:
   1488 
   1489     struct DataList {
   1490 
   1491         FX_INT32	start;
   1492 
   1493         FX_INT32	count;
   1494         FX_LPBYTE	data;
   1495     };
   1496 public:
   1497 
   1498     CFX_SortListArray(IFX_Allocator* pAllocator = NULL) : m_CurList(0), m_DataLists(pAllocator) {}
   1499 
   1500     ~CFX_SortListArray()
   1501     {
   1502         Clear();
   1503     }
   1504 
   1505 
   1506     void			Clear()
   1507     {
   1508         IFX_Allocator* pAllocator = m_DataLists.m_pAllocator;
   1509         for (FX_INT32 i = m_DataLists.GetUpperBound(); i >= 0; i--) {
   1510             DataList list = m_DataLists.ElementAt(i);
   1511             if (list.data) {
   1512                 FX_Allocator_Free(pAllocator, list.data);
   1513             }
   1514         }
   1515         m_DataLists.RemoveAll();
   1516         m_CurList = 0;
   1517     }
   1518 
   1519     void			Append(FX_INT32 nStart, FX_INT32 nCount)
   1520     {
   1521         if (nStart < 0) {
   1522             return;
   1523         }
   1524         IFX_Allocator* pAllocator = m_DataLists.m_pAllocator;
   1525         while (nCount > 0) {
   1526             FX_INT32 temp_count = FX_MIN(nCount, FX_DATALIST_LENGTH);
   1527             DataList list;
   1528             list.data = FX_Allocator_Alloc(pAllocator, FX_BYTE, temp_count * unit);
   1529             if (!list.data) {
   1530                 break;
   1531             }
   1532             FXSYS_memset32(list.data, 0, temp_count * unit);
   1533             list.start = nStart;
   1534             list.count = temp_count;
   1535             Append(list);
   1536             nCount -= temp_count;
   1537             nStart += temp_count;
   1538         }
   1539     }
   1540 
   1541     FX_LPBYTE		GetAt(FX_INT32 nIndex)
   1542     {
   1543         if (nIndex < 0) {
   1544             return NULL;
   1545         }
   1546         if (m_CurList < 0 || m_CurList >= m_DataLists.GetSize()) {
   1547             return NULL;
   1548         }
   1549         DataList *pCurList = m_DataLists.GetDataPtr(m_CurList);
   1550         if (!pCurList || nIndex < pCurList->start || nIndex >= pCurList->start + pCurList->count) {
   1551             pCurList = NULL;
   1552             FX_INT32 iStart = 0;
   1553             FX_INT32 iEnd = m_DataLists.GetUpperBound();
   1554             FX_INT32 iMid = 0;
   1555             while (iStart <= iEnd) {
   1556                 iMid = (iStart + iEnd) / 2;
   1557                 DataList* list = m_DataLists.GetDataPtr(iMid);
   1558                 if (nIndex < list->start) {
   1559                     iEnd = iMid - 1;
   1560                 } else if (nIndex >= list->start + list->count) {
   1561                     iStart = iMid + 1;
   1562                 } else {
   1563                     pCurList = list;
   1564                     m_CurList = iMid;
   1565                     break;
   1566                 }
   1567             }
   1568         }
   1569         return pCurList ? pCurList->data + (nIndex - pCurList->start) * unit : NULL;
   1570     }
   1571 protected:
   1572     void			Append(const DataList& list)
   1573     {
   1574         FX_INT32 iStart = 0;
   1575         FX_INT32 iEnd = m_DataLists.GetUpperBound();
   1576         FX_INT32 iFind = 0;
   1577         while (iStart <= iEnd) {
   1578             FX_INT32 iMid = (iStart + iEnd) / 2;
   1579             DataList* cur_list = m_DataLists.GetDataPtr(iMid);
   1580             if (list.start < cur_list->start + cur_list->count) {
   1581                 iEnd = iMid - 1;
   1582             } else {
   1583                 if (iMid == iEnd) {
   1584                     iFind = iMid + 1;
   1585                     break;
   1586                 }
   1587                 DataList* next_list = m_DataLists.GetDataPtr(iMid + 1);
   1588                 if (list.start < next_list->start) {
   1589                     iFind = iMid + 1;
   1590                     break;
   1591                 } else {
   1592                     iStart = iMid + 1;
   1593                 }
   1594             }
   1595         }
   1596         m_DataLists.InsertAt(iFind, list);
   1597     }
   1598     FX_INT32		m_CurList;
   1599     CFX_ArrayTemplate<DataList>	m_DataLists;
   1600 };
   1601 template<typename T1, typename T2>
   1602 class CFX_ListArrayTemplate : public CFX_Object
   1603 {
   1604 public:
   1605 
   1606     void			Clear()
   1607     {
   1608         m_Data.Clear();
   1609     }
   1610 
   1611     void			Add(FX_INT32 nStart, FX_INT32 nCount)
   1612     {
   1613         m_Data.Append(nStart, nCount);
   1614     }
   1615 
   1616     T2&				operator [] (FX_INT32 nIndex)
   1617     {
   1618         FX_LPBYTE data = m_Data.GetAt(nIndex);
   1619         FXSYS_assert(data != NULL);
   1620         return (T2&)(*(volatile T2*)data);
   1621     }
   1622 
   1623     T2*				GetPtrAt(FX_INT32 nIndex)
   1624     {
   1625         return (T2*)m_Data.GetAt(nIndex);
   1626     }
   1627 protected:
   1628     T1			m_Data;
   1629 };
   1630 typedef CFX_ListArrayTemplate<CFX_SortListArray<sizeof(FX_FILESIZE)>, FX_FILESIZE>	CFX_FileSizeListArray;
   1631 typedef CFX_ListArrayTemplate<CFX_SortListArray<sizeof(FX_DWORD)>, FX_DWORD>		CFX_DWordListArray;
   1632 typedef enum {
   1633     Ready,
   1634     ToBeContinued,
   1635     Found,
   1636     NotFound,
   1637     Failed,
   1638     Done
   1639 } FX_ProgressiveStatus;
   1640 #define ProgressiveStatus	FX_ProgressiveStatus
   1641 #define FX_NAMESPACE_DECLARE(namespace, type)       namespace::type
   1642 #endif
   1643