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