• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AppendString(FX_BSTR str)39     void					AppendString(FX_BSTR str)
40     {
41         AppendBlock(str.GetPtr(), str.GetLength());
42     }
43 
AppendByte(FX_BYTE byte)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 
GetBuffer()62     FX_LPBYTE				GetBuffer() const
63     {
64         return m_pBuffer;
65     }
66 
GetSize()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 
CFX_BinaryBuf(pAllocator)94     CFX_ByteTextBuf(IFX_Allocator* pAllocator = NULL) : CFX_BinaryBuf(pAllocator) {}
95 
96     void					operator = (FX_BSTR str);
97 
AppendChar(int ch)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 
GetLength()113     FX_STRSIZE				GetLength() const
114     {
115         return m_DataSize;
116     }
117 };
118 class CFX_WideTextBuf : public CFX_BinaryBuf
119 {
120 public:
121 
CFX_BinaryBuf(pAllocator)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 
GetLength()141     FX_STRSIZE				GetLength() const
142     {
143         return m_DataSize / sizeof(FX_WCHAR);
144     }
145 
GetBuffer()146     FX_LPWSTR				GetBuffer() const
147     {
148         return (FX_LPWSTR)m_pBuffer;
149     }
150 
Delete(int start_index,int count)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 
m_SavingBuf(pAllocator)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 
GetLength()183     FX_INTPTR				GetLength()
184     {
185         return m_SavingBuf.GetSize();
186     }
187 
GetBuffer()188     FX_LPCBYTE				GetBuffer()
189     {
190         return m_SavingBuf.GetBuffer();
191     }
192 
SetStream(IFX_FileStream * pStream)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 
m_Buffer(pAllocator)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 
ClearStatus()315     void			ClearStatus()
316     {
317         m_PendingBytes = 0;
318     }
319 
GetResult()320     CFX_WideStringC	GetResult() const
321     {
322         return m_Buffer.GetWideString();
323     }
GetResult(CFX_WideStringL & result)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 
m_Buffer(pAllocator)340     CFX_UTF8Encoder(IFX_Allocator* pAllocator = NULL) : m_Buffer(pAllocator)
341     {
342         m_UTF16First = 0;
343     }
344 
345     void			Input(FX_WCHAR unicode);
346 
AppendStr(FX_BSTR str)347     void			AppendStr(FX_BSTR str)
348     {
349         m_UTF16First = 0;
350         m_Buffer << str;
351     }
352 
GetResult()353     CFX_ByteStringC	GetResult() const
354     {
355         return m_Buffer.GetByteString();
356     }
GetResult(CFX_ByteStringL & result)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 
CFX_BasicArray(sizeof (TYPE),pAllocator)412     CFX_ArrayTemplate(IFX_Allocator* pAllocator = NULL) : CFX_BasicArray(sizeof(TYPE), pAllocator) {}
413 
GetSize()414     int			GetSize() const
415     {
416         return m_nSize;
417     }
418 
GetUpperBound()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 
RemoveAll()429     void		RemoveAll()
430     {
431         SetSize(0, -1);
432     }
433 
GetAt(int nIndex)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 
SetAt(int nIndex,TYPE newElement)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 
ElementAt(int nIndex)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 
GetData()459     const TYPE*	GetData() const
460     {
461         return (const TYPE*)m_pData;
462     }
463 
GetData()464     TYPE*		GetData()
465     {
466         return (TYPE*)m_pData;
467     }
468 
SetAtGrow(int nIndex,TYPE newElement)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 
Add(TYPE newElement)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 
Append(const CFX_ArrayTemplate & src)493     FX_BOOL		Append(const CFX_ArrayTemplate& src)
494     {
495         return CFX_BasicArray::Append(src);
496     }
497 
Copy(const CFX_ArrayTemplate & src)498     FX_BOOL		Copy(const CFX_ArrayTemplate& src)
499     {
500         return CFX_BasicArray::Copy(src);
501     }
502 
GetDataPtr(int index)503     TYPE*		GetDataPtr(int index)
504     {
505         return (TYPE*)CFX_BasicArray::GetDataPtr(index);
506     }
507 
AddSpace()508     TYPE*		AddSpace()
509     {
510         return (TYPE*)CFX_BasicArray::InsertSpaceAt(m_nSize, 1);
511     }
512 
InsertSpaceAt(int nIndex,int nCount)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 
InsertAt(int nStartIndex,const CFX_BasicArray * pNewArray)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 
CFX_BasicArray(sizeof (ObjectClass),pAllocator)579     CFX_ObjectArray(IFX_Allocator* pAllocator = NULL) : CFX_BasicArray(sizeof(ObjectClass), pAllocator) {}
580 
~CFX_ObjectArray()581     ~CFX_ObjectArray()
582     {
583         RemoveAll();
584     }
585 
Add(const ObjectClass & data)586     void			Add(const ObjectClass& data)
587     {
588         new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(data);
589     }
590 
Add()591     ObjectClass&	Add()
592     {
593         return *(ObjectClass*) new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass();
594     }
595 
AddSpace()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 
GetSize()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 
GetDataPtr(int index)670     ObjectClass*	GetDataPtr(int index)
671     {
672         return (ObjectClass*)CFX_BasicArray::GetDataPtr(index);
673     }
674 
RemoveAt(int index)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 
RemoveAll()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 
GetSize()710     int		GetSize() const
711     {
712         return m_DataSize;
713     }
714 
GetSegmentSize()715     int		GetSegmentSize() const
716     {
717         return m_SegmentSize;
718     }
719 
GetUnitSize()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)
CFX_BaseSegmentedArray(sizeof (ElementType),segment_units,index_size,pAllocator)751         : CFX_BaseSegmentedArray(sizeof(ElementType), segment_units, index_size, pAllocator)
752     {}
753 
Add(ElementType data)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)
m_pAllocator(pAllocator)769         : m_pAllocator(pAllocator)
770         , m_pData(NULL)
771     {}
772     CFX_FixedBufGrow(int data_size, IFX_Allocator* pAllocator = NULL)
m_pAllocator(pAllocator)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     }
SetDataSize(int data_size)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     }
~CFX_FixedBufGrow()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:
m_pAllocator(pAllocator)813     CFX_TempBuf(int size, IFX_Allocator* pAllocator = NULL) : m_pAllocator(pAllocator)
814     {
815         m_pData = FX_Allocator_Alloc(m_pAllocator, DataType, size);
816     }
~CFX_TempBuf()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 
GetCount()854     int GetCount() const
855     {
856         return m_nCount;
857     }
858 
IsEmpty()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 
SetAt(void * key,void * newValue)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 
GetStartPosition()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 
GetHashTableSize()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 
Lookup(KeyType key,ValueType & rValue)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 
SetAt(KeyType key,ValueType newValue)938     void SetAt(KeyType key, ValueType newValue)
939     {
940         CFX_MapPtrToPtr::SetAt((void*)(FX_UINTPTR)key, (void*)(FX_UINTPTR)newValue);
941     }
942 
RemoveKey(KeyType key)943     FX_BOOL	RemoveKey(KeyType key)
944     {
945         return CFX_MapPtrToPtr::RemoveKey((void*)(FX_UINTPTR)key);
946     }
947 
GetNextAssoc(FX_POSITION & rNextPosition,KeyType & rKey,ValueType & rValue)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 
m_Buffer(pAllocator)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 
GetCount()994     int GetCount() const
995     {
996         return m_nCount;
997     }
998 
IsEmpty()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 
SetAt(FX_BSTR key,void * newValue)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 
GetStartPosition()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 
GetHashTableSize()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 
GetHeadPosition()1104     FX_POSITION GetHeadPosition() const
1105     {
1106         return (FX_POSITION)m_pNodeHead;
1107     }
1108 
GetTailPosition()1109     FX_POSITION GetTailPosition() const
1110     {
1111         return (FX_POSITION)m_pNodeTail;
1112     }
1113 
GetNext(FX_POSITION & rPosition)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 
GetPrev(FX_POSITION & rPosition)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 
GetNextPosition(FX_POSITION pos)1128     FX_POSITION	GetNextPosition(FX_POSITION pos) const
1129     {
1130         return ((CNode*)pos)->pNext;
1131     }
1132 
GetPrevPosition(FX_POSITION pos)1133     FX_POSITION	GetPrevPosition(FX_POSITION pos) const
1134     {
1135         return ((CNode*)pos)->pPrev;
1136     }
1137 
GetAt(FX_POSITION rPosition)1138     void*	GetAt(FX_POSITION rPosition) const
1139     {
1140         CNode* pNode = (CNode*) rPosition;
1141         return pNode->data;
1142     }
1143 
GetCount()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 
SetAt(FX_POSITION pos,void * newElement)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 
m_DataList(pAllocator)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 
LookupPrivateData(FX_LPVOID module_id,FX_LPVOID & pData)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 
IsEOF()1253     FX_BOOL				IsEOF()
1254     {
1255         return m_BitPos >= m_BitSize;
1256     }
1257 
SkipBits(FX_DWORD nBits)1258     void				SkipBits(FX_DWORD nBits)
1259     {
1260         m_BitPos += nBits;
1261     }
1262 
Rewind()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 
CountedObj()1285         CountedObj() {}
1286 
CountedObj(const CountedObj & src)1287         CountedObj(const CountedObj& src) : ObjClass(src) {}
1288 
1289         int			m_RefCount;
1290     };
1291 
CFX_CountRef()1292     CFX_CountRef()
1293     {
1294         m_pObject = NULL;
1295     }
1296 
CFX_CountRef(const Ref & ref)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 
~CFX_CountRef()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 
New()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 
GetObject()1360     const ObjClass*		GetObject() const
1361     {
1362         return m_pObject;
1363     }
1364 
1365     operator			const ObjClass*() const
1366     {
1367         return m_pObject;
1368     }
1369 
IsNull()1370     FX_BOOL				IsNull() const
1371     {
1372         return m_pObject == NULL;
1373     }
1374 
NotNull()1375     FX_BOOL				NotNull() const
1376     {
1377         return m_pObject != NULL;
1378     }
1379 
GetModify()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 
SetNull()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 
IsEOF()1433     FX_BOOL			IsEOF() const
1434     {
1435         return m_bEOF;
1436     }
1437 
GetSrcPos()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:
CFX_SmartPointer(T * pObj)1463     CFX_SmartPointer(T *pObj) : m_pObj(pObj) {}
~CFX_SmartPointer()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 
~CFX_SortListArray()1500     ~CFX_SortListArray()
1501     {
1502         Clear();
1503     }
1504 
1505 
Clear()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 
Append(FX_INT32 nStart,FX_INT32 nCount)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 
GetAt(FX_INT32 nIndex)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:
Append(const DataList & list)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 
Clear()1606     void			Clear()
1607     {
1608         m_Data.Clear();
1609     }
1610 
Add(FX_INT32 nStart,FX_INT32 nCount)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 
GetPtrAt(FX_INT32 nIndex)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