1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../include/fxcrt/fx_basic.h"
8 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
9 CFX_BinaryBuf::CFX_BinaryBuf()
16 CFX_BinaryBuf::CFX_BinaryBuf(FX_STRSIZE size)
21 m_pBuffer = FX_Alloc(FX_BYTE, size);
23 CFX_BinaryBuf::~CFX_BinaryBuf()
29 void CFX_BinaryBuf::Delete(int start_index, int count)
31 if (!m_pBuffer || start_index < 0 || start_index + count > m_DataSize) {
34 FXSYS_memmove32(m_pBuffer + start_index, m_pBuffer + start_index + count, m_DataSize - start_index - count);
37 void CFX_BinaryBuf::Clear()
41 void CFX_BinaryBuf::DetachBuffer()
47 void CFX_BinaryBuf::AttachData(void* buffer, FX_STRSIZE size)
53 m_pBuffer = (FX_LPBYTE)buffer;
56 void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other)
58 AttachData(other.GetBuffer(), other.GetSize());
61 void CFX_BinaryBuf::EstimateSize(FX_STRSIZE size, FX_STRSIZE step)
64 if (m_AllocSize >= size) {
67 ExpandBuf(size - m_DataSize);
69 void CFX_BinaryBuf::ExpandBuf(FX_STRSIZE add_size)
71 FX_STRSIZE new_size = add_size + m_DataSize;
72 if (m_AllocSize >= new_size) {
76 if (m_AllocStep == 0) {
77 alloc_step = m_AllocSize / 4;
78 if (alloc_step < 128 ) {
82 alloc_step = m_AllocStep;
84 new_size = (new_size + alloc_step - 1) / alloc_step * alloc_step;
85 FX_LPBYTE pNewBuffer = m_pBuffer;
87 pNewBuffer = FX_Realloc(FX_BYTE, m_pBuffer, new_size);
89 pNewBuffer = FX_Alloc(FX_BYTE, new_size);
92 m_pBuffer = pNewBuffer;
93 m_AllocSize = new_size;
96 void CFX_BinaryBuf::CopyData(const void* pStr, FX_STRSIZE size)
102 if (m_AllocSize < size) {
103 ExpandBuf(size - m_DataSize);
108 FXSYS_memcpy32(m_pBuffer, pStr, size);
111 void CFX_BinaryBuf::AppendBlock(const void* pBuf, FX_STRSIZE size)
114 if (pBuf && m_pBuffer) {
115 FXSYS_memcpy32(m_pBuffer + m_DataSize, pBuf, size);
119 void CFX_BinaryBuf::InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size)
125 FXSYS_memmove32(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos);
127 FXSYS_memcpy32(m_pBuffer + pos, pBuf, size);
131 void CFX_BinaryBuf::AppendFill(FX_BYTE byte, FX_STRSIZE count)
137 FXSYS_memset8(m_pBuffer + m_DataSize, byte, count);
140 CFX_ByteStringC CFX_BinaryBuf::GetByteString() const
142 return CFX_ByteStringC(m_pBuffer, m_DataSize);
144 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz)
146 AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
149 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (int i)
152 FXSYS_itoa(i, buf, 10);
153 AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
156 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_DWORD i)
159 FXSYS_itoa(i, buf, 10);
160 AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
163 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (double f)
166 FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
167 AppendBlock(buf, len);
170 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf)
172 AppendBlock(buf.m_pBuffer, buf.m_DataSize);
175 void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str)
177 CopyData((FX_LPCBYTE)str, str.GetLength());
179 void CFX_WideTextBuf::AppendChar(FX_WCHAR ch)
181 if (m_AllocSize < m_DataSize + (FX_STRSIZE)sizeof(FX_WCHAR)) {
182 ExpandBuf(sizeof(FX_WCHAR));
184 ASSERT(m_pBuffer != NULL);
185 *(FX_WCHAR*)(m_pBuffer + m_DataSize) = ch;
186 m_DataSize += sizeof(FX_WCHAR);
188 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str)
190 AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
193 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str)
195 AppendBlock((FX_LPCWSTR)str, str.GetLength() * sizeof(FX_WCHAR));
198 CFX_WideTextBuf& CFX_WideTextBuf::operator << (int i)
201 FXSYS_itoa(i, buf, 10);
202 FX_STRSIZE len = (FX_STRSIZE)FXSYS_strlen(buf);
203 if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
204 ExpandBuf(len * sizeof(FX_WCHAR));
206 ASSERT(m_pBuffer != NULL);
207 FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
208 for (FX_STRSIZE j = 0; j < len; j ++) {
211 m_DataSize += len * sizeof(FX_WCHAR);
214 CFX_WideTextBuf& CFX_WideTextBuf::operator << (double f)
217 FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
218 if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
219 ExpandBuf(len * sizeof(FX_WCHAR));
221 ASSERT(m_pBuffer != NULL);
222 FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
223 for (FX_STRSIZE i = 0; i < len; i ++) {
226 m_DataSize += len * sizeof(FX_WCHAR);
229 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz)
231 AppendBlock(lpsz, (FX_STRSIZE)FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR));
234 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf)
236 AppendBlock(buf.m_pBuffer, buf.m_DataSize);
239 void CFX_WideTextBuf::operator =(FX_WSTR str)
241 CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
243 CFX_WideStringC CFX_WideTextBuf::GetWideString() const
245 return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
247 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BYTE i)
250 m_pStream->WriteBlock(&i, 1);
252 m_SavingBuf.AppendByte(i);
256 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (int i)
259 m_pStream->WriteBlock(&i, sizeof(int));
261 m_SavingBuf.AppendBlock(&i, sizeof(int));
265 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_DWORD i)
268 m_pStream->WriteBlock(&i, sizeof(FX_DWORD));
270 m_SavingBuf.AppendBlock(&i, sizeof(FX_DWORD));
274 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_FLOAT f)
277 m_pStream->WriteBlock(&f, sizeof(FX_FLOAT));
279 m_SavingBuf.AppendBlock(&f, sizeof(FX_FLOAT));
283 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BSTR bstr)
285 int len = bstr.GetLength();
287 m_pStream->WriteBlock(&len, sizeof(int));
288 m_pStream->WriteBlock(bstr, len);
290 m_SavingBuf.AppendBlock(&len, sizeof(int));
291 m_SavingBuf.AppendBlock(bstr, len);
295 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_LPCWSTR wstr)
297 FX_STRSIZE len = (FX_STRSIZE)FXSYS_wcslen(wstr);
299 m_pStream->WriteBlock(&len, sizeof(int));
300 m_pStream->WriteBlock(wstr, len);
302 m_SavingBuf.AppendBlock(&len, sizeof(int));
303 m_SavingBuf.AppendBlock(wstr, len);
307 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr)
309 CFX_ByteString encoded = wstr.UTF16LE_Encode();
310 return operator << (encoded);
312 void CFX_ArchiveSaver::Write(const void* pData, FX_STRSIZE dwSize)
315 m_pStream->WriteBlock(pData, dwSize);
317 m_SavingBuf.AppendBlock(pData, dwSize);
320 CFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize)
322 m_pLoadingBuf = pData;
324 m_LoadingSize = dwSize;
326 FX_BOOL CFX_ArchiveLoader::IsEOF()
328 return m_LoadingPos >= m_LoadingSize;
330 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_BYTE& i)
332 if (m_LoadingPos >= m_LoadingSize) {
335 i = m_pLoadingBuf[m_LoadingPos++];
338 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i)
340 Read(&i, sizeof(int));
343 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i)
345 Read(&i, sizeof(FX_DWORD));
348 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i)
350 Read(&i, sizeof(FX_FLOAT));
353 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_ByteString& str)
355 if (m_LoadingPos + 4 > m_LoadingSize) {
361 if (len <= 0 || m_LoadingPos + len > m_LoadingSize) {
364 FX_LPSTR buffer = str.GetBuffer(len);
365 FXSYS_memcpy32(buffer, m_pLoadingBuf + m_LoadingPos, len);
366 str.ReleaseBuffer(len);
370 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_WideString& str)
372 CFX_ByteString encoded;
373 operator >> (encoded);
374 str = CFX_WideString::FromUTF16LE((const unsigned short*)(FX_LPCSTR)encoded, encoded.GetLength());
377 FX_BOOL CFX_ArchiveLoader::Read(void* pBuf, FX_DWORD dwSize)
379 if (m_LoadingPos + dwSize > m_LoadingSize) {
382 FXSYS_memcpy32(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize);
383 m_LoadingPos += dwSize;
386 void CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize)
389 m_BitSize = dwSize * 8;
392 void CFX_BitStream::ByteAlign()
394 int mod = m_BitPos % 8;
400 FX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits)
402 if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) {
406 int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0;
410 FX_DWORD byte_pos = m_BitPos / 8;
411 FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits;
414 if (8 - bit_pos >= bit_left) {
415 result = (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left);
416 m_BitPos += bit_left;
419 bit_left -= 8 - bit_pos;
420 result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
422 while (bit_left >= 8) {
424 result |= m_pData[byte_pos++] << bit_left;
427 result |= m_pData[byte_pos] >> (8 - bit_left);
432 IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size)
438 void IFX_BufferArchive::Clear()
446 FX_BOOL IFX_BufferArchive::Flush()
448 FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
452 FX_INT32 IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size)
454 if (!pBuf || size < 1) {
458 m_pBuffer = FX_Alloc(FX_BYTE, m_BufSize);
463 FX_LPBYTE buffer = (FX_LPBYTE)pBuf;
464 FX_STRSIZE temp_size = (FX_STRSIZE)size;
465 while (temp_size > 0) {
466 FX_STRSIZE buf_size = FX_MIN(m_BufSize - m_Length, (FX_STRSIZE)temp_size);
467 FXSYS_memcpy32(m_pBuffer + m_Length, buffer, buf_size);
468 m_Length += buf_size;
469 if (m_Length == m_BufSize) {
474 temp_size -= buf_size;
477 return (FX_INT32)size;
479 FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte)
481 return AppendBlock(&byte, 1);
483 FX_INT32 IFX_BufferArchive::AppendDWord(FX_DWORD i)
486 FXSYS_itoa(i, buf, 10);
487 return AppendBlock(buf, (size_t)FXSYS_strlen(buf));
489 FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz)
491 return AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
493 CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size)
494 : IFX_BufferArchive(size)
499 CFX_FileBufferArchive::~CFX_FileBufferArchive()
503 void CFX_FileBufferArchive::Clear()
505 if (m_pFile && m_bTakeover) {
510 IFX_BufferArchive::Clear();
512 FX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover )
517 if (m_pFile && m_bTakeover) {
521 m_bTakeover = bTakeover;
524 FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCWSTR filename)
529 if (m_pFile && m_bTakeover) {
532 m_pFile = FX_CreateFileWrite(filename);
539 FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCSTR filename)
544 if (m_pFile && m_bTakeover) {
547 m_pFile = FX_CreateFileWrite(filename);
554 FX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size)
559 if (!pBuf || size < 1) {
562 return m_pFile->WriteBlock(pBuf, size);