Convert all line endings to LF.
[pdfium.git] / core / src / fxcrt / fx_basic_buffer.cpp
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 }