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" 8FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf); 9CFX_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} 17CFX_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} 25CFX_BinaryBuf::~CFX_BinaryBuf() 26{ 27 if (m_pBuffer) { 28 FX_Allocator_Free(m_pAllocator, m_pBuffer); 29 } 30} 31void 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} 39void CFX_BinaryBuf::Clear() 40{ 41 m_DataSize = 0; 42} 43void CFX_BinaryBuf::DetachBuffer() 44{ 45 m_DataSize = 0; 46 m_pBuffer = NULL; 47 m_AllocSize = 0; 48} 49void 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} 58void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other) 59{ 60 AttachData(other.GetBuffer(), other.GetSize()); 61 other.DetachBuffer(); 62} 63void 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} 71void 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} 98void 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} 113void 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} 121void 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} 133void 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} 142CFX_ByteStringC CFX_BinaryBuf::GetByteString() const 143{ 144 return CFX_ByteStringC(m_pBuffer, m_DataSize); 145} 146void CFX_BinaryBuf::GetByteStringL(CFX_ByteStringL &str) const 147{ 148 str.Set(CFX_ByteStringC(m_pBuffer, m_DataSize), m_pAllocator); 149} 150CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz) 151{ 152 AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength()); 153 return *this; 154} 155CFX_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} 162CFX_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} 169CFX_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} 176CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf) 177{ 178 AppendBlock(buf.m_pBuffer, buf.m_DataSize); 179 return *this; 180} 181void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str) 182{ 183 CopyData((FX_LPCBYTE)str, str.GetLength()); 184} 185void 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} 194CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str) 195{ 196 AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR)); 197 return *this; 198} 199CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str) 200{ 201 AppendBlock((FX_LPCWSTR)str, str.GetLength() * sizeof(FX_WCHAR)); 202 return *this; 203} 204CFX_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} 220CFX_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} 235CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz) 236{ 237 AppendBlock(lpsz, (FX_STRSIZE)FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR)); 238 return *this; 239} 240CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf) 241{ 242 AppendBlock(buf.m_pBuffer, buf.m_DataSize); 243 return *this; 244} 245void CFX_WideTextBuf::operator =(FX_WSTR str) 246{ 247 CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR)); 248} 249CFX_WideStringC CFX_WideTextBuf::GetWideString() const 250{ 251 return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR)); 252} 253void 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} 257CFX_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} 266CFX_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} 275CFX_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} 284CFX_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} 293CFX_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} 305CFX_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} 317CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr) 318{ 319 CFX_ByteString encoded = wstr.UTF16LE_Encode(); 320 return operator << (encoded); 321} 322void 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} 330CFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize) 331{ 332 m_pLoadingBuf = pData; 333 m_LoadingPos = 0; 334 m_LoadingSize = dwSize; 335} 336FX_BOOL CFX_ArchiveLoader::IsEOF() 337{ 338 return m_LoadingPos >= m_LoadingSize; 339} 340CFX_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} 348CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i) 349{ 350 Read(&i, sizeof(int)); 351 return *this; 352} 353CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i) 354{ 355 Read(&i, sizeof(FX_DWORD)); 356 return *this; 357} 358CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i) 359{ 360 Read(&i, sizeof(FX_FLOAT)); 361 return *this; 362} 363CFX_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} 380CFX_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} 387FX_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} 396void CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize) 397{ 398 m_pData = pData; 399 m_BitSize = dwSize * 8; 400 m_BitPos = 0; 401} 402void CFX_BitStream::ByteAlign() 403{ 404 int mod = m_BitPos % 8; 405 if (mod == 0) { 406 return; 407 } 408 m_BitPos += 8 - mod; 409} 410FX_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} 442IFX_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} 449void 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} 457FX_BOOL IFX_BufferArchive::Flush() 458{ 459 FX_BOOL bRet = DoWork(m_pBuffer, m_Length); 460 m_Length = 0; 461 return bRet; 462} 463FX_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} 490FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte) 491{ 492 return AppendBlock(&byte, 1); 493} 494FX_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} 500FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz) 501{ 502 return AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength()); 503} 504CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator) 505 : IFX_BufferArchive(size, pAllocator) 506 , m_pFile(NULL) 507 , m_bTakeover(FALSE) 508{ 509} 510CFX_FileBufferArchive::~CFX_FileBufferArchive() 511{ 512 Clear(); 513} 514void 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} 523FX_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} 535FX_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} 550FX_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} 565FX_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