Remove FX_STRSIZE casts, use safe conversions
[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()
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(FX_BYTE, 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_memmove32(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 = (FX_LPBYTE)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     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     if (pNewBuffer) {
92         m_pBuffer = pNewBuffer;
93         m_AllocSize = new_size;
94     }
95 }
96 void CFX_BinaryBuf::CopyData(const void* pStr, FX_STRSIZE size)
97 {
98     if (size == 0) {
99         m_DataSize = 0;
100         return;
101     }
102     if (m_AllocSize < size) {
103         ExpandBuf(size - m_DataSize);
104     }
105     if (!m_pBuffer) {
106         return;
107     }
108     FXSYS_memcpy32(m_pBuffer, pStr, size);
109     m_DataSize = size;
110 }
111 void CFX_BinaryBuf::AppendBlock(const void* pBuf, FX_STRSIZE size)
112 {
113     ExpandBuf(size);
114     if (pBuf && m_pBuffer) {
115         FXSYS_memcpy32(m_pBuffer + m_DataSize, pBuf, size);
116     }
117     m_DataSize += size;
118 }
119 void CFX_BinaryBuf::InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size)
120 {
121     ExpandBuf(size);
122     if (!m_pBuffer) {
123         return;
124     }
125     FXSYS_memmove32(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos);
126     if (pBuf) {
127         FXSYS_memcpy32(m_pBuffer + pos, pBuf, size);
128     }
129     m_DataSize += size;
130 }
131 void CFX_BinaryBuf::AppendFill(FX_BYTE byte, FX_STRSIZE count)
132 {
133     ExpandBuf(count);
134     if (!m_pBuffer) {
135         return;
136     }
137     FXSYS_memset8(m_pBuffer + m_DataSize, byte, count);
138     m_DataSize += count;
139 }
140 CFX_ByteStringC CFX_BinaryBuf::GetByteString() const
141 {
142     return CFX_ByteStringC(m_pBuffer, m_DataSize);
143 }
144 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz)
145 {
146     AppendBlock(lpsz.GetPtr(), lpsz.GetLength());
147     return *this;
148 }
149 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (int i)
150 {
151     char buf[32];
152     FXSYS_itoa(i, buf, 10);
153     AppendBlock(buf, FXSYS_strlen(buf));
154     return *this;
155 }
156 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_DWORD i)
157 {
158     char buf[32];
159     FXSYS_itoa(i, buf, 10);
160     AppendBlock(buf, FXSYS_strlen(buf));
161     return *this;
162 }
163 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (double f)
164 {
165     char buf[32];
166     FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
167     AppendBlock(buf, len);
168     return *this;
169 }
170 CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf)
171 {
172     AppendBlock(buf.m_pBuffer, buf.m_DataSize);
173     return *this;
174 }
175 void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str)
176 {
177     CopyData(str.GetPtr(), str.GetLength());
178 }
179 void CFX_WideTextBuf::AppendChar(FX_WCHAR ch)
180 {
181     if (m_AllocSize < m_DataSize + (FX_STRSIZE)sizeof(FX_WCHAR)) {
182         ExpandBuf(sizeof(FX_WCHAR));
183     }
184     ASSERT(m_pBuffer != NULL);
185     *(FX_WCHAR*)(m_pBuffer + m_DataSize) = ch;
186     m_DataSize += sizeof(FX_WCHAR);
187 }
188 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str)
189 {
190     AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
191     return *this;
192 }
193 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str)
194 {
195     AppendBlock(str.c_str(), str.GetLength() * sizeof(FX_WCHAR));
196     return *this;
197 }
198 CFX_WideTextBuf& CFX_WideTextBuf::operator << (int i)
199 {
200     char buf[32];
201     FXSYS_itoa(i, buf, 10);
202     FX_STRSIZE len = FXSYS_strlen(buf);
203     if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
204         ExpandBuf(len * sizeof(FX_WCHAR));
205     }
206     ASSERT(m_pBuffer != NULL);
207     FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
208     for (FX_STRSIZE j = 0; j < len; j ++) {
209         *str ++ = buf[j];
210     }
211     m_DataSize += len * sizeof(FX_WCHAR);
212     return *this;
213 }
214 CFX_WideTextBuf& CFX_WideTextBuf::operator << (double f)
215 {
216     char buf[32];
217     FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
218     if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
219         ExpandBuf(len * sizeof(FX_WCHAR));
220     }
221     ASSERT(m_pBuffer != NULL);
222     FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
223     for (FX_STRSIZE i = 0; i < len; i ++) {
224         *str ++ = buf[i];
225     }
226     m_DataSize += len * sizeof(FX_WCHAR);
227     return *this;
228 }
229 CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz)
230 {
231     AppendBlock(lpsz, FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR));
232     return *this;
233 }
234 CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf)
235 {
236     AppendBlock(buf.m_pBuffer, buf.m_DataSize);
237     return *this;
238 }
239 void CFX_WideTextBuf::operator =(FX_WSTR str)
240 {
241     CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
242 }
243 CFX_WideStringC CFX_WideTextBuf::GetWideString() const
244 {
245     return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
246 }
247 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BYTE i)
248 {
249     if (m_pStream) {
250         m_pStream->WriteBlock(&i, 1);
251     } else {
252         m_SavingBuf.AppendByte(i);
253     }
254     return *this;
255 }
256 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (int i)
257 {
258     if (m_pStream) {
259         m_pStream->WriteBlock(&i, sizeof(int));
260     } else {
261         m_SavingBuf.AppendBlock(&i, sizeof(int));
262     }
263     return *this;
264 }
265 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_DWORD i)
266 {
267     if (m_pStream) {
268         m_pStream->WriteBlock(&i, sizeof(FX_DWORD));
269     } else {
270         m_SavingBuf.AppendBlock(&i, sizeof(FX_DWORD));
271     }
272     return *this;
273 }
274 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_FLOAT f)
275 {
276     if (m_pStream) {
277         m_pStream->WriteBlock(&f, sizeof(FX_FLOAT));
278     } else {
279         m_SavingBuf.AppendBlock(&f, sizeof(FX_FLOAT));
280     }
281     return *this;
282 }
283 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BSTR bstr)
284 {
285     int len = bstr.GetLength();
286     if (m_pStream) {
287         m_pStream->WriteBlock(&len, sizeof(int));
288         m_pStream->WriteBlock(bstr.GetPtr(), len);
289     } else {
290         m_SavingBuf.AppendBlock(&len, sizeof(int));
291         m_SavingBuf.AppendBlock(bstr.GetPtr(), len);
292     }
293     return *this;
294 }
295 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_LPCWSTR wstr)
296 {
297     FX_STRSIZE len = FXSYS_wcslen(wstr);
298     if (m_pStream) {
299         m_pStream->WriteBlock(&len, sizeof(int));
300         m_pStream->WriteBlock(wstr, len);
301     } else {
302         m_SavingBuf.AppendBlock(&len, sizeof(int));
303         m_SavingBuf.AppendBlock(wstr, len);
304     }
305     return *this;
306 }
307 CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr)
308 {
309     CFX_ByteString encoded = wstr.UTF16LE_Encode();
310     return operator << (encoded);
311 }
312 void CFX_ArchiveSaver::Write(const void* pData, FX_STRSIZE dwSize)
313 {
314     if (m_pStream) {
315         m_pStream->WriteBlock(pData, dwSize);
316     } else {
317         m_SavingBuf.AppendBlock(pData, dwSize);
318     }
319 }
320 CFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize)
321 {
322     m_pLoadingBuf = pData;
323     m_LoadingPos = 0;
324     m_LoadingSize = dwSize;
325 }
326 FX_BOOL CFX_ArchiveLoader::IsEOF()
327 {
328     return m_LoadingPos >= m_LoadingSize;
329 }
330 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_BYTE& i)
331 {
332     if (m_LoadingPos >= m_LoadingSize) {
333         return *this;
334     }
335     i = m_pLoadingBuf[m_LoadingPos++];
336     return *this;
337 }
338 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i)
339 {
340     Read(&i, sizeof(int));
341     return *this;
342 }
343 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i)
344 {
345     Read(&i, sizeof(FX_DWORD));
346     return *this;
347 }
348 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i)
349 {
350     Read(&i, sizeof(FX_FLOAT));
351     return *this;
352 }
353 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_ByteString& str)
354 {
355     if (m_LoadingPos + 4 > m_LoadingSize) {
356         return *this;
357     }
358     int len;
359     operator >> (len);
360     str.Empty();
361     if (len <= 0 || m_LoadingPos + len > m_LoadingSize) {
362         return *this;
363     }
364     FX_LPSTR buffer = str.GetBuffer(len);
365     FXSYS_memcpy32(buffer, m_pLoadingBuf + m_LoadingPos, len);
366     str.ReleaseBuffer(len);
367     m_LoadingPos += len;
368     return *this;
369 }
370 CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_WideString& str)
371 {
372     CFX_ByteString encoded;
373     operator >> (encoded);
374     str = CFX_WideString::FromUTF16LE((const unsigned short*)encoded.c_str(), encoded.GetLength());
375     return *this;
376 }
377 FX_BOOL CFX_ArchiveLoader::Read(void* pBuf, FX_DWORD dwSize)
378 {
379     if (m_LoadingPos + dwSize > m_LoadingSize) {
380         return FALSE;
381     }
382     FXSYS_memcpy32(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize);
383     m_LoadingPos += dwSize;
384     return TRUE;
385 }
386 void CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize)
387 {
388     m_pData = pData;
389     m_BitSize = dwSize * 8;
390     m_BitPos = 0;
391 }
392 void CFX_BitStream::ByteAlign()
393 {
394     int mod = m_BitPos % 8;
395     if (mod == 0) {
396         return;
397     }
398     m_BitPos += 8 - mod;
399 }
400 FX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits)
401 {
402     if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) {
403         return 0;
404     }
405     if (nBits == 1) {
406         int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0;
407         m_BitPos ++;
408         return bit;
409     }
410     FX_DWORD byte_pos = m_BitPos / 8;
411     FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits;
412     FX_DWORD result = 0;
413     if (bit_pos) {
414         if (8 - bit_pos >= bit_left) {
415             result = (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left);
416             m_BitPos += bit_left;
417             return result;
418         }
419         bit_left -= 8 - bit_pos;
420         result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
421     }
422     while (bit_left >= 8) {
423         bit_left -= 8;
424         result |= m_pData[byte_pos++] << bit_left;
425     }
426     if (bit_left) {
427         result |= m_pData[byte_pos] >> (8 - bit_left);
428     }
429     m_BitPos += nBits;
430     return result;
431 }
432 IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size)
433     : m_BufSize(size)
434     , m_pBuffer(NULL)
435     , m_Length(0)
436 {
437 }
438 void IFX_BufferArchive::Clear()
439 {
440     m_Length = 0;
441     if (m_pBuffer) {
442         FX_Free(m_pBuffer);
443         m_pBuffer = NULL;
444     }
445 }
446 FX_BOOL IFX_BufferArchive::Flush()
447 {
448     FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
449     m_Length = 0;
450     return bRet;
451 }
452 FX_INT32 IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size)
453 {
454     if (!pBuf || size < 1) {
455         return 0;
456     }
457     if (!m_pBuffer) {
458         m_pBuffer = FX_Alloc(FX_BYTE, m_BufSize);
459         if (!m_pBuffer) {
460             return -1;
461         }
462     }
463     FX_LPBYTE buffer = (FX_LPBYTE)pBuf;
464     FX_STRSIZE temp_size = (FX_STRSIZE)size;
465     while (temp_size > 0) {
466         FX_STRSIZE buf_size = FX_MIN(m_BufSize - m_Length, (FX_STRSIZE)temp_size);
467         FXSYS_memcpy32(m_pBuffer + m_Length, buffer, buf_size);
468         m_Length += buf_size;
469         if (m_Length == m_BufSize) {
470             if (!Flush()) {
471                 return -1;
472             }
473         }
474         temp_size -= buf_size;
475         buffer += buf_size;
476     }
477     return (FX_INT32)size;
478 }
479 FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte)
480 {
481     return AppendBlock(&byte, 1);
482 }
483 FX_INT32 IFX_BufferArchive::AppendDWord(FX_DWORD i)
484 {
485     char buf[32];
486     FXSYS_itoa(i, buf, 10);
487     return AppendBlock(buf, (size_t)FXSYS_strlen(buf));
488 }
489 FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz)
490 {
491     return AppendBlock(lpsz.GetPtr(), lpsz.GetLength());
492 }
493 CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size)
494     : IFX_BufferArchive(size)
495     , m_pFile(NULL)
496     , m_bTakeover(FALSE)
497 {
498 }
499 CFX_FileBufferArchive::~CFX_FileBufferArchive()
500 {
501     Clear();
502 }
503 void CFX_FileBufferArchive::Clear()
504 {
505     if (m_pFile && m_bTakeover) {
506         m_pFile->Release();
507     }
508     m_pFile = NULL;
509     m_bTakeover = FALSE;
510     IFX_BufferArchive::Clear();
511 }
512 FX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover )
513 {
514     if (!pFile) {
515         return FALSE;
516     }
517     if (m_pFile && m_bTakeover) {
518         m_pFile->Release();
519     }
520     m_pFile = pFile;
521     m_bTakeover = bTakeover;
522     return TRUE;
523 }
524 FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCWSTR filename)
525 {
526     if (!filename) {
527         return FALSE;
528     }
529     if (m_pFile && m_bTakeover) {
530         m_pFile->Release();
531     }
532     m_pFile = FX_CreateFileWrite(filename);
533     if (!m_pFile) {
534         return FALSE;
535     }
536     m_bTakeover = TRUE;
537     return TRUE;
538 }
539 FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCSTR filename)
540 {
541     if (!filename) {
542         return FALSE;
543     }
544     if (m_pFile && m_bTakeover) {
545         m_pFile->Release();
546     }
547     m_pFile = FX_CreateFileWrite(filename);
548     if (!m_pFile) {
549         return FALSE;
550     }
551     m_bTakeover = TRUE;
552     return TRUE;
553 }
554 FX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size)
555 {
556     if (!m_pFile) {
557         return FALSE;
558     }
559     if (!pBuf || size < 1) {
560         return TRUE;
561     }
562     return m_pFile->WriteBlock(pBuf, size);
563 }