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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
10 #include "fx_memory.h"
11 #include "fx_stream.h"
12 #include "fx_string.h"
13 #include "fx_system.h"
15 // The FX_ArraySize(arr) macro returns the # of elements in an array arr.
16 // The expression is a compile-time constant, and therefore can be
17 // used in defining new arrays, for example. If you use FX_ArraySize on
18 // a pointer by mistake, you will get a compile-time error.
20 // One caveat is that FX_ArraySize() doesn't accept any array of an
21 // anonymous type or a type defined inside a function.
22 #define FX_ArraySize(array) (sizeof(ArraySizeHelper(array)))
24 // This template function declaration is used in defining FX_ArraySize.
25 // Note that the function doesn't need an implementation, as we only
27 template <typename T, size_t N>
28 char (&ArraySizeHelper(T (&array)[N]))[N];
30 class CFX_BinaryBuf : public CFX_Object
34 CFX_BinaryBuf(FX_STRSIZE size);
40 void EstimateSize(FX_STRSIZE size, FX_STRSIZE alloc_step = 0);
42 void AppendBlock(const void* pBuf, FX_STRSIZE size);
44 void AppendFill(FX_BYTE byte, FX_STRSIZE count);
46 void AppendString(FX_BSTR str)
48 AppendBlock(str.GetPtr(), str.GetLength());
51 inline void AppendByte(FX_BYTE byte)
53 if (m_AllocSize <= m_DataSize) {
56 m_pBuffer[m_DataSize++] = byte;
59 void InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size);
61 void AttachData(void* pBuf, FX_STRSIZE size);
63 void CopyData(const void* pBuf, FX_STRSIZE size);
65 void TakeOver(CFX_BinaryBuf& other);
67 void Delete(int start_index, int count);
69 FX_LPBYTE GetBuffer() const
74 FX_STRSIZE GetSize() const
79 CFX_ByteStringC GetByteString() const;
84 FX_STRSIZE m_AllocStep;
88 FX_STRSIZE m_DataSize;
90 FX_STRSIZE m_AllocSize;
92 void ExpandBuf(FX_STRSIZE size);
94 class CFX_ByteTextBuf : public CFX_BinaryBuf
98 void operator = (FX_BSTR str);
100 void AppendChar(int ch)
102 AppendByte((FX_BYTE)ch);
105 CFX_ByteTextBuf& operator << (int i);
107 CFX_ByteTextBuf& operator << (FX_DWORD i);
109 CFX_ByteTextBuf& operator << (double f);
111 CFX_ByteTextBuf& operator << (FX_BSTR lpsz);
113 CFX_ByteTextBuf& operator << (const CFX_ByteTextBuf& buf);
115 FX_STRSIZE GetLength() const
120 class CFX_WideTextBuf : public CFX_BinaryBuf
124 void operator = (FX_LPCWSTR lpsz);
126 void operator = (FX_WSTR str);
128 void AppendChar(FX_WCHAR wch);
130 CFX_WideTextBuf& operator << (int i);
132 CFX_WideTextBuf& operator << (double f);
134 CFX_WideTextBuf& operator << (FX_LPCWSTR lpsz);
136 CFX_WideTextBuf& operator << (FX_WSTR str);
137 CFX_WideTextBuf& operator << (const CFX_WideString &str);
139 CFX_WideTextBuf& operator << (const CFX_WideTextBuf& buf);
141 FX_STRSIZE GetLength() const
143 return m_DataSize / sizeof(FX_WCHAR);
146 FX_LPWSTR GetBuffer() const
148 return (FX_LPWSTR)m_pBuffer;
151 void Delete(int start_index, int count)
153 CFX_BinaryBuf::Delete(start_index * sizeof(FX_WCHAR), count * sizeof(FX_WCHAR));
156 CFX_WideStringC GetWideString() const;
158 class CFX_ArchiveSaver : public CFX_Object
161 CFX_ArchiveSaver() : m_pStream(NULL) {}
163 CFX_ArchiveSaver& operator << (FX_BYTE i);
165 CFX_ArchiveSaver& operator << (int i);
167 CFX_ArchiveSaver& operator << (FX_DWORD i);
169 CFX_ArchiveSaver& operator << (FX_FLOAT i);
171 CFX_ArchiveSaver& operator << (double i);
173 CFX_ArchiveSaver& operator << (FX_BSTR bstr);
175 CFX_ArchiveSaver& operator << (FX_LPCWSTR bstr);
177 CFX_ArchiveSaver& operator << (const CFX_WideString& wstr);
179 void Write(const void* pData, FX_STRSIZE dwSize);
181 FX_INTPTR GetLength()
183 return m_SavingBuf.GetSize();
186 FX_LPCBYTE GetBuffer()
188 return m_SavingBuf.GetBuffer();
191 void SetStream(IFX_FileStream* pStream)
197 CFX_BinaryBuf m_SavingBuf;
199 IFX_FileStream* m_pStream;
201 class CFX_ArchiveLoader : public CFX_Object
205 CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize);
207 CFX_ArchiveLoader& operator >> (FX_BYTE& i);
209 CFX_ArchiveLoader& operator >> (int& i);
211 CFX_ArchiveLoader& operator >> (FX_DWORD& i);
213 CFX_ArchiveLoader& operator >> (FX_FLOAT& i);
215 CFX_ArchiveLoader& operator >> (double& i);
217 CFX_ArchiveLoader& operator >> (CFX_ByteString& bstr);
219 CFX_ArchiveLoader& operator >> (CFX_WideString& wstr);
223 FX_BOOL Read(void* pBuf, FX_DWORD dwSize);
226 FX_DWORD m_LoadingPos;
228 FX_LPCBYTE m_pLoadingBuf;
230 FX_DWORD m_LoadingSize;
232 class IFX_BufferArchive
235 IFX_BufferArchive(FX_STRSIZE size);
236 virtual ~IFX_BufferArchive() { }
238 virtual void Clear();
244 FX_INT32 AppendBlock(const void* pBuf, size_t size);
246 FX_INT32 AppendByte(FX_BYTE byte);
248 FX_INT32 AppendDWord(FX_DWORD i);
251 FX_INT32 AppendString(FX_BSTR lpsz);
255 virtual FX_BOOL DoWork(const void* pBuf, size_t size) = 0;
257 FX_STRSIZE m_BufSize;
263 class CFX_FileBufferArchive : public IFX_BufferArchive, public CFX_Object
266 CFX_FileBufferArchive(FX_STRSIZE size = 32768);
267 ~CFX_FileBufferArchive() override;
268 virtual void Clear();
270 FX_BOOL AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover = FALSE);
272 FX_BOOL AttachFile(FX_LPCWSTR filename);
274 FX_BOOL AttachFile(FX_LPCSTR filename);
277 virtual FX_BOOL DoWork(const void* pBuf, size_t size);
279 IFX_StreamWrite *m_pFile;
285 static CFX_CharMap* GetDefaultMapper(FX_INT32 codepage = 0);
288 CFX_WideString (*m_GetWideString)(CFX_CharMap* pMap, const CFX_ByteString& bstr);
290 CFX_ByteString (*m_GetByteString)(CFX_CharMap* pMap, const CFX_WideString& wstr);
292 FX_INT32 (*m_GetCodePage)();
294 class CFX_UTF8Decoder
304 void Input(FX_BYTE byte);
306 void AppendChar(FX_DWORD ch);
313 CFX_WideStringC GetResult() const
315 return m_Buffer.GetWideString();
321 FX_DWORD m_PendingChar;
323 CFX_WideTextBuf m_Buffer;
325 class CFX_UTF8Encoder
333 void Input(FX_WCHAR unicode);
335 void AppendStr(FX_BSTR str)
341 CFX_ByteStringC GetResult() const
343 return m_Buffer.GetByteString();
347 CFX_ByteTextBuf m_Buffer;
349 FX_DWORD m_UTF16First;
351 CFX_ByteString FX_UrlEncode(const CFX_WideString& wsUrl);
352 CFX_WideString FX_UrlDecode(const CFX_ByteString& bsUrl);
353 CFX_ByteString FX_EncodeURI(const CFX_WideString& wsURI);
354 CFX_WideString FX_DecodeURI(const CFX_ByteString& bsURI);
355 class CFX_BasicArray : public CFX_Object
358 CFX_BasicArray(int unit_size);
362 FX_BOOL SetSize(int nNewSize);
364 FX_BOOL Append(const CFX_BasicArray& src);
366 FX_BOOL Copy(const CFX_BasicArray& src);
368 FX_LPBYTE InsertSpaceAt(int nIndex, int nCount);
370 FX_BOOL RemoveAt(int nIndex, int nCount);
372 FX_BOOL InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray);
374 const void* GetDataPtr(int index) const;
386 class CFX_ArrayTemplate : public CFX_BasicArray
389 CFX_ArrayTemplate() : CFX_BasicArray(sizeof(TYPE)) {}
396 int GetUpperBound() const
401 FX_BOOL SetSize(int nNewSize)
403 return CFX_BasicArray::SetSize(nNewSize);
411 const TYPE GetAt(int nIndex) const
413 if (nIndex < 0 || nIndex >= m_nSize) {
414 return (const TYPE&)(*(volatile const TYPE*)NULL);
416 return ((const TYPE*)m_pData)[nIndex];
419 FX_BOOL SetAt(int nIndex, TYPE newElement)
421 if (nIndex < 0 || nIndex >= m_nSize) {
424 ((TYPE*)m_pData)[nIndex] = newElement;
428 TYPE& ElementAt(int nIndex)
430 if (nIndex < 0 || nIndex >= m_nSize) {
433 return ((TYPE*)m_pData)[nIndex];
436 const TYPE* GetData() const
438 return (const TYPE*)m_pData;
443 return (TYPE*)m_pData;
446 FX_BOOL SetAtGrow(int nIndex, TYPE newElement)
451 if (nIndex >= m_nSize)
452 if (!SetSize(nIndex + 1)) {
455 ((TYPE*)m_pData)[nIndex] = newElement;
459 FX_BOOL Add(TYPE newElement)
461 if (m_nSize < m_nMaxSize) {
463 } else if (!SetSize(m_nSize + 1)) {
466 ((TYPE*)m_pData)[m_nSize - 1] = newElement;
470 FX_BOOL Append(const CFX_ArrayTemplate& src)
472 return CFX_BasicArray::Append(src);
475 FX_BOOL Copy(const CFX_ArrayTemplate& src)
477 return CFX_BasicArray::Copy(src);
480 TYPE* GetDataPtr(int index)
482 return (TYPE*)CFX_BasicArray::GetDataPtr(index);
487 return (TYPE*)CFX_BasicArray::InsertSpaceAt(m_nSize, 1);
490 TYPE* InsertSpaceAt(int nIndex, int nCount)
492 return (TYPE*)CFX_BasicArray::InsertSpaceAt(nIndex, nCount);
495 const TYPE operator[](int nIndex) const
497 if (nIndex < 0 || nIndex >= m_nSize) {
498 *(volatile char*)0 = '\0';
500 return ((const TYPE*)m_pData)[nIndex];
503 TYPE& operator[](int nIndex)
505 if (nIndex < 0 || nIndex >= m_nSize) {
506 *(volatile char*)0 = '\0';
508 return ((TYPE*)m_pData)[nIndex];
511 FX_BOOL InsertAt(int nIndex, TYPE newElement, int nCount = 1)
513 if (!InsertSpaceAt(nIndex, nCount)) {
517 ((TYPE*)m_pData)[nIndex++] = newElement;
522 FX_BOOL RemoveAt(int nIndex, int nCount = 1)
524 return CFX_BasicArray::RemoveAt(nIndex, nCount);
527 FX_BOOL InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray)
529 return CFX_BasicArray::InsertAt(nStartIndex, pNewArray);
532 int Find(TYPE data, int iStart = 0) const
537 for (; iStart < (int)m_nSize; iStart ++)
538 if (((TYPE*)m_pData)[iStart] == data) {
544 typedef CFX_ArrayTemplate<FX_BYTE> CFX_ByteArray;
545 typedef CFX_ArrayTemplate<FX_WORD> CFX_WordArray;
546 typedef CFX_ArrayTemplate<FX_DWORD> CFX_DWordArray;
547 typedef CFX_ArrayTemplate<void*> CFX_PtrArray;
548 typedef CFX_ArrayTemplate<FX_FILESIZE> CFX_FileSizeArray;
549 typedef CFX_ArrayTemplate<FX_FLOAT> CFX_FloatArray;
550 typedef CFX_ArrayTemplate<FX_INT32> CFX_Int32Array;
551 template <class ObjectClass>
552 class CFX_ObjectArray : public CFX_BasicArray
555 CFX_ObjectArray() : CFX_BasicArray(sizeof(ObjectClass)) {}
562 void Add(const ObjectClass& data)
564 new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(data);
569 return *(ObjectClass*) new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass();
574 return InsertSpaceAt(m_nSize, 1);
577 FX_INT32 Append(const CFX_ObjectArray& src, FX_INT32 nStart = 0, FX_INT32 nCount = -1)
582 FX_INT32 nSize = src.GetSize();
586 FXSYS_assert(nStart > -1 && nStart < nSize);
590 if (nStart + nCount > nSize) {
591 nCount = nSize - nStart;
597 InsertSpaceAt(m_nSize, nCount);
598 ObjectClass* pStartObj = (ObjectClass*)GetDataPtr(nSize);
599 nSize = nStart + nCount;
600 for (FX_INT32 i = nStart; i < nSize; i ++, pStartObj++) {
601 new ((void*)pStartObj) ObjectClass(src[i]);
606 FX_INT32 Copy(const CFX_ObjectArray& src, FX_INT32 nStart = 0, FX_INT32 nCount = -1)
611 FX_INT32 nSize = src.GetSize();
615 FXSYS_assert(nStart > -1 && nStart < nSize);
619 if (nStart + nCount > nSize) {
620 nCount = nSize - nStart;
627 ObjectClass* pStartObj = (ObjectClass*)m_pData;
628 nSize = nStart + nCount;
629 for (FX_INT32 i = nStart; i < nSize; i ++, pStartObj++) {
630 new ((void*)pStartObj) ObjectClass(src[i]);
640 ObjectClass& operator[] (int index) const
642 FXSYS_assert(index < m_nSize);
643 return *(ObjectClass*)CFX_BasicArray::GetDataPtr(index);
646 ObjectClass* GetDataPtr(int index)
648 return (ObjectClass*)CFX_BasicArray::GetDataPtr(index);
651 void RemoveAt(int index)
653 FXSYS_assert(index < m_nSize);
654 ((ObjectClass*)GetDataPtr(index))->~ObjectClass();
655 CFX_BasicArray::RemoveAt(index, 1);
660 for (int i = 0; i < m_nSize; i ++) {
661 ((ObjectClass*)GetDataPtr(i))->~ObjectClass();
663 CFX_BasicArray::SetSize(0);
666 typedef CFX_ObjectArray<CFX_ByteString> CFX_ByteStringArray;
667 typedef CFX_ObjectArray<CFX_WideString> CFX_WideStringArray;
668 class CFX_BaseSegmentedArray : public CFX_Object
671 CFX_BaseSegmentedArray(int unit_size = 1, int segment_units = 512, int index_size = 8);
673 ~CFX_BaseSegmentedArray();
675 void SetUnitSize(int unit_size, int segment_units, int index_size = 8);
679 void* GetAt(int index) const;
683 void Delete(int index, int count = 1);
690 int GetSegmentSize() const
692 return m_SegmentSize;
695 int GetUnitSize() const
700 void* Iterate(FX_BOOL (*callback)(void* param, void* pData), void* param) const;
709 FX_BYTE m_IndexDepth;
714 void** GetIndex(int seg_index) const;
715 void* IterateIndex(int level, int& start, void** pIndex, FX_BOOL (*callback)(void* param, void* pData), void* param) const;
716 void* IterateSegment(FX_LPCBYTE pSegment, int count, FX_BOOL (*callback)(void* param, void* pData), void* param) const;
718 template <class ElementType>
719 class CFX_SegmentedArray : public CFX_BaseSegmentedArray
722 CFX_SegmentedArray(int segment_units, int index_size = 8)
723 : CFX_BaseSegmentedArray(sizeof(ElementType), segment_units, index_size)
726 void Add(ElementType data)
728 *(ElementType*)CFX_BaseSegmentedArray::Add() = data;
731 ElementType& operator [] (int index)
733 return *(ElementType*)CFX_BaseSegmentedArray::GetAt(index);
736 template <class DataType, int FixedSize>
737 class CFX_FixedBufGrow : public CFX_Object
740 CFX_FixedBufGrow() : m_pData(NULL)
742 CFX_FixedBufGrow(int data_size) : m_pData(NULL)
744 if (data_size > FixedSize) {
745 m_pData = FX_Alloc(DataType, data_size);
747 FXSYS_memset32(m_Data, 0, sizeof(DataType)*FixedSize);
750 void SetDataSize(int data_size)
756 if (data_size > FixedSize) {
757 m_pData = FX_Alloc(DataType, data_size);
759 FXSYS_memset32(m_Data, 0, sizeof(DataType)*FixedSize);
770 return m_pData ? m_pData : m_Data;
773 DataType m_Data[FixedSize];
776 template <class DataType>
780 CFX_TempBuf(int size)
782 m_pData = FX_Alloc(DataType, size);
790 DataType& operator[](int i)
792 FXSYS_assert(m_pData != NULL);
802 class CFX_MapPtrToPtr : public CFX_Object
815 CFX_MapPtrToPtr(int nBlockSize = 10);
824 FX_BOOL IsEmpty() const
826 return m_nCount == 0;
829 FX_BOOL Lookup(void* key, void*& rValue) const;
831 void* GetValueAt(void* key) const;
833 void*& operator[](void* key);
835 void SetAt(void* key, void* newValue)
837 (*this)[key] = newValue;
840 FX_BOOL RemoveKey(void* key);
844 FX_POSITION GetStartPosition() const
846 return (m_nCount == 0) ? NULL : (FX_POSITION) - 1;
849 void GetNextAssoc(FX_POSITION& rNextPosition, void*& rKey, void*& rValue) const;
851 FX_DWORD GetHashTableSize() const
853 return m_nHashTableSize;
856 void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE);
859 CAssoc** m_pHashTable;
861 FX_DWORD m_nHashTableSize;
867 struct CFX_Plex* m_pBlocks;
871 FX_DWORD HashKey(void* key) const;
875 void FreeAssoc(CAssoc* pAssoc);
877 CAssoc* GetAssocAt(void* key, FX_DWORD& hash) const;
879 template <class KeyType, class ValueType>
880 class CFX_MapPtrTemplate : public CFX_MapPtrToPtr
883 CFX_MapPtrTemplate() : CFX_MapPtrToPtr(10) {}
885 FX_BOOL Lookup(KeyType key, ValueType& rValue) const
887 FX_LPVOID pValue = NULL;
888 if (!CFX_MapPtrToPtr::Lookup((void*)(FX_UINTPTR)key, pValue)) {
891 rValue = (ValueType)(FX_UINTPTR)pValue;
895 ValueType& operator[](KeyType key)
897 return (ValueType&)CFX_MapPtrToPtr::operator []((void*)(FX_UINTPTR)key);
900 void SetAt(KeyType key, ValueType newValue)
902 CFX_MapPtrToPtr::SetAt((void*)(FX_UINTPTR)key, (void*)(FX_UINTPTR)newValue);
905 FX_BOOL RemoveKey(KeyType key)
907 return CFX_MapPtrToPtr::RemoveKey((void*)(FX_UINTPTR)key);
910 void GetNextAssoc(FX_POSITION& rNextPosition, KeyType& rKey, ValueType& rValue) const
914 CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue);
915 rKey = (KeyType)(FX_UINTPTR)pKey;
916 rValue = (ValueType)(FX_UINTPTR)pValue;
919 class CFX_CMapDWordToDWord : public CFX_Object
923 FX_BOOL Lookup(FX_DWORD key, FX_DWORD& value) const;
925 void SetAt(FX_DWORD key, FX_DWORD value);
927 void EstimateSize(FX_DWORD size, FX_DWORD grow_by);
929 FX_POSITION GetStartPosition() const;
931 void GetNextAssoc(FX_POSITION& pos, FX_DWORD& key, FX_DWORD& value) const;
934 CFX_BinaryBuf m_Buffer;
936 class CFX_MapByteStringToPtr : public CFX_Object
951 CFX_MapByteStringToPtr(int nBlockSize = 10);
958 FX_BOOL IsEmpty() const
960 return m_nCount == 0;
963 FX_BOOL Lookup(FX_BSTR key, void*& rValue) const;
965 void*& operator[](FX_BSTR key);
967 void SetAt(FX_BSTR key, void* newValue)
969 (*this)[key] = newValue;
972 FX_BOOL RemoveKey(FX_BSTR key);
976 FX_POSITION GetStartPosition() const
978 return (m_nCount == 0) ? NULL : (FX_POSITION) - 1;
981 void GetNextAssoc(FX_POSITION& rNextPosition, CFX_ByteString& rKey, void*& rValue) const;
983 FX_LPVOID GetNextValue(FX_POSITION& rNextPosition) const;
985 FX_DWORD GetHashTableSize() const
987 return m_nHashTableSize;
990 void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE);
992 FX_DWORD HashKey(FX_BSTR key) const;
995 CAssoc** m_pHashTable;
997 FX_DWORD m_nHashTableSize;
1001 CAssoc* m_pFreeList;
1003 struct CFX_Plex* m_pBlocks;
1009 void FreeAssoc(CAssoc* pAssoc);
1011 CAssoc* GetAssocAt(FX_BSTR key, FX_DWORD& hash) const;
1014 ~CFX_MapByteStringToPtr();
1016 class CFX_CMapByteStringToPtr : public CFX_Object
1019 CFX_CMapByteStringToPtr();
1021 ~CFX_CMapByteStringToPtr();
1025 FX_POSITION GetStartPosition() const;
1027 void GetNextAssoc(FX_POSITION& rNextPosition, CFX_ByteString& rKey, void*& rValue) const;
1029 FX_LPVOID GetNextValue(FX_POSITION& rNextPosition) const;
1031 FX_BOOL Lookup(FX_BSTR key, void*& rValue) const;
1033 void SetAt(FX_BSTR key, void* value);
1035 void RemoveKey(FX_BSTR key);
1037 int GetCount() const;
1039 void AddValue(FX_BSTR key, void* pValue);
1042 CFX_BaseSegmentedArray m_Buffer;
1044 class CFX_PtrList : public CFX_Object
1057 CFX_PtrList(int nBlockSize = 10);
1059 FX_POSITION GetHeadPosition() const
1061 return (FX_POSITION)m_pNodeHead;
1064 FX_POSITION GetTailPosition() const
1066 return (FX_POSITION)m_pNodeTail;
1069 void* GetNext(FX_POSITION& rPosition) const
1071 CNode* pNode = (CNode*) rPosition;
1072 rPosition = (FX_POSITION) pNode->pNext;
1076 void* GetPrev(FX_POSITION& rPosition) const
1078 CNode* pNode = (CNode*) rPosition;
1079 rPosition = (FX_POSITION) pNode->pPrev;
1083 FX_POSITION GetNextPosition(FX_POSITION pos) const
1085 return ((CNode*)pos)->pNext;
1088 FX_POSITION GetPrevPosition(FX_POSITION pos) const
1090 return ((CNode*)pos)->pPrev;
1093 void* GetAt(FX_POSITION rPosition) const
1095 CNode* pNode = (CNode*) rPosition;
1099 int GetCount() const
1104 FX_POSITION AddTail(void* newElement);
1106 FX_POSITION AddHead(void* newElement);
1108 void SetAt(FX_POSITION pos, void* newElement)
1110 CNode* pNode = (CNode*) pos;
1111 pNode->data = newElement;
1114 FX_POSITION InsertAfter(FX_POSITION pos, void* newElement);
1116 FX_POSITION Find(void* searchValue, FX_POSITION startAfter = NULL ) const;
1118 FX_POSITION FindIndex(int index) const;
1120 void RemoveAt(FX_POSITION pos);
1133 struct CFX_Plex* m_pBlocks;
1137 CNode* NewNode(CNode* pPrev, CNode* pNext);
1139 void FreeNode(CNode* pNode);
1144 typedef void (*PD_CALLBACK_FREEDATA)(FX_LPVOID pData);
1145 struct FX_PRIVATEDATA {
1149 FX_LPVOID m_pModuleId;
1153 PD_CALLBACK_FREEDATA m_pCallback;
1155 FX_BOOL m_bSelfDestruct;
1157 class CFX_PrivateData
1165 void SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback);
1167 void SetPrivateObj(FX_LPVOID module_id, CFX_DestructObject* pObj);
1169 FX_LPVOID GetPrivateData(FX_LPVOID module_id);
1171 FX_BOOL LookupPrivateData(FX_LPVOID module_id, FX_LPVOID &pData) const
1176 FX_DWORD nCount = m_DataList.GetSize();
1177 for (FX_DWORD n = 0; n < nCount; n ++) {
1178 if (m_DataList[n].m_pModuleId == module_id) {
1179 pData = m_DataList[n].m_pData;
1186 FX_BOOL RemovePrivateData(FX_LPVOID module_id);
1189 CFX_ArrayTemplate<FX_PRIVATEDATA> m_DataList;
1191 void AddData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback, FX_BOOL bSelfDestruct);
1193 class CFX_BitStream : public CFX_Object
1197 void Init(FX_LPCBYTE pData, FX_DWORD dwSize);
1200 FX_DWORD GetBits(FX_DWORD nBits);
1206 return m_BitPos >= m_BitSize;
1209 void SkipBits(FX_DWORD nBits)
1226 template <class ObjClass> class CFX_CountRef : public CFX_Object
1230 typedef CFX_CountRef<ObjClass> Ref;
1232 class CountedObj : public ObjClass
1238 CountedObj(const CountedObj& src) : ObjClass(src) {}
1248 CFX_CountRef(const Ref& ref)
1250 m_pObject = ref.m_pObject;
1252 m_pObject->m_RefCount ++;
1261 m_pObject->m_RefCount --;
1262 if (m_pObject->m_RefCount <= 0) {
1270 m_pObject->m_RefCount --;
1271 if (m_pObject->m_RefCount <= 0) {
1276 m_pObject = FX_NEW CountedObj;
1280 m_pObject->m_RefCount = 1;
1284 void operator = (const Ref& ref)
1286 if (ref.m_pObject) {
1287 ref.m_pObject->m_RefCount ++;
1290 m_pObject->m_RefCount --;
1291 if (m_pObject->m_RefCount <= 0) {
1295 m_pObject = ref.m_pObject;
1298 void operator = (void* p)
1300 FXSYS_assert(p == 0);
1301 if (m_pObject == NULL) {
1304 m_pObject->m_RefCount --;
1305 if (m_pObject->m_RefCount <= 0) {
1311 const ObjClass* GetObject() const
1316 operator const ObjClass*() const
1321 FX_BOOL IsNull() const
1323 return m_pObject == NULL;
1326 FX_BOOL NotNull() const
1328 return m_pObject != NULL;
1331 ObjClass* GetModify()
1333 if (m_pObject == NULL) {
1334 m_pObject = FX_NEW CountedObj;
1336 m_pObject->m_RefCount = 1;
1338 } else if (m_pObject->m_RefCount > 1) {
1339 m_pObject->m_RefCount --;
1340 CountedObj* pOldObject = m_pObject;
1342 m_pObject = FX_NEW CountedObj(*pOldObject);
1344 m_pObject->m_RefCount = 1;
1352 if (m_pObject == NULL) {
1355 m_pObject->m_RefCount --;
1356 if (m_pObject->m_RefCount <= 0) {
1362 FX_BOOL operator == (const Ref& ref) const
1364 return m_pObject == ref.m_pObject;
1368 CountedObj* m_pObject;
1373 virtual ~IFX_Pause() { }
1374 virtual FX_BOOL NeedToPauseNow() = 0;
1376 class CFX_DataFilter : public CFX_Object
1380 virtual ~CFX_DataFilter();
1382 void SetDestFilter(CFX_DataFilter* pFilter);
1384 FX_BOOL IsEOF() const
1389 FX_DWORD GetSrcPos()
1394 void FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf);
1396 void FilterFinish(CFX_BinaryBuf& dest_buf);
1400 virtual void v_FilterIn(FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf) = 0;
1401 virtual void v_FilterFinish(CFX_BinaryBuf& dest_buf) = 0;
1402 void ReportEOF(FX_DWORD left_input);
1408 CFX_DataFilter* m_pDestFilter;
1411 template<typename T>
1412 class CFX_AutoRestorer {
1414 explicit CFX_AutoRestorer(T* location) {
1415 m_Location = location;
1416 m_OldValue = *location;
1418 ~CFX_AutoRestorer() { *m_Location = m_OldValue; }
1426 class CFX_SmartPointer
1429 CFX_SmartPointer(T *pObj) : m_pObj(pObj) {}
1442 T* operator ->(void)
1449 #define FX_DATALIST_LENGTH 1024
1450 template<size_t unit>
1451 class CFX_SortListArray : public CFX_Object
1464 CFX_SortListArray() : m_CurList(0) {}
1466 ~CFX_SortListArray()
1474 for (FX_INT32 i = m_DataLists.GetUpperBound(); i >= 0; i--) {
1475 DataList list = m_DataLists.ElementAt(i);
1480 m_DataLists.RemoveAll();
1484 void Append(FX_INT32 nStart, FX_INT32 nCount)
1489 while (nCount > 0) {
1490 FX_INT32 temp_count = FX_MIN(nCount, FX_DATALIST_LENGTH);
1492 list.data = FX_Alloc(FX_BYTE, temp_count * unit);
1496 list.start = nStart;
1497 list.count = temp_count;
1499 nCount -= temp_count;
1500 nStart += temp_count;
1504 FX_LPBYTE GetAt(FX_INT32 nIndex)
1509 if (m_CurList < 0 || m_CurList >= m_DataLists.GetSize()) {
1512 DataList *pCurList = m_DataLists.GetDataPtr(m_CurList);
1513 if (!pCurList || nIndex < pCurList->start || nIndex >= pCurList->start + pCurList->count) {
1515 FX_INT32 iStart = 0;
1516 FX_INT32 iEnd = m_DataLists.GetUpperBound();
1518 while (iStart <= iEnd) {
1519 iMid = (iStart + iEnd) / 2;
1520 DataList* list = m_DataLists.GetDataPtr(iMid);
1521 if (nIndex < list->start) {
1523 } else if (nIndex >= list->start + list->count) {
1532 return pCurList ? pCurList->data + (nIndex - pCurList->start) * unit : NULL;
1535 void Append(const DataList& list)
1537 FX_INT32 iStart = 0;
1538 FX_INT32 iEnd = m_DataLists.GetUpperBound();
1540 while (iStart <= iEnd) {
1541 FX_INT32 iMid = (iStart + iEnd) / 2;
1542 DataList* cur_list = m_DataLists.GetDataPtr(iMid);
1543 if (list.start < cur_list->start + cur_list->count) {
1550 DataList* next_list = m_DataLists.GetDataPtr(iMid + 1);
1551 if (list.start < next_list->start) {
1559 m_DataLists.InsertAt(iFind, list);
1562 CFX_ArrayTemplate<DataList> m_DataLists;
1564 template<typename T1, typename T2>
1565 class CFX_ListArrayTemplate : public CFX_Object
1574 void Add(FX_INT32 nStart, FX_INT32 nCount)
1576 m_Data.Append(nStart, nCount);
1579 T2& operator [] (FX_INT32 nIndex)
1581 FX_LPBYTE data = m_Data.GetAt(nIndex);
1582 FXSYS_assert(data != NULL);
1583 return (T2&)(*(volatile T2*)data);
1586 T2* GetPtrAt(FX_INT32 nIndex)
1588 return (T2*)m_Data.GetAt(nIndex);
1593 typedef CFX_ListArrayTemplate<CFX_SortListArray<sizeof(FX_FILESIZE)>, FX_FILESIZE> CFX_FileSizeListArray;
1594 typedef CFX_ListArrayTemplate<CFX_SortListArray<sizeof(FX_DWORD)>, FX_DWORD> CFX_DWordListArray;
1602 } FX_ProgressiveStatus;
1603 #define ProgressiveStatus FX_ProgressiveStatus
1604 #define FX_NAMESPACE_DECLARE(namespace, type) namespace::type
1608 virtual FX_DWORD Release() = 0;
1609 virtual FX_DWORD AddRef() = 0;
1611 #define FX_IsOdd(a) ((a) & 1)
1613 class CFX_Vector_3by1 : public CFX_Object
1618 a(0.0f), b(0.0f), c(0.0f)
1621 CFX_Vector_3by1(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1):
1629 class CFX_Matrix_3by3 : public CFX_Object
1634 a(0.0f), b(0.0f), c(0.0f), d(0.0f), e(0.0f), f(0.0f), g(0.0f), h(0.0f), i(0.0f)
1637 CFX_Matrix_3by3(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1, FX_FLOAT d1, FX_FLOAT e1, FX_FLOAT f1, FX_FLOAT g1, FX_FLOAT h1, FX_FLOAT i1) :
1638 a(a1), b(b1), c(c1), d(d1), e(e1), f(f1), g(g1), h(h1), i(i1)
1641 CFX_Matrix_3by3 Inverse();
1643 CFX_Matrix_3by3 Multiply(const CFX_Matrix_3by3 &m);
1645 CFX_Vector_3by1 TransformVector(const CFX_Vector_3by1 &v);