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() 10 : m_AllocStep(0) 11 , m_pBuffer(NULL) 12 , m_DataSize(0) 13 , m_AllocSize(0) 14{ 15} 16CFX_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} 23CFX_BinaryBuf::~CFX_BinaryBuf() 24{ 25 if (m_pBuffer) { 26 FX_Free(m_pBuffer); 27 } 28} 29void 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} 37void CFX_BinaryBuf::Clear() 38{ 39 m_DataSize = 0; 40} 41void CFX_BinaryBuf::DetachBuffer() 42{ 43 m_DataSize = 0; 44 m_pBuffer = NULL; 45 m_AllocSize = 0; 46} 47void 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} 56void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other) 57{ 58 AttachData(other.GetBuffer(), other.GetSize()); 59 other.DetachBuffer(); 60} 61void 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} 69void 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} 94void 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} 109void 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} 117void 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} 129void 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} 138CFX_ByteStringC CFX_BinaryBuf::GetByteString() const 139{ 140 return CFX_ByteStringC(m_pBuffer, m_DataSize); 141} 142CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz) 143{ 144 AppendBlock(lpsz.GetPtr(), lpsz.GetLength()); 145 return *this; 146} 147CFX_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} 154CFX_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} 161CFX_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} 168CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf) 169{ 170 AppendBlock(buf.m_pBuffer, buf.m_DataSize); 171 return *this; 172} 173void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str) 174{ 175 CopyData(str.GetPtr(), str.GetLength()); 176} 177void 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} 186CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str) 187{ 188 AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR)); 189 return *this; 190} 191CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str) 192{ 193 AppendBlock(str.c_str(), str.GetLength() * sizeof(FX_WCHAR)); 194 return *this; 195} 196CFX_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} 212CFX_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} 227CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz) 228{ 229 AppendBlock(lpsz, FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR)); 230 return *this; 231} 232CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf) 233{ 234 AppendBlock(buf.m_pBuffer, buf.m_DataSize); 235 return *this; 236} 237void CFX_WideTextBuf::operator =(FX_WSTR str) 238{ 239 CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR)); 240} 241CFX_WideStringC CFX_WideTextBuf::GetWideString() const 242{ 243 return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR)); 244} 245CFX_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} 254CFX_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} 263CFX_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} 272CFX_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} 281CFX_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} 293CFX_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} 305CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr) 306{ 307 CFX_ByteString encoded = wstr.UTF16LE_Encode(); 308 return operator << (encoded); 309} 310void 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} 318CFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize) 319{ 320 m_pLoadingBuf = pData; 321 m_LoadingPos = 0; 322 m_LoadingSize = dwSize; 323} 324FX_BOOL CFX_ArchiveLoader::IsEOF() 325{ 326 return m_LoadingPos >= m_LoadingSize; 327} 328CFX_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} 336CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i) 337{ 338 Read(&i, sizeof(int)); 339 return *this; 340} 341CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i) 342{ 343 Read(&i, sizeof(FX_DWORD)); 344 return *this; 345} 346CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i) 347{ 348 Read(&i, sizeof(FX_FLOAT)); 349 return *this; 350} 351CFX_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} 368CFX_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} 375FX_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} 384void CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize) 385{ 386 m_pData = pData; 387 m_BitSize = dwSize * 8; 388 m_BitPos = 0; 389} 390void CFX_BitStream::ByteAlign() 391{ 392 int mod = m_BitPos % 8; 393 if (mod == 0) { 394 return; 395 } 396 m_BitPos += 8 - mod; 397} 398FX_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} 430IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size) 431 : m_BufSize(size) 432 , m_pBuffer(NULL) 433 , m_Length(0) 434{ 435} 436void IFX_BufferArchive::Clear() 437{ 438 m_Length = 0; 439 if (m_pBuffer) { 440 FX_Free(m_pBuffer); 441 m_pBuffer = NULL; 442 } 443} 444FX_BOOL IFX_BufferArchive::Flush() 445{ 446 FX_BOOL bRet = DoWork(m_pBuffer, m_Length); 447 m_Length = 0; 448 return bRet; 449} 450FX_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} 474FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte) 475{ 476 return AppendBlock(&byte, 1); 477} 478FX_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} 484FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz) 485{ 486 return AppendBlock(lpsz.GetPtr(), lpsz.GetLength()); 487} 488CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size) 489 : IFX_BufferArchive(size) 490 , m_pFile(NULL) 491 , m_bTakeover(FALSE) 492{ 493} 494CFX_FileBufferArchive::~CFX_FileBufferArchive() 495{ 496 Clear(); 497} 498void 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} 507FX_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} 519FX_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} 534FX_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} 549FX_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