Kill CFX_ArchiveLoader / CFX_ArchiveSaver and subclasses
[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 void CFX_BitStream::Init(const uint8_t* pData, FX_DWORD dwSize)
246 {
247     m_pData = pData;
248     m_BitSize = dwSize * 8;
249     m_BitPos = 0;
250 }
251 void CFX_BitStream::ByteAlign()
252 {
253     int mod = m_BitPos % 8;
254     if (mod == 0) {
255         return;
256     }
257     m_BitPos += 8 - mod;
258 }
259 FX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits)
260 {
261     if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) {
262         return 0;
263     }
264     if (nBits == 1) {
265         int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0;
266         m_BitPos ++;
267         return bit;
268     }
269     FX_DWORD byte_pos = m_BitPos / 8;
270     FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits;
271     FX_DWORD result = 0;
272     if (bit_pos) {
273         if (8 - bit_pos >= bit_left) {
274             result = (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left);
275             m_BitPos += bit_left;
276             return result;
277         }
278         bit_left -= 8 - bit_pos;
279         result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
280     }
281     while (bit_left >= 8) {
282         bit_left -= 8;
283         result |= m_pData[byte_pos++] << bit_left;
284     }
285     if (bit_left) {
286         result |= m_pData[byte_pos] >> (8 - bit_left);
287     }
288     m_BitPos += nBits;
289     return result;
290 }
291 IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size)
292     : m_BufSize(size)
293     , m_pBuffer(NULL)
294     , m_Length(0)
295 {
296 }
297 void IFX_BufferArchive::Clear()
298 {
299     m_Length = 0;
300     if (m_pBuffer) {
301         FX_Free(m_pBuffer);
302         m_pBuffer = NULL;
303     }
304 }
305 FX_BOOL IFX_BufferArchive::Flush()
306 {
307     FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
308     m_Length = 0;
309     return bRet;
310 }
311 int32_t IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size)
312 {
313     if (!pBuf || size < 1) {
314         return 0;
315     }
316     if (!m_pBuffer) {
317         m_pBuffer = FX_Alloc(uint8_t, m_BufSize);
318     }
319     uint8_t* buffer = (uint8_t*)pBuf;
320     FX_STRSIZE temp_size = (FX_STRSIZE)size;
321     while (temp_size > 0) {
322         FX_STRSIZE buf_size = FX_MIN(m_BufSize - m_Length, (FX_STRSIZE)temp_size);
323         FXSYS_memcpy(m_pBuffer + m_Length, buffer, buf_size);
324         m_Length += buf_size;
325         if (m_Length == m_BufSize) {
326             if (!Flush()) {
327                 return -1;
328             }
329         }
330         temp_size -= buf_size;
331         buffer += buf_size;
332     }
333     return (int32_t)size;
334 }
335 int32_t IFX_BufferArchive::AppendByte(uint8_t byte)
336 {
337     return AppendBlock(&byte, 1);
338 }
339 int32_t IFX_BufferArchive::AppendDWord(FX_DWORD i)
340 {
341     char buf[32];
342     FXSYS_itoa(i, buf, 10);
343     return AppendBlock(buf, (size_t)FXSYS_strlen(buf));
344 }
345 int32_t IFX_BufferArchive::AppendString(const CFX_ByteStringC& lpsz)
346 {
347     return AppendBlock(lpsz.GetPtr(), lpsz.GetLength());
348 }
349 CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size)
350     : IFX_BufferArchive(size)
351     , m_pFile(NULL)
352     , m_bTakeover(FALSE)
353 {
354 }
355 CFX_FileBufferArchive::~CFX_FileBufferArchive()
356 {
357     Clear();
358 }
359 void CFX_FileBufferArchive::Clear()
360 {
361     if (m_pFile && m_bTakeover) {
362         m_pFile->Release();
363     }
364     m_pFile = NULL;
365     m_bTakeover = FALSE;
366     IFX_BufferArchive::Clear();
367 }
368 FX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover )
369 {
370     if (!pFile) {
371         return FALSE;
372     }
373     if (m_pFile && m_bTakeover) {
374         m_pFile->Release();
375     }
376     m_pFile = pFile;
377     m_bTakeover = bTakeover;
378     return TRUE;
379 }
380 FX_BOOL CFX_FileBufferArchive::AttachFile(const FX_WCHAR* filename)
381 {
382     if (!filename) {
383         return FALSE;
384     }
385     if (m_pFile && m_bTakeover) {
386         m_pFile->Release();
387     }
388     m_pFile = FX_CreateFileWrite(filename);
389     if (!m_pFile) {
390         return FALSE;
391     }
392     m_bTakeover = TRUE;
393     return TRUE;
394 }
395 FX_BOOL CFX_FileBufferArchive::AttachFile(const FX_CHAR* filename)
396 {
397     if (!filename) {
398         return FALSE;
399     }
400     if (m_pFile && m_bTakeover) {
401         m_pFile->Release();
402     }
403     m_pFile = FX_CreateFileWrite(filename);
404     if (!m_pFile) {
405         return FALSE;
406     }
407     m_bTakeover = TRUE;
408     return TRUE;
409 }
410 FX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size)
411 {
412     if (!m_pFile) {
413         return FALSE;
414     }
415     if (!pBuf || size < 1) {
416         return TRUE;
417     }
418     return m_pFile->WriteBlock(pBuf, size);
419 }