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