Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../include/fxcrt/fx_basic.h"
      8 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
      9 CFX_BinaryBuf::CFX_BinaryBuf(IFX_Allocator* pAllocator)
     10     : m_pAllocator(pAllocator)
     11     , m_AllocStep(0)
     12     , m_pBuffer(NULL)
     13     , m_DataSize(0)
     14     , m_AllocSize(0)
     15 {
     16 }
     17 CFX_BinaryBuf::CFX_BinaryBuf(FX_STRSIZE size, IFX_Allocator* pAllocator)
     18     : m_pAllocator(pAllocator)
     19     , m_AllocStep(0)
     20     , m_DataSize(size)
     21     , m_AllocSize(size)
     22 {
     23     m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, size);
     24 }
     25 CFX_BinaryBuf::~CFX_BinaryBuf()
     26 {
     27     if (m_pBuffer) {
     28         FX_Allocator_Free(m_pAllocator, m_pBuffer);
     29     }
     30 }
     31 void CFX_BinaryBuf::Delete(int start_index, int count)
     32 {
     33     if (!m_pBuffer || start_index < 0 || start_index + count > m_DataSize) {
     34         return;
     35     }
     36     FXSYS_memmove32(m_pBuffer + start_index, m_pBuffer + start_index + count, m_DataSize - start_index - count);
     37     m_DataSize -= count;
     38 }
     39 void CFX_BinaryBuf::Clear()
     40 {
     41     m_DataSize = 0;
     42 }
     43 void CFX_BinaryBuf::DetachBuffer()
     44 {
     45     m_DataSize = 0;
     46     m_pBuffer = NULL;
     47     m_AllocSize = 0;
     48 }
     49 void CFX_BinaryBuf::AttachData(void* buffer, FX_STRSIZE size)
     50 {
     51     if (m_pBuffer) {
     52         FX_Allocator_Free(m_pAllocator, m_pBuffer);
     53     }
     54     m_DataSize = size;
     55     m_pBuffer = (FX_LPBYTE)buffer;
     56     m_AllocSize = size;
     57 }
     58 void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other)
     59 {
     60     AttachData(other.GetBuffer(), other.GetSize());
     61     other.DetachBuffer();
     62 }
     63 void CFX_BinaryBuf::EstimateSize(FX_STRSIZE size, FX_STRSIZE step)
     64 {
     65     m_AllocStep = step;
     66     if (m_AllocSize >= size) {
     67         return;
     68     }
     69     ExpandBuf(size - m_DataSize);
     70 }
     71 void CFX_BinaryBuf::ExpandBuf(FX_STRSIZE add_size)
     72 {
     73     FX_STRSIZE new_size = add_size + m_DataSize;
     74     if (m_AllocSize >= new_size) {
     75         return;
     76     }
     77     int alloc_step;
     78     if (m_AllocStep == 0) {
     79         alloc_step = m_AllocSize / 4;
     80         if (alloc_step < 128 ) {
     81             alloc_step = 128;
     82         }
     83     } else {
     84         alloc_step = m_AllocStep;
     85     }
     86     new_size = (new_size + alloc_step - 1) / alloc_step * alloc_step;
     87     FX_LPBYTE pNewBuffer = m_pBuffer;
     88     if (pNewBuffer) {
     89         pNewBuffer = FX_Allocator_Realloc(m_pAllocator, FX_BYTE, m_pBuffer, new_size);
     90     } else {
     91         pNewBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, new_size);
     92     }
     93     if (pNewBuffer) {
     94         m_pBuffer = pNewBuffer;
     95         m_AllocSize = new_size;
     96     }
     97 }
     98 void CFX_BinaryBuf::CopyData(const void* pStr, FX_STRSIZE size)
     99 {
    100     if (size == 0) {
    101         m_DataSize = 0;
    102         return;
    103     }
    104     if (m_AllocSize < size) {
    105         ExpandBuf(size - m_DataSize);
    106     }
    107     if (!m_pBuffer) {
    108         return;
    109     }
    110     FXSYS_memcpy32(m_pBuffer, pStr, size);
    111     m_DataSize = size;
    112 }
    113 void CFX_BinaryBuf::AppendBlock(const void* pBuf, FX_STRSIZE size)
    114 {
    115     ExpandBuf(size);
    116     if (pBuf && m_pBuffer) {
    117         FXSYS_memcpy32(m_pBuffer + m_DataSize, pBuf, size);
    118     }
    119     m_DataSize += size;
    120 }
    121 void CFX_BinaryBuf::InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size)
    122 {
    123     ExpandBuf(size);
    124     if (!m_pBuffer) {
    125         return;
    126     }
    127     FXSYS_memmove32(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos);
    128     if (pBuf) {
    129         FXSYS_memcpy32(m_pBuffer + pos, pBuf, size);
    130     }
    131     m_DataSize += size;
    132 }
    133 void CFX_BinaryBuf::AppendFill(FX_BYTE byte, FX_STRSIZE count)
    134 {
    135     ExpandBuf(count);
    136     if (!m_pBuffer) {
    137         return;
    138     }
    139     FXSYS_memset8(m_pBuffer + m_DataSize, byte, count);
    140     m_DataSize += count;
    141 }
    142 CFX_ByteStringC CFX_BinaryBuf::GetByteString() const
    143 {
    144     return CFX_ByteStringC(m_pBuffer, m_DataSize);
    145 }
    146 void CFX_BinaryBuf::GetByteStringL(CFX_ByteStringL &str) const
    147 {
    148     str.Set(CFX_ByteStringC(m_pBuffer, m_DataSize), m_pAllocator);
    149 }
    150 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz)
    151 {
    152     AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
    153     return *this;
    154 }
    155 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (int i)
    156 {
    157     char buf[32];
    158     FXSYS_itoa(i, buf, 10);
    159     AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
    160     return *this;
    161 }
    162 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_DWORD i)
    163 {
    164     char buf[32];
    165     FXSYS_itoa(i, buf, 10);
    166     AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
    167     return *this;
    168 }
    169 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (double f)
    170 {
    171     char buf[32];
    172     FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
    173     AppendBlock(buf, len);
    174     return *this;
    175 }
    176 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf)
    177 {
    178     AppendBlock(buf.m_pBuffer, buf.m_DataSize);
    179     return *this;
    180 }
    181 void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str)
    182 {
    183     CopyData((FX_LPCBYTE)str, str.GetLength());
    184 }
    185 void CFX_WideTextBuf::AppendChar(FX_WCHAR ch)
    186 {
    187     if (m_AllocSize < m_DataSize + (FX_STRSIZE)sizeof(FX_WCHAR)) {
    188         ExpandBuf(sizeof(FX_WCHAR));
    189     }
    190     ASSERT(m_pBuffer != NULL);
    191     *(FX_WCHAR*)(m_pBuffer + m_DataSize) = ch;
    192     m_DataSize += sizeof(FX_WCHAR);
    193 }
    194 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str)
    195 {
    196     AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
    197     return *this;
    198 }
    199 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str)
    200 {
    201     AppendBlock((FX_LPCWSTR)str, str.GetLength() * sizeof(FX_WCHAR));
    202     return *this;
    203 }
    204 CFX_WideTextBuf& CFX_WideTextBuf::operator << (int i)
    205 {
    206     char buf[32];
    207     FXSYS_itoa(i, buf, 10);
    208     FX_STRSIZE len = (FX_STRSIZE)FXSYS_strlen(buf);
    209     if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
    210         ExpandBuf(len * sizeof(FX_WCHAR));
    211     }
    212     ASSERT(m_pBuffer != NULL);
    213     FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
    214     for (FX_STRSIZE j = 0; j < len; j ++) {
    215         *str ++ = buf[j];
    216     }
    217     m_DataSize += len * sizeof(FX_WCHAR);
    218     return *this;
    219 }
    220 CFX_WideTextBuf& CFX_WideTextBuf::operator << (double f)
    221 {
    222     char buf[32];
    223     FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
    224     if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
    225         ExpandBuf(len * sizeof(FX_WCHAR));
    226     }
    227     ASSERT(m_pBuffer != NULL);
    228     FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
    229     for (FX_STRSIZE i = 0; i < len; i ++) {
    230         *str ++ = buf[i];
    231     }
    232     m_DataSize += len * sizeof(FX_WCHAR);
    233     return *this;
    234 }
    235 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz)
    236 {
    237     AppendBlock(lpsz, (FX_STRSIZE)FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR));
    238     return *this;
    239 }
    240 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf)
    241 {
    242     AppendBlock(buf.m_pBuffer, buf.m_DataSize);
    243     return *this;
    244 }
    245 void CFX_WideTextBuf::operator =(FX_WSTR str)
    246 {
    247     CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
    248 }
    249 CFX_WideStringC CFX_WideTextBuf::GetWideString() const
    250 {
    251     return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
    252 }
    253 void CFX_WideTextBuf::GetWideStringL(CFX_WideStringL& wideText) const
    254 {
    255     wideText.Set(CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR)), m_pAllocator);
    256 }
    257 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BYTE i)
    258 {
    259     if (m_pStream) {
    260         m_pStream->WriteBlock(&i, 1);
    261     } else {
    262         m_SavingBuf.AppendByte(i);
    263     }
    264     return *this;
    265 }
    266 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (int i)
    267 {
    268     if (m_pStream) {
    269         m_pStream->WriteBlock(&i, sizeof(int));
    270     } else {
    271         m_SavingBuf.AppendBlock(&i, sizeof(int));
    272     }
    273     return *this;
    274 }
    275 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_DWORD i)
    276 {
    277     if (m_pStream) {
    278         m_pStream->WriteBlock(&i, sizeof(FX_DWORD));
    279     } else {
    280         m_SavingBuf.AppendBlock(&i, sizeof(FX_DWORD));
    281     }
    282     return *this;
    283 }
    284 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_FLOAT f)
    285 {
    286     if (m_pStream) {
    287         m_pStream->WriteBlock(&f, sizeof(FX_FLOAT));
    288     } else {
    289         m_SavingBuf.AppendBlock(&f, sizeof(FX_FLOAT));
    290     }
    291     return *this;
    292 }
    293 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BSTR bstr)
    294 {
    295     int len = bstr.GetLength();
    296     if (m_pStream) {
    297         m_pStream->WriteBlock(&len, sizeof(int));
    298         m_pStream->WriteBlock(bstr, len);
    299     } else {
    300         m_SavingBuf.AppendBlock(&len, sizeof(int));
    301         m_SavingBuf.AppendBlock(bstr, len);
    302     }
    303     return *this;
    304 }
    305 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_LPCWSTR wstr)
    306 {
    307     FX_STRSIZE len = (FX_STRSIZE)FXSYS_wcslen(wstr);
    308     if (m_pStream) {
    309         m_pStream->WriteBlock(&len, sizeof(int));
    310         m_pStream->WriteBlock(wstr, len);
    311     } else {
    312         m_SavingBuf.AppendBlock(&len, sizeof(int));
    313         m_SavingBuf.AppendBlock(wstr, len);
    314     }
    315     return *this;
    316 }
    317 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr)
    318 {
    319     CFX_ByteString encoded = wstr.UTF16LE_Encode();
    320     return operator << (encoded);
    321 }
    322 void CFX_ArchiveSaver::Write(const void* pData, FX_STRSIZE dwSize)
    323 {
    324     if (m_pStream) {
    325         m_pStream->WriteBlock(pData, dwSize);
    326     } else {
    327         m_SavingBuf.AppendBlock(pData, dwSize);
    328     }
    329 }
    330 CFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize)
    331 {
    332     m_pLoadingBuf = pData;
    333     m_LoadingPos = 0;
    334     m_LoadingSize = dwSize;
    335 }
    336 FX_BOOL CFX_ArchiveLoader::IsEOF()
    337 {
    338     return m_LoadingPos >= m_LoadingSize;
    339 }
    340 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_BYTE& i)
    341 {
    342     if (m_LoadingPos >= m_LoadingSize) {
    343         return *this;
    344     }
    345     i = m_pLoadingBuf[m_LoadingPos++];
    346     return *this;
    347 }
    348 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i)
    349 {
    350     Read(&i, sizeof(int));
    351     return *this;
    352 }
    353 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i)
    354 {
    355     Read(&i, sizeof(FX_DWORD));
    356     return *this;
    357 }
    358 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i)
    359 {
    360     Read(&i, sizeof(FX_FLOAT));
    361     return *this;
    362 }
    363 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_ByteString& str)
    364 {
    365     if (m_LoadingPos + 4 > m_LoadingSize) {
    366         return *this;
    367     }
    368     int len;
    369     operator >> (len);
    370     str.Empty();
    371     if (len <= 0 || m_LoadingPos + len > m_LoadingSize) {
    372         return *this;
    373     }
    374     FX_LPSTR buffer = str.GetBuffer(len);
    375     FXSYS_memcpy32(buffer, m_pLoadingBuf + m_LoadingPos, len);
    376     str.ReleaseBuffer(len);
    377     m_LoadingPos += len;
    378     return *this;
    379 }
    380 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_WideString& str)
    381 {
    382     CFX_ByteString encoded;
    383     operator >> (encoded);
    384     str = CFX_WideString::FromUTF16LE((const unsigned short*)(FX_LPCSTR)encoded, encoded.GetLength());
    385     return *this;
    386 }
    387 FX_BOOL CFX_ArchiveLoader::Read(void* pBuf, FX_DWORD dwSize)
    388 {
    389     if (m_LoadingPos + dwSize > m_LoadingSize) {
    390         return FALSE;
    391     }
    392     FXSYS_memcpy32(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize);
    393     m_LoadingPos += dwSize;
    394     return TRUE;
    395 }
    396 void CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize)
    397 {
    398     m_pData = pData;
    399     m_BitSize = dwSize * 8;
    400     m_BitPos = 0;
    401 }
    402 void CFX_BitStream::ByteAlign()
    403 {
    404     int mod = m_BitPos % 8;
    405     if (mod == 0) {
    406         return;
    407     }
    408     m_BitPos += 8 - mod;
    409 }
    410 FX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits)
    411 {
    412     if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) {
    413         return 0;
    414     }
    415     if (nBits == 1) {
    416         int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0;
    417         m_BitPos ++;
    418         return bit;
    419     }
    420     FX_DWORD byte_pos = m_BitPos / 8;
    421     FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits;
    422     FX_DWORD result = 0;
    423     if (bit_pos) {
    424         if (8 - bit_pos >= bit_left) {
    425             result = (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left);
    426             m_BitPos += bit_left;
    427             return result;
    428         }
    429         bit_left -= 8 - bit_pos;
    430         result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
    431     }
    432     while (bit_left >= 8) {
    433         bit_left -= 8;
    434         result |= m_pData[byte_pos++] << bit_left;
    435     }
    436     if (bit_left) {
    437         result |= m_pData[byte_pos] >> (8 - bit_left);
    438     }
    439     m_BitPos += nBits;
    440     return result;
    441 }
    442 IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator)
    443     : m_pAllocator(pAllocator)
    444     , m_BufSize(size)
    445     , m_pBuffer(NULL)
    446     , m_Length(0)
    447 {
    448 }
    449 void IFX_BufferArchive::Clear()
    450 {
    451     m_Length = 0;
    452     if (m_pBuffer) {
    453         FX_Allocator_Free(m_pAllocator, m_pBuffer);
    454         m_pBuffer = NULL;
    455     }
    456 }
    457 FX_BOOL IFX_BufferArchive::Flush()
    458 {
    459     FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
    460     m_Length = 0;
    461     return bRet;
    462 }
    463 FX_INT32 IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size)
    464 {
    465     if (!pBuf || size < 1) {
    466         return 0;
    467     }
    468     if (!m_pBuffer) {
    469         m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, m_BufSize);
    470         if (!m_pBuffer) {
    471             return -1;
    472         }
    473     }
    474     FX_LPBYTE buffer = (FX_LPBYTE)pBuf;
    475     FX_STRSIZE temp_size = (FX_STRSIZE)size;
    476     while (temp_size > 0) {
    477         FX_STRSIZE buf_size = FX_MIN(m_BufSize - m_Length, (FX_STRSIZE)temp_size);
    478         FXSYS_memcpy32(m_pBuffer + m_Length, buffer, buf_size);
    479         m_Length += buf_size;
    480         if (m_Length == m_BufSize) {
    481             if (!Flush()) {
    482                 return -1;
    483             }
    484         }
    485         temp_size -= buf_size;
    486         buffer += buf_size;
    487     }
    488     return (FX_INT32)size;
    489 }
    490 FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte)
    491 {
    492     return AppendBlock(&byte, 1);
    493 }
    494 FX_INT32 IFX_BufferArchive::AppendDWord(FX_DWORD i)
    495 {
    496     char buf[32];
    497     FXSYS_itoa(i, buf, 10);
    498     return AppendBlock(buf, (size_t)FXSYS_strlen(buf));
    499 }
    500 FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz)
    501 {
    502     return AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
    503 }
    504 CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator)
    505     : IFX_BufferArchive(size, pAllocator)
    506     , m_pFile(NULL)
    507     , m_bTakeover(FALSE)
    508 {
    509 }
    510 CFX_FileBufferArchive::~CFX_FileBufferArchive()
    511 {
    512     Clear();
    513 }
    514 void CFX_FileBufferArchive::Clear()
    515 {
    516     if (m_pFile && m_bTakeover) {
    517         m_pFile->Release();
    518     }
    519     m_pFile = NULL;
    520     m_bTakeover = FALSE;
    521     IFX_BufferArchive::Clear();
    522 }
    523 FX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover )
    524 {
    525     if (!pFile) {
    526         return FALSE;
    527     }
    528     if (m_pFile && m_bTakeover) {
    529         m_pFile->Release();
    530     }
    531     m_pFile = pFile;
    532     m_bTakeover = bTakeover;
    533     return TRUE;
    534 }
    535 FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCWSTR filename)
    536 {
    537     if (!filename) {
    538         return FALSE;
    539     }
    540     if (m_pFile && m_bTakeover) {
    541         m_pFile->Release();
    542     }
    543     m_pFile = FX_CreateFileWrite(filename);
    544     if (!m_pFile) {
    545         return FALSE;
    546     }
    547     m_bTakeover = TRUE;
    548     return TRUE;
    549 }
    550 FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCSTR filename)
    551 {
    552     if (!filename) {
    553         return FALSE;
    554     }
    555     if (m_pFile && m_bTakeover) {
    556         m_pFile->Release();
    557     }
    558     m_pFile = FX_CreateFileWrite(filename);
    559     if (!m_pFile) {
    560         return FALSE;
    561     }
    562     m_bTakeover = TRUE;
    563     return TRUE;
    564 }
    565 FX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size)
    566 {
    567     if (!m_pFile) {
    568         return FALSE;
    569     }
    570     if (!pBuf || size < 1) {
    571         return TRUE;
    572     }
    573     return m_pFile->WriteBlock(pBuf, size);
    574 }
    575