Kill FXSYS_mem{cpy,cmp,set.move}{32,8}.
[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_CHAR* 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(uint8_t, 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_memmove(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 = (uint8_t*)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     uint8_t* pNewBuffer = m_pBuffer;
86     if (pNewBuffer) {
87         pNewBuffer = FX_Realloc(uint8_t, m_pBuffer, new_size);
88     } else {
89         pNewBuffer = FX_Alloc(uint8_t, 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_memcpy(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_memcpy(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_memmove(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos);
124     if (pBuf) {
125         FXSYS_memcpy(m_pBuffer + pos, pBuf, size);
126     }
127     m_DataSize += size;
128 }
129 void CFX_BinaryBuf::AppendFill(uint8_t byte, FX_STRSIZE count)
130 {
131     ExpandBuf(count);
132     if (!m_pBuffer) {
133         return;
134     }
135     FXSYS_memset(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 << (const CFX_ByteStringC& 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 << (const CFX_WideStringC& 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_WCHAR* 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_WCHAR* 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 << (const FX_WCHAR* 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 =(const CFX_WideStringC& str)
238 {
239     CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
240 }
241 CFX_WideStringC CFX_WideTextBuf::GetWideString() const
242 {
243     return CFX_WideStringC((const FX_WCHAR*)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
244 }
245 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (uint8_t 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 << (const CFX_ByteStringC& 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 << (const FX_WCHAR* 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(const uint8_t* 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 >> (uint8_t& 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_CHAR* buffer = str.GetBuffer(len);
363     FXSYS_memcpy(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_memcpy(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize);
381     m_LoadingPos += dwSize;
382     return TRUE;
383 }
384 void CFX_BitStream::Init(const uint8_t* 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 int32_t 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(uint8_t, m_BufSize);
457     }
458     uint8_t* buffer = (uint8_t*)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_memcpy(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 (int32_t)size;
473 }
474 int32_t IFX_BufferArchive::AppendByte(uint8_t byte)
475 {
476     return AppendBlock(&byte, 1);
477 }
478 int32_t 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 int32_t IFX_BufferArchive::AppendString(const CFX_ByteStringC& 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(const FX_WCHAR* 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(const FX_CHAR* 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 }