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);
CFX_BinaryBuf()9 CFX_BinaryBuf::CFX_BinaryBuf()
10 : m_AllocStep(0)
11 , m_pBuffer(NULL)
12 , m_DataSize(0)
13 , m_AllocSize(0)
14 {
15 }
CFX_BinaryBuf(FX_STRSIZE size)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 }
~CFX_BinaryBuf()23 CFX_BinaryBuf::~CFX_BinaryBuf()
24 {
25 if (m_pBuffer) {
26 FX_Free(m_pBuffer);
27 }
28 }
Delete(int start_index,int count)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 }
Clear()37 void CFX_BinaryBuf::Clear()
38 {
39 m_DataSize = 0;
40 }
DetachBuffer()41 void CFX_BinaryBuf::DetachBuffer()
42 {
43 m_DataSize = 0;
44 m_pBuffer = NULL;
45 m_AllocSize = 0;
46 }
AttachData(void * buffer,FX_STRSIZE size)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 }
TakeOver(CFX_BinaryBuf & other)56 void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other)
57 {
58 AttachData(other.GetBuffer(), other.GetSize());
59 other.DetachBuffer();
60 }
EstimateSize(FX_STRSIZE size,FX_STRSIZE step)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 }
ExpandBuf(FX_STRSIZE add_size)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 }
CopyData(const void * pStr,FX_STRSIZE size)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 }
AppendBlock(const void * pBuf,FX_STRSIZE size)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 }
InsertBlock(FX_STRSIZE pos,const void * pBuf,FX_STRSIZE size)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 }
AppendFill(FX_BYTE byte,FX_STRSIZE count)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 }
GetByteString() const138 CFX_ByteStringC CFX_BinaryBuf::GetByteString() const
139 {
140 return CFX_ByteStringC(m_pBuffer, m_DataSize);
141 }
operator <<(FX_BSTR lpsz)142 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz)
143 {
144 AppendBlock(lpsz.GetPtr(), lpsz.GetLength());
145 return *this;
146 }
operator <<(int i)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 }
operator <<(FX_DWORD i)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 }
operator <<(double f)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 }
operator <<(const CFX_ByteTextBuf & buf)168 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf)
169 {
170 AppendBlock(buf.m_pBuffer, buf.m_DataSize);
171 return *this;
172 }
operator =(const CFX_ByteStringC & str)173 void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str)
174 {
175 CopyData(str.GetPtr(), str.GetLength());
176 }
AppendChar(FX_WCHAR ch)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 }
operator <<(FX_WSTR str)186 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str)
187 {
188 AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
189 return *this;
190 }
operator <<(const CFX_WideString & str)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 }
operator <<(int i)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 }
operator <<(double f)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 }
operator <<(FX_LPCWSTR lpsz)227 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz)
228 {
229 AppendBlock(lpsz, FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR));
230 return *this;
231 }
operator <<(const CFX_WideTextBuf & buf)232 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf)
233 {
234 AppendBlock(buf.m_pBuffer, buf.m_DataSize);
235 return *this;
236 }
operator =(FX_WSTR str)237 void CFX_WideTextBuf::operator =(FX_WSTR str)
238 {
239 CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
240 }
GetWideString() const241 CFX_WideStringC CFX_WideTextBuf::GetWideString() const
242 {
243 return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
244 }
operator <<(FX_BYTE i)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 }
operator <<(int i)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 }
operator <<(FX_DWORD i)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 }
operator <<(FX_FLOAT f)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 }
operator <<(FX_BSTR bstr)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 }
operator <<(FX_LPCWSTR wstr)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 }
operator <<(const CFX_WideString & wstr)305 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr)
306 {
307 CFX_ByteString encoded = wstr.UTF16LE_Encode();
308 return operator << (encoded);
309 }
Write(const void * pData,FX_STRSIZE dwSize)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 }
CFX_ArchiveLoader(FX_LPCBYTE pData,FX_DWORD dwSize)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 }
IsEOF()324 FX_BOOL CFX_ArchiveLoader::IsEOF()
325 {
326 return m_LoadingPos >= m_LoadingSize;
327 }
operator >>(FX_BYTE & i)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 }
operator >>(int & i)336 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i)
337 {
338 Read(&i, sizeof(int));
339 return *this;
340 }
operator >>(FX_DWORD & i)341 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i)
342 {
343 Read(&i, sizeof(FX_DWORD));
344 return *this;
345 }
operator >>(FX_FLOAT & i)346 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i)
347 {
348 Read(&i, sizeof(FX_FLOAT));
349 return *this;
350 }
operator >>(CFX_ByteString & str)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 }
operator >>(CFX_WideString & str)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 }
Read(void * pBuf,FX_DWORD dwSize)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 }
Init(FX_LPCBYTE pData,FX_DWORD dwSize)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 }
ByteAlign()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 }
GetBits(FX_DWORD nBits)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 }
IFX_BufferArchive(FX_STRSIZE size)430 IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size)
431 : m_BufSize(size)
432 , m_pBuffer(NULL)
433 , m_Length(0)
434 {
435 }
Clear()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 }
Flush()444 FX_BOOL IFX_BufferArchive::Flush()
445 {
446 FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
447 m_Length = 0;
448 return bRet;
449 }
AppendBlock(const void * pBuf,size_t size)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 }
AppendByte(FX_BYTE byte)474 FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte)
475 {
476 return AppendBlock(&byte, 1);
477 }
AppendDWord(FX_DWORD i)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 }
AppendString(FX_BSTR lpsz)484 FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz)
485 {
486 return AppendBlock(lpsz.GetPtr(), lpsz.GetLength());
487 }
CFX_FileBufferArchive(FX_STRSIZE size)488 CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size)
489 : IFX_BufferArchive(size)
490 , m_pFile(NULL)
491 , m_bTakeover(FALSE)
492 {
493 }
~CFX_FileBufferArchive()494 CFX_FileBufferArchive::~CFX_FileBufferArchive()
495 {
496 Clear();
497 }
Clear()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 }
AttachFile(IFX_StreamWrite * pFile,FX_BOOL bTakeover)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 }
AttachFile(FX_LPCWSTR filename)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 }
AttachFile(FX_LPCSTR filename)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 }
DoWork(const void * pBuf,size_t size)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