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 <algorithm> 8 9 #include "core/include/fxcrt/fx_basic.h" 10 11 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_CHAR* buf); 12 CFX_BinaryBuf::CFX_BinaryBuf() 13 : m_AllocStep(0), m_pBuffer(NULL), m_DataSize(0), m_AllocSize(0) {} 14 CFX_BinaryBuf::CFX_BinaryBuf(FX_STRSIZE size) 15 : m_AllocStep(0), m_DataSize(size), m_AllocSize(size) { 16 m_pBuffer = FX_Alloc(uint8_t, size); 17 } 18 CFX_BinaryBuf::~CFX_BinaryBuf() { 19 FX_Free(m_pBuffer); 20 } 21 void CFX_BinaryBuf::Delete(int start_index, int count) { 22 if (!m_pBuffer || start_index < 0 || start_index + count > m_DataSize) { 23 return; 24 } 25 FXSYS_memmove(m_pBuffer + start_index, m_pBuffer + start_index + count, 26 m_DataSize - start_index - count); 27 m_DataSize -= count; 28 } 29 void CFX_BinaryBuf::Clear() { 30 m_DataSize = 0; 31 } 32 void CFX_BinaryBuf::DetachBuffer() { 33 m_DataSize = 0; 34 m_pBuffer = NULL; 35 m_AllocSize = 0; 36 } 37 void CFX_BinaryBuf::AttachData(void* buffer, FX_STRSIZE size) { 38 FX_Free(m_pBuffer); 39 m_DataSize = size; 40 m_pBuffer = (uint8_t*)buffer; 41 m_AllocSize = size; 42 } 43 void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other) { 44 AttachData(other.GetBuffer(), other.GetSize()); 45 other.DetachBuffer(); 46 } 47 void CFX_BinaryBuf::EstimateSize(FX_STRSIZE size, FX_STRSIZE step) { 48 m_AllocStep = step; 49 if (m_AllocSize >= size) { 50 return; 51 } 52 ExpandBuf(size - m_DataSize); 53 } 54 void CFX_BinaryBuf::ExpandBuf(FX_STRSIZE add_size) { 55 FX_STRSIZE new_size = add_size + m_DataSize; 56 if (m_AllocSize >= new_size) { 57 return; 58 } 59 int alloc_step; 60 if (m_AllocStep == 0) { 61 alloc_step = m_AllocSize / 4; 62 if (alloc_step < 128) { 63 alloc_step = 128; 64 } 65 } else { 66 alloc_step = m_AllocStep; 67 } 68 new_size = (new_size + alloc_step - 1) / alloc_step * alloc_step; 69 uint8_t* pNewBuffer = m_pBuffer; 70 if (pNewBuffer) { 71 pNewBuffer = FX_Realloc(uint8_t, m_pBuffer, new_size); 72 } else { 73 pNewBuffer = FX_Alloc(uint8_t, new_size); 74 } 75 m_pBuffer = pNewBuffer; 76 m_AllocSize = new_size; 77 } 78 void CFX_BinaryBuf::CopyData(const void* pStr, FX_STRSIZE size) { 79 if (size == 0) { 80 m_DataSize = 0; 81 return; 82 } 83 if (m_AllocSize < size) { 84 ExpandBuf(size - m_DataSize); 85 } 86 if (!m_pBuffer) { 87 return; 88 } 89 FXSYS_memcpy(m_pBuffer, pStr, size); 90 m_DataSize = size; 91 } 92 void CFX_BinaryBuf::AppendBlock(const void* pBuf, FX_STRSIZE size) { 93 ExpandBuf(size); 94 if (pBuf && m_pBuffer) { 95 FXSYS_memcpy(m_pBuffer + m_DataSize, pBuf, size); 96 } 97 m_DataSize += size; 98 } 99 void CFX_BinaryBuf::InsertBlock(FX_STRSIZE pos, 100 const void* pBuf, 101 FX_STRSIZE size) { 102 ExpandBuf(size); 103 if (!m_pBuffer) { 104 return; 105 } 106 FXSYS_memmove(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos); 107 if (pBuf) { 108 FXSYS_memcpy(m_pBuffer + pos, pBuf, size); 109 } 110 m_DataSize += size; 111 } 112 void CFX_BinaryBuf::AppendFill(uint8_t byte, FX_STRSIZE count) { 113 ExpandBuf(count); 114 if (!m_pBuffer) { 115 return; 116 } 117 FXSYS_memset(m_pBuffer + m_DataSize, byte, count); 118 m_DataSize += count; 119 } 120 CFX_ByteStringC CFX_BinaryBuf::GetByteString() const { 121 return CFX_ByteStringC(m_pBuffer, m_DataSize); 122 } 123 CFX_ByteTextBuf& CFX_ByteTextBuf::operator<<(const CFX_ByteStringC& lpsz) { 124 AppendBlock(lpsz.GetPtr(), lpsz.GetLength()); 125 return *this; 126 } 127 CFX_ByteTextBuf& CFX_ByteTextBuf::operator<<(int i) { 128 char buf[32]; 129 FXSYS_itoa(i, buf, 10); 130 AppendBlock(buf, FXSYS_strlen(buf)); 131 return *this; 132 } 133 CFX_ByteTextBuf& CFX_ByteTextBuf::operator<<(FX_DWORD i) { 134 char buf[32]; 135 FXSYS_itoa(i, buf, 10); 136 AppendBlock(buf, FXSYS_strlen(buf)); 137 return *this; 138 } 139 CFX_ByteTextBuf& CFX_ByteTextBuf::operator<<(double f) { 140 char buf[32]; 141 FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf); 142 AppendBlock(buf, len); 143 return *this; 144 } 145 CFX_ByteTextBuf& CFX_ByteTextBuf::operator<<(const CFX_ByteTextBuf& buf) { 146 AppendBlock(buf.m_pBuffer, buf.m_DataSize); 147 return *this; 148 } 149 void CFX_ByteTextBuf::operator=(const CFX_ByteStringC& str) { 150 CopyData(str.GetPtr(), str.GetLength()); 151 } 152 void CFX_WideTextBuf::AppendChar(FX_WCHAR ch) { 153 if (m_AllocSize < m_DataSize + (FX_STRSIZE)sizeof(FX_WCHAR)) { 154 ExpandBuf(sizeof(FX_WCHAR)); 155 } 156 ASSERT(m_pBuffer); 157 *(FX_WCHAR*)(m_pBuffer + m_DataSize) = ch; 158 m_DataSize += sizeof(FX_WCHAR); 159 } 160 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const CFX_WideStringC& str) { 161 AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR)); 162 return *this; 163 } 164 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const CFX_WideString& str) { 165 AppendBlock(str.c_str(), str.GetLength() * sizeof(FX_WCHAR)); 166 return *this; 167 } 168 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(int i) { 169 char buf[32]; 170 FXSYS_itoa(i, buf, 10); 171 FX_STRSIZE len = FXSYS_strlen(buf); 172 if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) { 173 ExpandBuf(len * sizeof(FX_WCHAR)); 174 } 175 ASSERT(m_pBuffer); 176 FX_WCHAR* str = (FX_WCHAR*)(m_pBuffer + m_DataSize); 177 for (FX_STRSIZE j = 0; j < len; j++) { 178 *str++ = buf[j]; 179 } 180 m_DataSize += len * sizeof(FX_WCHAR); 181 return *this; 182 } 183 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(double f) { 184 char buf[32]; 185 FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf); 186 if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) { 187 ExpandBuf(len * sizeof(FX_WCHAR)); 188 } 189 ASSERT(m_pBuffer); 190 FX_WCHAR* str = (FX_WCHAR*)(m_pBuffer + m_DataSize); 191 for (FX_STRSIZE i = 0; i < len; i++) { 192 *str++ = buf[i]; 193 } 194 m_DataSize += len * sizeof(FX_WCHAR); 195 return *this; 196 } 197 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const FX_WCHAR* lpsz) { 198 AppendBlock(lpsz, FXSYS_wcslen(lpsz) * sizeof(FX_WCHAR)); 199 return *this; 200 } 201 CFX_WideTextBuf& CFX_WideTextBuf::operator<<(const CFX_WideTextBuf& buf) { 202 AppendBlock(buf.m_pBuffer, buf.m_DataSize); 203 return *this; 204 } 205 void CFX_WideTextBuf::operator=(const CFX_WideStringC& str) { 206 CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR)); 207 } 208 CFX_WideStringC CFX_WideTextBuf::GetWideString() const { 209 return CFX_WideStringC((const FX_WCHAR*)m_pBuffer, 210 m_DataSize / sizeof(FX_WCHAR)); 211 } 212 213 #ifdef PDF_ENABLE_XFA 214 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(uint8_t i) { 215 if (m_pStream) { 216 m_pStream->WriteBlock(&i, 1); 217 } else { 218 m_SavingBuf.AppendByte(i); 219 } 220 return *this; 221 } 222 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(int i) { 223 if (m_pStream) { 224 m_pStream->WriteBlock(&i, sizeof(int)); 225 } else { 226 m_SavingBuf.AppendBlock(&i, sizeof(int)); 227 } 228 return *this; 229 } 230 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(FX_DWORD i) { 231 if (m_pStream) { 232 m_pStream->WriteBlock(&i, sizeof(FX_DWORD)); 233 } else { 234 m_SavingBuf.AppendBlock(&i, sizeof(FX_DWORD)); 235 } 236 return *this; 237 } 238 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(FX_FLOAT f) { 239 if (m_pStream) { 240 m_pStream->WriteBlock(&f, sizeof(FX_FLOAT)); 241 } else { 242 m_SavingBuf.AppendBlock(&f, sizeof(FX_FLOAT)); 243 } 244 return *this; 245 } 246 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(const CFX_ByteStringC& bstr) { 247 int len = bstr.GetLength(); 248 if (m_pStream) { 249 m_pStream->WriteBlock(&len, sizeof(int)); 250 m_pStream->WriteBlock(bstr.GetPtr(), len); 251 } else { 252 m_SavingBuf.AppendBlock(&len, sizeof(int)); 253 m_SavingBuf.AppendBlock(bstr.GetPtr(), len); 254 } 255 return *this; 256 } 257 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(const FX_WCHAR* wstr) { 258 FX_STRSIZE len = FXSYS_wcslen(wstr); 259 if (m_pStream) { 260 m_pStream->WriteBlock(&len, sizeof(int)); 261 m_pStream->WriteBlock(wstr, len); 262 } else { 263 m_SavingBuf.AppendBlock(&len, sizeof(int)); 264 m_SavingBuf.AppendBlock(wstr, len); 265 } 266 return *this; 267 } 268 CFX_ArchiveSaver& CFX_ArchiveSaver::operator<<(const CFX_WideString& wstr) { 269 CFX_ByteString encoded = wstr.UTF16LE_Encode(); 270 return operator<<(encoded); 271 } 272 void CFX_ArchiveSaver::Write(const void* pData, FX_STRSIZE dwSize) { 273 if (m_pStream) { 274 m_pStream->WriteBlock(pData, dwSize); 275 } else { 276 m_SavingBuf.AppendBlock(pData, dwSize); 277 } 278 } 279 CFX_ArchiveLoader::CFX_ArchiveLoader(const uint8_t* pData, FX_DWORD dwSize) { 280 m_pLoadingBuf = pData; 281 m_LoadingPos = 0; 282 m_LoadingSize = dwSize; 283 } 284 FX_BOOL CFX_ArchiveLoader::IsEOF() { 285 return m_LoadingPos >= m_LoadingSize; 286 } 287 CFX_ArchiveLoader& CFX_ArchiveLoader::operator>>(uint8_t& i) { 288 if (m_LoadingPos >= m_LoadingSize) { 289 return *this; 290 } 291 i = m_pLoadingBuf[m_LoadingPos++]; 292 return *this; 293 } 294 CFX_ArchiveLoader& CFX_ArchiveLoader::operator>>(int& i) { 295 Read(&i, sizeof(int)); 296 return *this; 297 } 298 CFX_ArchiveLoader& CFX_ArchiveLoader::operator>>(FX_DWORD& i) { 299 Read(&i, sizeof(FX_DWORD)); 300 return *this; 301 } 302 CFX_ArchiveLoader& CFX_ArchiveLoader::operator>>(FX_FLOAT& i) { 303 Read(&i, sizeof(FX_FLOAT)); 304 return *this; 305 } 306 CFX_ArchiveLoader& CFX_ArchiveLoader::operator>>(CFX_ByteString& str) { 307 if (m_LoadingPos + 4 > m_LoadingSize) { 308 return *this; 309 } 310 int len; 311 operator>>(len); 312 str.Empty(); 313 if (len <= 0 || m_LoadingPos + len > m_LoadingSize) { 314 return *this; 315 } 316 FX_CHAR* buffer = str.GetBuffer(len); 317 FXSYS_memcpy(buffer, m_pLoadingBuf + m_LoadingPos, len); 318 str.ReleaseBuffer(len); 319 m_LoadingPos += len; 320 return *this; 321 } 322 CFX_ArchiveLoader& CFX_ArchiveLoader::operator>>(CFX_WideString& str) { 323 CFX_ByteString encoded; 324 operator>>(encoded); 325 str = CFX_WideString::FromUTF16LE( 326 reinterpret_cast<const unsigned short*>(encoded.c_str()), 327 encoded.GetLength() / sizeof(unsigned short)); 328 return *this; 329 } 330 FX_BOOL CFX_ArchiveLoader::Read(void* pBuf, FX_DWORD dwSize) { 331 if (m_LoadingPos + dwSize > m_LoadingSize) { 332 return FALSE; 333 } 334 FXSYS_memcpy(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize); 335 m_LoadingPos += dwSize; 336 return TRUE; 337 } 338 #endif // PDF_ENABLE_XFA 339 340 void CFX_BitStream::Init(const uint8_t* pData, FX_DWORD dwSize) { 341 m_pData = pData; 342 m_BitSize = dwSize * 8; 343 m_BitPos = 0; 344 } 345 void CFX_BitStream::ByteAlign() { 346 int mod = m_BitPos % 8; 347 if (mod == 0) { 348 return; 349 } 350 m_BitPos += 8 - mod; 351 } 352 FX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits) { 353 if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) { 354 return 0; 355 } 356 if (nBits == 1) { 357 int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0; 358 m_BitPos++; 359 return bit; 360 } 361 FX_DWORD byte_pos = m_BitPos / 8; 362 FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits; 363 FX_DWORD result = 0; 364 if (bit_pos) { 365 if (8 - bit_pos >= bit_left) { 366 result = 367 (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left); 368 m_BitPos += bit_left; 369 return result; 370 } 371 bit_left -= 8 - bit_pos; 372 result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left; 373 } 374 while (bit_left >= 8) { 375 bit_left -= 8; 376 result |= m_pData[byte_pos++] << bit_left; 377 } 378 if (bit_left) { 379 result |= m_pData[byte_pos] >> (8 - bit_left); 380 } 381 m_BitPos += nBits; 382 return result; 383 } 384 IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size) 385 : m_BufSize(size), m_pBuffer(NULL), m_Length(0) {} 386 void IFX_BufferArchive::Clear() { 387 m_Length = 0; 388 FX_Free(m_pBuffer); 389 m_pBuffer = NULL; 390 } 391 FX_BOOL IFX_BufferArchive::Flush() { 392 FX_BOOL bRet = DoWork(m_pBuffer, m_Length); 393 m_Length = 0; 394 return bRet; 395 } 396 int32_t IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size) { 397 if (!pBuf || size < 1) { 398 return 0; 399 } 400 if (!m_pBuffer) { 401 m_pBuffer = FX_Alloc(uint8_t, m_BufSize); 402 } 403 uint8_t* buffer = (uint8_t*)pBuf; 404 FX_STRSIZE temp_size = (FX_STRSIZE)size; 405 while (temp_size > 0) { 406 FX_STRSIZE buf_size = std::min(m_BufSize - m_Length, (FX_STRSIZE)temp_size); 407 FXSYS_memcpy(m_pBuffer + m_Length, buffer, buf_size); 408 m_Length += buf_size; 409 if (m_Length == m_BufSize) { 410 if (!Flush()) { 411 return -1; 412 } 413 } 414 temp_size -= buf_size; 415 buffer += buf_size; 416 } 417 return (int32_t)size; 418 } 419 int32_t IFX_BufferArchive::AppendByte(uint8_t byte) { 420 return AppendBlock(&byte, 1); 421 } 422 int32_t IFX_BufferArchive::AppendDWord(FX_DWORD i) { 423 char buf[32]; 424 FXSYS_itoa(i, buf, 10); 425 return AppendBlock(buf, (size_t)FXSYS_strlen(buf)); 426 } 427 int32_t IFX_BufferArchive::AppendString(const CFX_ByteStringC& lpsz) { 428 return AppendBlock(lpsz.GetPtr(), lpsz.GetLength()); 429 } 430 CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size) 431 : IFX_BufferArchive(size), m_pFile(NULL), m_bTakeover(FALSE) {} 432 CFX_FileBufferArchive::~CFX_FileBufferArchive() { 433 Clear(); 434 } 435 void CFX_FileBufferArchive::Clear() { 436 if (m_pFile && m_bTakeover) { 437 m_pFile->Release(); 438 } 439 m_pFile = NULL; 440 m_bTakeover = FALSE; 441 IFX_BufferArchive::Clear(); 442 } 443 FX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite* pFile, 444 FX_BOOL bTakeover) { 445 if (!pFile) { 446 return FALSE; 447 } 448 if (m_pFile && m_bTakeover) { 449 m_pFile->Release(); 450 } 451 m_pFile = pFile; 452 m_bTakeover = bTakeover; 453 return TRUE; 454 } 455 FX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size) { 456 if (!m_pFile) { 457 return FALSE; 458 } 459 if (!pBuf || size < 1) { 460 return TRUE; 461 } 462 return m_pFile->WriteBlock(pBuf, size); 463 } 464