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 CORE_INCLUDE_FXCRT_FX_BASIC_H_ 8 #define CORE_INCLUDE_FXCRT_FX_BASIC_H_ 9 10 #include <algorithm> 11 12 #include "fx_memory.h" 13 #include "fx_stream.h" 14 #include "fx_string.h" 15 #include "fx_system.h" 16 17 // The FX_ArraySize(arr) macro returns the # of elements in an array arr. 18 // The expression is a compile-time constant, and therefore can be 19 // used in defining new arrays, for example. If you use FX_ArraySize on 20 // a pointer by mistake, you will get a compile-time error. 21 // 22 // One caveat is that FX_ArraySize() doesn't accept any array of an 23 // anonymous type or a type defined inside a function. 24 #define FX_ArraySize(array) (sizeof(ArraySizeHelper(array))) 25 26 // This template function declaration is used in defining FX_ArraySize. 27 // Note that the function doesn't need an implementation, as we only 28 // use its type. 29 template <typename T, size_t N> 30 char(&ArraySizeHelper(T(&array)[N]))[N]; 31 32 class CFX_BinaryBuf { 33 public: 34 CFX_BinaryBuf(); 35 CFX_BinaryBuf(FX_STRSIZE size); 36 37 ~CFX_BinaryBuf(); 38 39 void Clear(); 40 41 void EstimateSize(FX_STRSIZE size, FX_STRSIZE alloc_step = 0); 42 43 void AppendBlock(const void* pBuf, FX_STRSIZE size); 44 45 void AppendFill(uint8_t byte, FX_STRSIZE count); 46 AppendString(const CFX_ByteStringC & str)47 void AppendString(const CFX_ByteStringC& str) { 48 AppendBlock(str.GetPtr(), str.GetLength()); 49 } 50 AppendByte(uint8_t byte)51 inline void AppendByte(uint8_t byte) { 52 if (m_AllocSize <= m_DataSize) { 53 ExpandBuf(1); 54 } 55 m_pBuffer[m_DataSize++] = byte; 56 } 57 58 void InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size); 59 60 void AttachData(void* pBuf, FX_STRSIZE size); 61 62 void CopyData(const void* pBuf, FX_STRSIZE size); 63 64 void TakeOver(CFX_BinaryBuf& other); 65 66 void Delete(int start_index, int count); 67 GetBuffer()68 uint8_t* GetBuffer() const { return m_pBuffer; } 69 GetSize()70 FX_STRSIZE GetSize() const { return m_DataSize; } 71 72 CFX_ByteStringC GetByteString() const; 73 74 void DetachBuffer(); 75 76 protected: 77 FX_STRSIZE m_AllocStep; 78 79 uint8_t* m_pBuffer; 80 81 FX_STRSIZE m_DataSize; 82 83 FX_STRSIZE m_AllocSize; 84 85 void ExpandBuf(FX_STRSIZE size); 86 }; 87 class CFX_ByteTextBuf : public CFX_BinaryBuf { 88 public: 89 void operator=(const CFX_ByteStringC& str); 90 AppendChar(int ch)91 void AppendChar(int ch) { AppendByte((uint8_t)ch); } 92 93 CFX_ByteTextBuf& operator<<(int i); 94 95 CFX_ByteTextBuf& operator<<(FX_DWORD i); 96 97 CFX_ByteTextBuf& operator<<(double f); 98 99 CFX_ByteTextBuf& operator<<(const CFX_ByteStringC& lpsz); 100 101 CFX_ByteTextBuf& operator<<(const CFX_ByteTextBuf& buf); 102 GetLength()103 FX_STRSIZE GetLength() const { return m_DataSize; } 104 }; 105 class CFX_WideTextBuf : public CFX_BinaryBuf { 106 public: 107 void operator=(const FX_WCHAR* lpsz); 108 109 void operator=(const CFX_WideStringC& str); 110 111 void AppendChar(FX_WCHAR wch); 112 113 CFX_WideTextBuf& operator<<(int i); 114 115 CFX_WideTextBuf& operator<<(double f); 116 117 CFX_WideTextBuf& operator<<(const FX_WCHAR* lpsz); 118 119 CFX_WideTextBuf& operator<<(const CFX_WideStringC& str); 120 CFX_WideTextBuf& operator<<(const CFX_WideString& str); 121 122 CFX_WideTextBuf& operator<<(const CFX_WideTextBuf& buf); 123 GetLength()124 FX_STRSIZE GetLength() const { return m_DataSize / sizeof(FX_WCHAR); } 125 GetBuffer()126 FX_WCHAR* GetBuffer() const { return (FX_WCHAR*)m_pBuffer; } 127 Delete(int start_index,int count)128 void Delete(int start_index, int count) { 129 CFX_BinaryBuf::Delete(start_index * sizeof(FX_WCHAR), 130 count * sizeof(FX_WCHAR)); 131 } 132 133 CFX_WideStringC GetWideString() const; 134 }; 135 #ifdef PDF_ENABLE_XFA 136 class CFX_ArchiveSaver { 137 public: CFX_ArchiveSaver()138 CFX_ArchiveSaver() : m_pStream(NULL) {} 139 140 CFX_ArchiveSaver& operator<<(uint8_t i); 141 142 CFX_ArchiveSaver& operator<<(int i); 143 144 CFX_ArchiveSaver& operator<<(FX_DWORD i); 145 146 CFX_ArchiveSaver& operator<<(FX_FLOAT i); 147 148 CFX_ArchiveSaver& operator<<(double i); 149 150 CFX_ArchiveSaver& operator<<(const CFX_ByteStringC& bstr); 151 152 CFX_ArchiveSaver& operator<<(const FX_WCHAR* bstr); 153 154 CFX_ArchiveSaver& operator<<(const CFX_WideString& wstr); 155 156 void Write(const void* pData, FX_STRSIZE dwSize); 157 GetLength()158 intptr_t GetLength() { return m_SavingBuf.GetSize(); } 159 GetBuffer()160 const uint8_t* GetBuffer() { return m_SavingBuf.GetBuffer(); } 161 SetStream(IFX_FileStream * pStream)162 void SetStream(IFX_FileStream* pStream) { m_pStream = pStream; } 163 164 protected: 165 CFX_BinaryBuf m_SavingBuf; 166 167 IFX_FileStream* m_pStream; 168 }; 169 class CFX_ArchiveLoader { 170 public: 171 CFX_ArchiveLoader(const uint8_t* pData, FX_DWORD dwSize); 172 173 CFX_ArchiveLoader& operator>>(uint8_t& i); 174 175 CFX_ArchiveLoader& operator>>(int& i); 176 177 CFX_ArchiveLoader& operator>>(FX_DWORD& i); 178 179 CFX_ArchiveLoader& operator>>(FX_FLOAT& i); 180 181 CFX_ArchiveLoader& operator>>(double& i); 182 183 CFX_ArchiveLoader& operator>>(CFX_ByteString& bstr); 184 185 CFX_ArchiveLoader& operator>>(CFX_WideString& wstr); 186 187 FX_BOOL IsEOF(); 188 189 FX_BOOL Read(void* pBuf, FX_DWORD dwSize); 190 191 protected: 192 FX_DWORD m_LoadingPos; 193 194 const uint8_t* m_pLoadingBuf; 195 196 FX_DWORD m_LoadingSize; 197 }; 198 #endif // PDF_ENABLE_XFA 199 200 class IFX_BufferArchive { 201 public: 202 IFX_BufferArchive(FX_STRSIZE size); ~IFX_BufferArchive()203 virtual ~IFX_BufferArchive() {} 204 205 virtual void Clear(); 206 207 FX_BOOL Flush(); 208 209 int32_t AppendBlock(const void* pBuf, size_t size); 210 211 int32_t AppendByte(uint8_t byte); 212 213 int32_t AppendDWord(FX_DWORD i); 214 215 int32_t AppendString(const CFX_ByteStringC& lpsz); 216 217 protected: 218 virtual FX_BOOL DoWork(const void* pBuf, size_t size) = 0; 219 220 FX_STRSIZE m_BufSize; 221 222 uint8_t* m_pBuffer; 223 224 FX_STRSIZE m_Length; 225 }; 226 227 class CFX_FileBufferArchive : public IFX_BufferArchive { 228 public: 229 CFX_FileBufferArchive(FX_STRSIZE size = 32768); 230 ~CFX_FileBufferArchive() override; 231 232 void Clear() override; 233 FX_BOOL AttachFile(IFX_StreamWrite* pFile, FX_BOOL bTakeover = FALSE); 234 235 private: 236 FX_BOOL DoWork(const void* pBuf, size_t size) override; 237 238 IFX_StreamWrite* m_pFile; 239 FX_BOOL m_bTakeover; 240 }; 241 242 struct CFX_CharMap { 243 static CFX_CharMap* GetDefaultMapper(int32_t codepage = 0); 244 245 CFX_WideString (*m_GetWideString)(CFX_CharMap* pMap, 246 const CFX_ByteString& bstr); 247 248 CFX_ByteString (*m_GetByteString)(CFX_CharMap* pMap, 249 const CFX_WideString& wstr); 250 251 int32_t (*m_GetCodePage)(); 252 }; 253 class CFX_UTF8Decoder { 254 public: CFX_UTF8Decoder()255 CFX_UTF8Decoder() { m_PendingBytes = 0; } 256 257 void Clear(); 258 259 void Input(uint8_t byte); 260 261 void AppendChar(FX_DWORD ch); 262 ClearStatus()263 void ClearStatus() { m_PendingBytes = 0; } 264 GetResult()265 CFX_WideStringC GetResult() const { return m_Buffer.GetWideString(); } 266 267 protected: 268 int m_PendingBytes; 269 270 FX_DWORD m_PendingChar; 271 272 CFX_WideTextBuf m_Buffer; 273 }; 274 275 class CFX_UTF8Encoder { 276 public: CFX_UTF8Encoder()277 CFX_UTF8Encoder() {} 278 279 void Input(FX_WCHAR unicode); AppendStr(const CFX_ByteStringC & str)280 void AppendStr(const CFX_ByteStringC& str) { m_Buffer << str; } GetResult()281 CFX_ByteStringC GetResult() const { return m_Buffer.GetByteString(); } 282 283 protected: 284 CFX_ByteTextBuf m_Buffer; 285 }; 286 287 class CFX_BasicArray { 288 protected: 289 CFX_BasicArray(int unit_size); 290 291 ~CFX_BasicArray(); 292 293 FX_BOOL SetSize(int nNewSize); 294 295 FX_BOOL Append(const CFX_BasicArray& src); 296 297 FX_BOOL Copy(const CFX_BasicArray& src); 298 299 uint8_t* InsertSpaceAt(int nIndex, int nCount); 300 301 FX_BOOL RemoveAt(int nIndex, int nCount); 302 303 FX_BOOL InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray); 304 305 const void* GetDataPtr(int index) const; 306 307 protected: 308 uint8_t* m_pData; 309 310 int m_nSize; 311 312 int m_nMaxSize; 313 314 int m_nUnitSize; 315 }; 316 template <class TYPE> 317 class CFX_ArrayTemplate : public CFX_BasicArray { 318 public: CFX_ArrayTemplate()319 CFX_ArrayTemplate() : CFX_BasicArray(sizeof(TYPE)) {} 320 GetSize()321 int GetSize() const { return m_nSize; } 322 GetUpperBound()323 int GetUpperBound() const { return m_nSize - 1; } 324 SetSize(int nNewSize)325 FX_BOOL SetSize(int nNewSize) { return CFX_BasicArray::SetSize(nNewSize); } 326 RemoveAll()327 void RemoveAll() { SetSize(0); } 328 GetAt(int nIndex)329 const TYPE GetAt(int nIndex) const { 330 if (nIndex < 0 || nIndex >= m_nSize) { 331 return (const TYPE&)(*(volatile const TYPE*)NULL); 332 } 333 return ((const TYPE*)m_pData)[nIndex]; 334 } 335 SetAt(int nIndex,TYPE newElement)336 FX_BOOL SetAt(int nIndex, TYPE newElement) { 337 if (nIndex < 0 || nIndex >= m_nSize) { 338 return FALSE; 339 } 340 ((TYPE*)m_pData)[nIndex] = newElement; 341 return TRUE; 342 } 343 ElementAt(int nIndex)344 TYPE& ElementAt(int nIndex) { 345 if (nIndex < 0 || nIndex >= m_nSize) { 346 return *(TYPE*)NULL; 347 } 348 return ((TYPE*)m_pData)[nIndex]; 349 } 350 GetData()351 const TYPE* GetData() const { return (const TYPE*)m_pData; } 352 GetData()353 TYPE* GetData() { return (TYPE*)m_pData; } 354 SetAtGrow(int nIndex,TYPE newElement)355 FX_BOOL SetAtGrow(int nIndex, TYPE newElement) { 356 if (nIndex < 0) { 357 return FALSE; 358 } 359 if (nIndex >= m_nSize) 360 if (!SetSize(nIndex + 1)) { 361 return FALSE; 362 } 363 ((TYPE*)m_pData)[nIndex] = newElement; 364 return TRUE; 365 } 366 Add(TYPE newElement)367 FX_BOOL Add(TYPE newElement) { 368 if (m_nSize < m_nMaxSize) { 369 m_nSize++; 370 } else if (!SetSize(m_nSize + 1)) { 371 return FALSE; 372 } 373 ((TYPE*)m_pData)[m_nSize - 1] = newElement; 374 return TRUE; 375 } 376 Append(const CFX_ArrayTemplate & src)377 FX_BOOL Append(const CFX_ArrayTemplate& src) { 378 return CFX_BasicArray::Append(src); 379 } 380 Copy(const CFX_ArrayTemplate & src)381 FX_BOOL Copy(const CFX_ArrayTemplate& src) { 382 return CFX_BasicArray::Copy(src); 383 } 384 GetDataPtr(int index)385 TYPE* GetDataPtr(int index) { 386 return (TYPE*)CFX_BasicArray::GetDataPtr(index); 387 } 388 AddSpace()389 TYPE* AddSpace() { return (TYPE*)CFX_BasicArray::InsertSpaceAt(m_nSize, 1); } 390 InsertSpaceAt(int nIndex,int nCount)391 TYPE* InsertSpaceAt(int nIndex, int nCount) { 392 return (TYPE*)CFX_BasicArray::InsertSpaceAt(nIndex, nCount); 393 } 394 395 const TYPE operator[](int nIndex) const { 396 if (nIndex < 0 || nIndex >= m_nSize) { 397 *(volatile char*)0 = '\0'; 398 } 399 return ((const TYPE*)m_pData)[nIndex]; 400 } 401 402 TYPE& operator[](int nIndex) { 403 if (nIndex < 0 || nIndex >= m_nSize) { 404 *(volatile char*)0 = '\0'; 405 } 406 return ((TYPE*)m_pData)[nIndex]; 407 } 408 409 FX_BOOL InsertAt(int nIndex, TYPE newElement, int nCount = 1) { 410 if (!InsertSpaceAt(nIndex, nCount)) { 411 return FALSE; 412 } 413 while (nCount--) { 414 ((TYPE*)m_pData)[nIndex++] = newElement; 415 } 416 return TRUE; 417 } 418 419 FX_BOOL RemoveAt(int nIndex, int nCount = 1) { 420 return CFX_BasicArray::RemoveAt(nIndex, nCount); 421 } 422 InsertAt(int nStartIndex,const CFX_BasicArray * pNewArray)423 FX_BOOL InsertAt(int nStartIndex, const CFX_BasicArray* pNewArray) { 424 return CFX_BasicArray::InsertAt(nStartIndex, pNewArray); 425 } 426 427 int Find(TYPE data, int iStart = 0) const { 428 if (iStart < 0) { 429 return -1; 430 } 431 for (; iStart < (int)m_nSize; iStart++) 432 if (((TYPE*)m_pData)[iStart] == data) { 433 return iStart; 434 } 435 return -1; 436 } 437 }; 438 typedef CFX_ArrayTemplate<uint8_t> CFX_ByteArray; 439 typedef CFX_ArrayTemplate<FX_WORD> CFX_WordArray; 440 typedef CFX_ArrayTemplate<FX_DWORD> CFX_DWordArray; 441 typedef CFX_ArrayTemplate<void*> CFX_PtrArray; 442 typedef CFX_ArrayTemplate<FX_FILESIZE> CFX_FileSizeArray; 443 #ifdef PDF_ENABLE_XFA 444 typedef CFX_ArrayTemplate<FX_FLOAT> CFX_FloatArray; 445 typedef CFX_ArrayTemplate<int32_t> CFX_Int32Array; 446 #endif // PDF_ENABLE_XFA 447 448 template <class ObjectClass> 449 class CFX_ObjectArray : public CFX_BasicArray { 450 public: CFX_ObjectArray()451 CFX_ObjectArray() : CFX_BasicArray(sizeof(ObjectClass)) {} 452 ~CFX_ObjectArray()453 ~CFX_ObjectArray() { RemoveAll(); } 454 Add(const ObjectClass & data)455 void Add(const ObjectClass& data) { 456 new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(data); 457 } 458 Add()459 ObjectClass& Add() { 460 return *(ObjectClass*)new ((void*)InsertSpaceAt(m_nSize, 1)) ObjectClass(); 461 } 462 AddSpace()463 void* AddSpace() { return InsertSpaceAt(m_nSize, 1); } 464 465 int32_t Append(const CFX_ObjectArray& src, 466 int32_t nStart = 0, 467 int32_t nCount = -1) { 468 if (nCount == 0) { 469 return 0; 470 } 471 int32_t nSize = src.GetSize(); 472 if (!nSize) { 473 return 0; 474 } 475 FXSYS_assert(nStart > -1 && nStart < nSize); 476 if (nCount < 0) { 477 nCount = nSize; 478 } 479 if (nStart + nCount > nSize) { 480 nCount = nSize - nStart; 481 } 482 if (nCount < 1) { 483 return 0; 484 } 485 nSize = m_nSize; 486 InsertSpaceAt(m_nSize, nCount); 487 ObjectClass* pStartObj = (ObjectClass*)GetDataPtr(nSize); 488 nSize = nStart + nCount; 489 for (int32_t i = nStart; i < nSize; i++, pStartObj++) { 490 new ((void*)pStartObj) ObjectClass(src[i]); 491 } 492 return nCount; 493 } 494 495 int32_t Copy(const CFX_ObjectArray& src, 496 int32_t nStart = 0, 497 int32_t nCount = -1) { 498 if (nCount == 0) { 499 return 0; 500 } 501 int32_t nSize = src.GetSize(); 502 if (!nSize) { 503 return 0; 504 } 505 FXSYS_assert(nStart > -1 && nStart < nSize); 506 if (nCount < 0) { 507 nCount = nSize; 508 } 509 if (nStart + nCount > nSize) { 510 nCount = nSize - nStart; 511 } 512 if (nCount < 1) { 513 return 0; 514 } 515 RemoveAll(); 516 SetSize(nCount); 517 ObjectClass* pStartObj = (ObjectClass*)m_pData; 518 nSize = nStart + nCount; 519 for (int32_t i = nStart; i < nSize; i++, pStartObj++) { 520 new ((void*)pStartObj) ObjectClass(src[i]); 521 } 522 return nCount; 523 } 524 GetSize()525 int GetSize() const { return m_nSize; } 526 527 ObjectClass& operator[](int index) const { 528 FXSYS_assert(index < m_nSize); 529 return *(ObjectClass*)CFX_BasicArray::GetDataPtr(index); 530 } 531 GetDataPtr(int index)532 ObjectClass* GetDataPtr(int index) { 533 return (ObjectClass*)CFX_BasicArray::GetDataPtr(index); 534 } 535 RemoveAt(int index)536 void RemoveAt(int index) { 537 FXSYS_assert(index < m_nSize); 538 ((ObjectClass*)GetDataPtr(index))->~ObjectClass(); 539 CFX_BasicArray::RemoveAt(index, 1); 540 } 541 RemoveAll()542 void RemoveAll() { 543 for (int i = 0; i < m_nSize; i++) { 544 ((ObjectClass*)GetDataPtr(i))->~ObjectClass(); 545 } 546 CFX_BasicArray::SetSize(0); 547 } 548 }; 549 typedef CFX_ObjectArray<CFX_ByteString> CFX_ByteStringArray; 550 typedef CFX_ObjectArray<CFX_WideString> CFX_WideStringArray; 551 class CFX_BaseSegmentedArray { 552 public: 553 CFX_BaseSegmentedArray(int unit_size = 1, 554 int segment_units = 512, 555 int index_size = 8); 556 557 ~CFX_BaseSegmentedArray(); 558 559 void SetUnitSize(int unit_size, int segment_units, int index_size = 8); 560 561 void* Add(); 562 563 void* GetAt(int index) const; 564 565 void RemoveAll(); 566 567 void Delete(int index, int count = 1); 568 GetSize()569 int GetSize() const { return m_DataSize; } 570 GetSegmentSize()571 int GetSegmentSize() const { return m_SegmentSize; } 572 GetUnitSize()573 int GetUnitSize() const { return m_UnitSize; } 574 575 void* Iterate(FX_BOOL (*callback)(void* param, void* pData), 576 void* param) const; 577 578 private: 579 int m_UnitSize; 580 581 short m_SegmentSize; 582 583 uint8_t m_IndexSize; 584 585 uint8_t m_IndexDepth; 586 587 int m_DataSize; 588 589 void* m_pIndex; 590 void** GetIndex(int seg_index) const; 591 void* IterateIndex(int level, 592 int& start, 593 void** pIndex, 594 FX_BOOL (*callback)(void* param, void* pData), 595 void* param) const; 596 void* IterateSegment(const uint8_t* pSegment, 597 int count, 598 FX_BOOL (*callback)(void* param, void* pData), 599 void* param) const; 600 }; 601 template <class ElementType> 602 class CFX_SegmentedArray : public CFX_BaseSegmentedArray { 603 public: 604 CFX_SegmentedArray(int segment_units, int index_size = 8) CFX_BaseSegmentedArray(sizeof (ElementType),segment_units,index_size)605 : CFX_BaseSegmentedArray(sizeof(ElementType), segment_units, index_size) { 606 } 607 Add(ElementType data)608 void Add(ElementType data) { 609 *(ElementType*)CFX_BaseSegmentedArray::Add() = data; 610 } 611 612 ElementType& operator[](int index) { 613 return *(ElementType*)CFX_BaseSegmentedArray::GetAt(index); 614 } 615 }; 616 template <class DataType, int FixedSize> 617 class CFX_FixedBufGrow { 618 public: CFX_FixedBufGrow()619 CFX_FixedBufGrow() : m_pData(NULL) {} CFX_FixedBufGrow(int data_size)620 CFX_FixedBufGrow(int data_size) : m_pData(NULL) { 621 if (data_size > FixedSize) { 622 m_pData = FX_Alloc(DataType, data_size); 623 } else { 624 FXSYS_memset(m_Data, 0, sizeof(DataType) * FixedSize); 625 } 626 } SetDataSize(int data_size)627 void SetDataSize(int data_size) { 628 FX_Free(m_pData); 629 m_pData = NULL; 630 if (data_size > FixedSize) { 631 m_pData = FX_Alloc(DataType, data_size); 632 } else { 633 FXSYS_memset(m_Data, 0, sizeof(DataType) * FixedSize); 634 } 635 } ~CFX_FixedBufGrow()636 ~CFX_FixedBufGrow() { FX_Free(m_pData); } 637 operator DataType*() { return m_pData ? m_pData : m_Data; } 638 639 private: 640 DataType m_Data[FixedSize]; 641 DataType* m_pData; 642 }; 643 class CFX_MapPtrToPtr { 644 protected: 645 struct CAssoc { 646 CAssoc* pNext; 647 648 void* key; 649 650 void* value; 651 }; 652 653 public: 654 CFX_MapPtrToPtr(int nBlockSize = 10); 655 656 ~CFX_MapPtrToPtr(); 657 GetCount()658 int GetCount() const { return m_nCount; } 659 IsEmpty()660 FX_BOOL IsEmpty() const { return m_nCount == 0; } 661 662 FX_BOOL Lookup(void* key, void*& rValue) const; 663 664 void* GetValueAt(void* key) const; 665 666 void*& operator[](void* key); 667 SetAt(void * key,void * newValue)668 void SetAt(void* key, void* newValue) { (*this)[key] = newValue; } 669 670 FX_BOOL RemoveKey(void* key); 671 672 void RemoveAll(); 673 GetStartPosition()674 FX_POSITION GetStartPosition() const { 675 return (m_nCount == 0) ? NULL : (FX_POSITION)-1; 676 } 677 678 void GetNextAssoc(FX_POSITION& rNextPosition, 679 void*& rKey, 680 void*& rValue) const; 681 GetHashTableSize()682 FX_DWORD GetHashTableSize() const { return m_nHashTableSize; } 683 684 void InitHashTable(FX_DWORD hashSize, FX_BOOL bAllocNow = TRUE); 685 686 protected: 687 CAssoc** m_pHashTable; 688 689 FX_DWORD m_nHashTableSize; 690 691 int m_nCount; 692 693 CAssoc* m_pFreeList; 694 695 struct CFX_Plex* m_pBlocks; 696 697 int m_nBlockSize; 698 699 FX_DWORD HashKey(void* key) const; 700 701 CAssoc* NewAssoc(); 702 703 void FreeAssoc(CAssoc* pAssoc); 704 705 CAssoc* GetAssocAt(void* key, FX_DWORD& hash) const; 706 }; 707 #ifdef PDF_ENABLE_XFA 708 template <class KeyType, class ValueType> 709 class CFX_MapPtrTemplate : public CFX_MapPtrToPtr { 710 public: CFX_MapPtrTemplate()711 CFX_MapPtrTemplate() : CFX_MapPtrToPtr(10) {} 712 Lookup(KeyType key,ValueType & rValue)713 FX_BOOL Lookup(KeyType key, ValueType& rValue) const { 714 void* pValue = NULL; 715 if (!CFX_MapPtrToPtr::Lookup((void*)(uintptr_t)key, pValue)) { 716 return FALSE; 717 } 718 rValue = (ValueType)(uintptr_t)pValue; 719 return TRUE; 720 } 721 722 ValueType& operator[](KeyType key) { 723 return (ValueType&)CFX_MapPtrToPtr::operator[]((void*)(uintptr_t)key); 724 } 725 SetAt(KeyType key,ValueType newValue)726 void SetAt(KeyType key, ValueType newValue) { 727 CFX_MapPtrToPtr::SetAt((void*)(uintptr_t)key, (void*)(uintptr_t)newValue); 728 } 729 RemoveKey(KeyType key)730 FX_BOOL RemoveKey(KeyType key) { 731 return CFX_MapPtrToPtr::RemoveKey((void*)(uintptr_t)key); 732 } 733 GetNextAssoc(FX_POSITION & rNextPosition,KeyType & rKey,ValueType & rValue)734 void GetNextAssoc(FX_POSITION& rNextPosition, 735 KeyType& rKey, 736 ValueType& rValue) const { 737 void* pKey = NULL; 738 void* pValue = NULL; 739 CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue); 740 rKey = (KeyType)(uintptr_t)pKey; 741 rValue = (ValueType)(uintptr_t)pValue; 742 } 743 }; 744 #endif // PDF_ENABLE_XFA 745 class CFX_CMapByteStringToPtr { 746 public: 747 CFX_CMapByteStringToPtr(); 748 749 ~CFX_CMapByteStringToPtr(); 750 751 void RemoveAll(); 752 753 FX_POSITION GetStartPosition() const; 754 755 void GetNextAssoc(FX_POSITION& rNextPosition, 756 CFX_ByteString& rKey, 757 void*& rValue) const; 758 759 void* GetNextValue(FX_POSITION& rNextPosition) const; 760 761 FX_BOOL Lookup(const CFX_ByteStringC& key, void*& rValue) const; 762 763 void SetAt(const CFX_ByteStringC& key, void* value); 764 765 void RemoveKey(const CFX_ByteStringC& key); 766 767 int GetCount() const; 768 769 void AddValue(const CFX_ByteStringC& key, void* pValue); 770 771 private: 772 CFX_BaseSegmentedArray m_Buffer; 773 }; 774 class CFX_PtrList { 775 protected: 776 struct CNode { 777 CNode* pNext; 778 779 CNode* pPrev; 780 781 void* data; 782 }; 783 784 public: 785 CFX_PtrList(int nBlockSize = 10); 786 GetHeadPosition()787 FX_POSITION GetHeadPosition() const { return (FX_POSITION)m_pNodeHead; } 788 GetTailPosition()789 FX_POSITION GetTailPosition() const { return (FX_POSITION)m_pNodeTail; } 790 GetNext(FX_POSITION & rPosition)791 void* GetNext(FX_POSITION& rPosition) const { 792 CNode* pNode = (CNode*)rPosition; 793 rPosition = (FX_POSITION)pNode->pNext; 794 return pNode->data; 795 } 796 GetPrev(FX_POSITION & rPosition)797 void* GetPrev(FX_POSITION& rPosition) const { 798 CNode* pNode = (CNode*)rPosition; 799 rPosition = (FX_POSITION)pNode->pPrev; 800 return pNode->data; 801 } 802 GetNextPosition(FX_POSITION pos)803 FX_POSITION GetNextPosition(FX_POSITION pos) const { 804 return ((CNode*)pos)->pNext; 805 } 806 GetPrevPosition(FX_POSITION pos)807 FX_POSITION GetPrevPosition(FX_POSITION pos) const { 808 return ((CNode*)pos)->pPrev; 809 } 810 GetAt(FX_POSITION rPosition)811 void* GetAt(FX_POSITION rPosition) const { 812 CNode* pNode = (CNode*)rPosition; 813 return pNode->data; 814 } 815 GetCount()816 int GetCount() const { return m_nCount; } 817 818 FX_POSITION AddTail(void* newElement); 819 820 FX_POSITION AddHead(void* newElement); 821 SetAt(FX_POSITION pos,void * newElement)822 void SetAt(FX_POSITION pos, void* newElement) { 823 CNode* pNode = (CNode*)pos; 824 pNode->data = newElement; 825 } 826 827 FX_POSITION InsertAfter(FX_POSITION pos, void* newElement); 828 829 FX_POSITION Find(void* searchValue, FX_POSITION startAfter = NULL) const; 830 831 FX_POSITION FindIndex(int index) const; 832 833 void RemoveAt(FX_POSITION pos); 834 835 void RemoveAll(); 836 837 protected: 838 CNode* m_pNodeHead; 839 840 CNode* m_pNodeTail; 841 842 int m_nCount; 843 844 CNode* m_pNodeFree; 845 846 struct CFX_Plex* m_pBlocks; 847 848 int m_nBlockSize; 849 850 CNode* NewNode(CNode* pPrev, CNode* pNext); 851 852 void FreeNode(CNode* pNode); 853 854 public: 855 ~CFX_PtrList(); 856 }; 857 typedef void (*PD_CALLBACK_FREEDATA)(void* pData); 858 struct FX_PRIVATEDATA { 859 void FreeData(); 860 861 void* m_pModuleId; 862 863 void* m_pData; 864 865 PD_CALLBACK_FREEDATA m_pCallback; 866 867 FX_BOOL m_bSelfDestruct; 868 }; 869 class CFX_PrivateData { 870 public: 871 ~CFX_PrivateData(); 872 873 void ClearAll(); 874 875 void SetPrivateData(void* module_id, 876 void* pData, 877 PD_CALLBACK_FREEDATA callback); 878 879 void SetPrivateObj(void* module_id, CFX_DestructObject* pObj); 880 881 void* GetPrivateData(void* module_id); 882 LookupPrivateData(void * module_id,void * & pData)883 FX_BOOL LookupPrivateData(void* module_id, void*& pData) const { 884 if (!module_id) { 885 return FALSE; 886 } 887 FX_DWORD nCount = m_DataList.GetSize(); 888 for (FX_DWORD n = 0; n < nCount; n++) { 889 if (m_DataList[n].m_pModuleId == module_id) { 890 pData = m_DataList[n].m_pData; 891 return TRUE; 892 } 893 } 894 return FALSE; 895 } 896 897 FX_BOOL RemovePrivateData(void* module_id); 898 899 protected: 900 CFX_ArrayTemplate<FX_PRIVATEDATA> m_DataList; 901 902 void AddData(void* module_id, 903 void* pData, 904 PD_CALLBACK_FREEDATA callback, 905 FX_BOOL bSelfDestruct); 906 }; 907 class CFX_BitStream { 908 public: 909 void Init(const uint8_t* pData, FX_DWORD dwSize); 910 911 FX_DWORD GetBits(FX_DWORD nBits); 912 913 void ByteAlign(); 914 IsEOF()915 FX_BOOL IsEOF() { return m_BitPos >= m_BitSize; } 916 SkipBits(FX_DWORD nBits)917 void SkipBits(FX_DWORD nBits) { m_BitPos += nBits; } 918 Rewind()919 void Rewind() { m_BitPos = 0; } 920 GetPos()921 FX_DWORD GetPos() const { return m_BitPos; } 922 BitsRemaining()923 FX_DWORD BitsRemaining() const { 924 return m_BitSize >= m_BitPos ? m_BitSize - m_BitPos : 0; 925 } 926 927 protected: 928 FX_DWORD m_BitPos; 929 930 FX_DWORD m_BitSize; 931 932 const uint8_t* m_pData; 933 }; 934 template <class ObjClass> 935 class CFX_CountRef { 936 public: 937 typedef CFX_CountRef<ObjClass> Ref; 938 939 class CountedObj : public ObjClass { 940 public: CountedObj()941 CountedObj() {} 942 CountedObj(const CountedObj & src)943 CountedObj(const CountedObj& src) : ObjClass(src) {} 944 945 int m_RefCount; 946 }; 947 CFX_CountRef()948 CFX_CountRef() { m_pObject = NULL; } 949 CFX_CountRef(const Ref & ref)950 CFX_CountRef(const Ref& ref) { 951 m_pObject = ref.m_pObject; 952 if (m_pObject) { 953 m_pObject->m_RefCount++; 954 } 955 } 956 ~CFX_CountRef()957 ~CFX_CountRef() { 958 if (!m_pObject) { 959 return; 960 } 961 m_pObject->m_RefCount--; 962 if (m_pObject->m_RefCount <= 0) { 963 delete m_pObject; 964 } 965 } 966 New()967 ObjClass* New() { 968 if (m_pObject) { 969 m_pObject->m_RefCount--; 970 if (m_pObject->m_RefCount <= 0) { 971 delete m_pObject; 972 } 973 } 974 m_pObject = new CountedObj; 975 m_pObject->m_RefCount = 1; 976 return m_pObject; 977 } 978 979 void operator=(const Ref& ref) { 980 if (ref.m_pObject) { 981 ref.m_pObject->m_RefCount++; 982 } 983 if (m_pObject) { 984 m_pObject->m_RefCount--; 985 if (m_pObject->m_RefCount <= 0) { 986 delete m_pObject; 987 } 988 } 989 m_pObject = ref.m_pObject; 990 } 991 992 void operator=(void* p) { 993 FXSYS_assert(p == 0); 994 if (!m_pObject) { 995 return; 996 } 997 m_pObject->m_RefCount--; 998 if (m_pObject->m_RefCount <= 0) { 999 delete m_pObject; 1000 } 1001 m_pObject = NULL; 1002 } 1003 GetObject()1004 const ObjClass* GetObject() const { return m_pObject; } 1005 1006 operator const ObjClass*() const { return m_pObject; } 1007 IsNull()1008 FX_BOOL IsNull() const { return !m_pObject; } 1009 NotNull()1010 FX_BOOL NotNull() const { return !IsNull(); } 1011 GetModify()1012 ObjClass* GetModify() { 1013 if (!m_pObject) { 1014 m_pObject = new CountedObj; 1015 m_pObject->m_RefCount = 1; 1016 } else if (m_pObject->m_RefCount > 1) { 1017 m_pObject->m_RefCount--; 1018 CountedObj* pOldObject = m_pObject; 1019 m_pObject = new CountedObj(*pOldObject); 1020 m_pObject->m_RefCount = 1; 1021 } 1022 return m_pObject; 1023 } 1024 SetNull()1025 void SetNull() { 1026 if (!m_pObject) { 1027 return; 1028 } 1029 m_pObject->m_RefCount--; 1030 if (m_pObject->m_RefCount <= 0) { 1031 delete m_pObject; 1032 } 1033 m_pObject = NULL; 1034 } 1035 1036 FX_BOOL operator==(const Ref& ref) const { 1037 return m_pObject == ref.m_pObject; 1038 } 1039 1040 protected: 1041 CountedObj* m_pObject; 1042 }; 1043 class IFX_Pause { 1044 public: ~IFX_Pause()1045 virtual ~IFX_Pause() {} 1046 virtual FX_BOOL NeedToPauseNow() = 0; 1047 }; 1048 1049 template <typename T> 1050 class CFX_AutoRestorer { 1051 public: CFX_AutoRestorer(T * location)1052 explicit CFX_AutoRestorer(T* location) 1053 : m_Location(location), m_OldValue(*location) {} ~CFX_AutoRestorer()1054 ~CFX_AutoRestorer() { *m_Location = m_OldValue; } 1055 1056 private: 1057 T* const m_Location; 1058 const T m_OldValue; 1059 }; 1060 1061 struct FxFreeDeleter { operatorFxFreeDeleter1062 inline void operator()(void* ptr) const { FX_Free(ptr); } 1063 }; 1064 1065 // Used with std::unique_ptr to Release() objects that can't be deleted. 1066 template <class T> 1067 struct ReleaseDeleter { operatorReleaseDeleter1068 inline void operator()(T* ptr) const { ptr->Release(); } 1069 }; 1070 1071 #define FX_DATALIST_LENGTH 1024 1072 template <size_t unit> 1073 class CFX_SortListArray { 1074 protected: 1075 struct DataList { 1076 int32_t start; 1077 1078 int32_t count; 1079 uint8_t* data; 1080 }; 1081 1082 public: CFX_SortListArray()1083 CFX_SortListArray() : m_CurList(0) {} 1084 ~CFX_SortListArray()1085 ~CFX_SortListArray() { Clear(); } 1086 Clear()1087 void Clear() { 1088 for (int32_t i = m_DataLists.GetUpperBound(); i >= 0; i--) { 1089 DataList list = m_DataLists.ElementAt(i); 1090 FX_Free(list.data); 1091 } 1092 m_DataLists.RemoveAll(); 1093 m_CurList = 0; 1094 } 1095 Append(int32_t nStart,int32_t nCount)1096 void Append(int32_t nStart, int32_t nCount) { 1097 if (nStart < 0) { 1098 return; 1099 } 1100 while (nCount > 0) { 1101 int32_t temp_count = std::min(nCount, FX_DATALIST_LENGTH); 1102 DataList list; 1103 list.data = FX_Alloc2D(uint8_t, temp_count, unit); 1104 list.start = nStart; 1105 list.count = temp_count; 1106 Append(list); 1107 nCount -= temp_count; 1108 nStart += temp_count; 1109 } 1110 } 1111 GetAt(int32_t nIndex)1112 uint8_t* GetAt(int32_t nIndex) { 1113 if (nIndex < 0) { 1114 return NULL; 1115 } 1116 if (m_CurList < 0 || m_CurList >= m_DataLists.GetSize()) { 1117 return NULL; 1118 } 1119 DataList* pCurList = m_DataLists.GetDataPtr(m_CurList); 1120 if (!pCurList || nIndex < pCurList->start || 1121 nIndex >= pCurList->start + pCurList->count) { 1122 pCurList = NULL; 1123 int32_t iStart = 0; 1124 int32_t iEnd = m_DataLists.GetUpperBound(); 1125 int32_t iMid = 0; 1126 while (iStart <= iEnd) { 1127 iMid = (iStart + iEnd) / 2; 1128 DataList* list = m_DataLists.GetDataPtr(iMid); 1129 if (nIndex < list->start) { 1130 iEnd = iMid - 1; 1131 } else if (nIndex >= list->start + list->count) { 1132 iStart = iMid + 1; 1133 } else { 1134 pCurList = list; 1135 m_CurList = iMid; 1136 break; 1137 } 1138 } 1139 } 1140 return pCurList ? pCurList->data + (nIndex - pCurList->start) * unit : NULL; 1141 } 1142 1143 protected: Append(const DataList & list)1144 void Append(const DataList& list) { 1145 int32_t iStart = 0; 1146 int32_t iEnd = m_DataLists.GetUpperBound(); 1147 int32_t iFind = 0; 1148 while (iStart <= iEnd) { 1149 int32_t iMid = (iStart + iEnd) / 2; 1150 DataList* cur_list = m_DataLists.GetDataPtr(iMid); 1151 if (list.start < cur_list->start + cur_list->count) { 1152 iEnd = iMid - 1; 1153 } else { 1154 if (iMid == iEnd) { 1155 iFind = iMid + 1; 1156 break; 1157 } 1158 DataList* next_list = m_DataLists.GetDataPtr(iMid + 1); 1159 if (list.start < next_list->start) { 1160 iFind = iMid + 1; 1161 break; 1162 } else { 1163 iStart = iMid + 1; 1164 } 1165 } 1166 } 1167 m_DataLists.InsertAt(iFind, list); 1168 } 1169 int32_t m_CurList; 1170 CFX_ArrayTemplate<DataList> m_DataLists; 1171 }; 1172 template <typename T1, typename T2> 1173 class CFX_ListArrayTemplate { 1174 public: Clear()1175 void Clear() { m_Data.Clear(); } 1176 Add(int32_t nStart,int32_t nCount)1177 void Add(int32_t nStart, int32_t nCount) { m_Data.Append(nStart, nCount); } 1178 1179 T2& operator[](int32_t nIndex) { 1180 uint8_t* data = m_Data.GetAt(nIndex); 1181 FXSYS_assert(data); 1182 return (T2&)(*(volatile T2*)data); 1183 } 1184 GetPtrAt(int32_t nIndex)1185 T2* GetPtrAt(int32_t nIndex) { return (T2*)m_Data.GetAt(nIndex); } 1186 1187 protected: 1188 T1 m_Data; 1189 }; 1190 typedef CFX_ListArrayTemplate<CFX_SortListArray<sizeof(FX_FILESIZE)>, 1191 FX_FILESIZE> CFX_FileSizeListArray; 1192 1193 typedef enum { 1194 Ready, 1195 ToBeContinued, 1196 Found, 1197 NotFound, 1198 Failed, 1199 Done 1200 } FX_ProgressiveStatus; 1201 #define ProgressiveStatus FX_ProgressiveStatus 1202 #ifdef PDF_ENABLE_XFA 1203 class IFX_Unknown { 1204 public: ~IFX_Unknown()1205 virtual ~IFX_Unknown() {} 1206 virtual FX_DWORD Release() = 0; 1207 virtual FX_DWORD AddRef() = 0; 1208 }; 1209 #define FX_IsOdd(a) ((a)&1) 1210 #endif // PDF_ENABLE_XFA 1211 1212 class CFX_Vector_3by1 { 1213 public: CFX_Vector_3by1()1214 CFX_Vector_3by1() : a(0.0f), b(0.0f), c(0.0f) {} 1215 CFX_Vector_3by1(FX_FLOAT a1,FX_FLOAT b1,FX_FLOAT c1)1216 CFX_Vector_3by1(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1) 1217 : a(a1), b(b1), c(c1) {} 1218 1219 FX_FLOAT a; 1220 FX_FLOAT b; 1221 FX_FLOAT c; 1222 }; 1223 class CFX_Matrix_3by3 { 1224 public: CFX_Matrix_3by3()1225 CFX_Matrix_3by3() 1226 : a(0.0f), 1227 b(0.0f), 1228 c(0.0f), 1229 d(0.0f), 1230 e(0.0f), 1231 f(0.0f), 1232 g(0.0f), 1233 h(0.0f), 1234 i(0.0f) {} 1235 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)1236 CFX_Matrix_3by3(FX_FLOAT a1, 1237 FX_FLOAT b1, 1238 FX_FLOAT c1, 1239 FX_FLOAT d1, 1240 FX_FLOAT e1, 1241 FX_FLOAT f1, 1242 FX_FLOAT g1, 1243 FX_FLOAT h1, 1244 FX_FLOAT i1) 1245 : a(a1), b(b1), c(c1), d(d1), e(e1), f(f1), g(g1), h(h1), i(i1) {} 1246 1247 CFX_Matrix_3by3 Inverse(); 1248 1249 CFX_Matrix_3by3 Multiply(const CFX_Matrix_3by3& m); 1250 1251 CFX_Vector_3by1 TransformVector(const CFX_Vector_3by1& v); 1252 1253 FX_FLOAT a; 1254 FX_FLOAT b; 1255 FX_FLOAT c; 1256 FX_FLOAT d; 1257 FX_FLOAT e; 1258 FX_FLOAT f; 1259 FX_FLOAT g; 1260 FX_FLOAT h; 1261 FX_FLOAT i; 1262 }; 1263 1264 #endif // CORE_INCLUDE_FXCRT_FX_BASIC_H_ 1265