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