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