1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/fxcrt/fx_basic.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_BinaryBuf::CFX_BinaryBuf(IFX_Allocator* pAllocator)
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pAllocator(pAllocator)
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_AllocStep(0)
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pBuffer(NULL)
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_DataSize(0)
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_AllocSize(0)
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_BinaryBuf::CFX_BinaryBuf(FX_STRSIZE size, IFX_Allocator* pAllocator)
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pAllocator(pAllocator)
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_AllocStep(0)
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_DataSize(size)
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_AllocSize(size)
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, size);
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_BinaryBuf::~CFX_BinaryBuf()
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer) {
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pBuffer);
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::Delete(int start_index, int count)
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pBuffer || start_index < 0 || start_index + count > m_DataSize) {
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memmove32(m_pBuffer + start_index, m_pBuffer + start_index + count, m_DataSize - start_index - count);
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize -= count;
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::Clear()
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize = 0;
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::DetachBuffer()
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize = 0;
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = NULL;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_AllocSize = 0;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::AttachData(void* buffer, FX_STRSIZE size)
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer) {
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pBuffer);
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize = size;
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBuffer = (FX_LPBYTE)buffer;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_AllocSize = size;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other)
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AttachData(other.GetBuffer(), other.GetSize());
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    other.DetachBuffer();
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::EstimateSize(FX_STRSIZE size, FX_STRSIZE step)
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_AllocStep = step;
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocSize >= size) {
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ExpandBuf(size - m_DataSize);
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::ExpandBuf(FX_STRSIZE add_size)
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_STRSIZE new_size = add_size + m_DataSize;
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocSize >= new_size) {
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int alloc_step;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocStep == 0) {
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        alloc_step = m_AllocSize / 4;
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (alloc_step < 128 ) {
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            alloc_step = 128;
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        alloc_step = m_AllocStep;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    new_size = (new_size + alloc_step - 1) / alloc_step * alloc_step;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE pNewBuffer = m_pBuffer;
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pNewBuffer) {
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pNewBuffer = FX_Allocator_Realloc(m_pAllocator, FX_BYTE, m_pBuffer, new_size);
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pNewBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, new_size);
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pNewBuffer) {
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBuffer = pNewBuffer;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_AllocSize = new_size;
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::CopyData(const void* pStr, FX_STRSIZE size)
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (size == 0) {
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_DataSize = 0;
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocSize < size) {
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ExpandBuf(size - m_DataSize);
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pBuffer) {
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(m_pBuffer, pStr, size);
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize = size;
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::AppendBlock(const void* pBuf, FX_STRSIZE size)
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ExpandBuf(size);
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBuf && m_pBuffer) {
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(m_pBuffer + m_DataSize, pBuf, size);
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize += size;
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size)
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ExpandBuf(size);
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pBuffer) {
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memmove32(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos);
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBuf) {
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(m_pBuffer + pos, pBuf, size);
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize += size;
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::AppendFill(FX_BYTE byte, FX_STRSIZE count)
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ExpandBuf(count);
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pBuffer) {
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset8(m_pBuffer + m_DataSize, byte, count);
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize += count;
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteStringC CFX_BinaryBuf::GetByteString() const
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return CFX_ByteStringC(m_pBuffer, m_DataSize);
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BinaryBuf::GetByteStringL(CFX_ByteStringL &str) const
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    str.Set(CFX_ByteStringC(m_pBuffer, m_DataSize), m_pAllocator);
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz)
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteTextBuf& CFX_ByteTextBuf::operator << (int i)
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char buf[32];
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_itoa(i, buf, 10);
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_DWORD i)
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char buf[32];
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_itoa(i, buf, 10);
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteTextBuf& CFX_ByteTextBuf::operator << (double f)
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char buf[32];
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(buf, len);
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf)
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(buf.m_pBuffer, buf.m_DataSize);
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str)
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CopyData((FX_LPCBYTE)str, str.GetLength());
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_WideTextBuf::AppendChar(FX_WCHAR ch)
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocSize < m_DataSize + (FX_STRSIZE)sizeof(FX_WCHAR)) {
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ExpandBuf(sizeof(FX_WCHAR));
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pBuffer != NULL);
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *(FX_WCHAR*)(m_pBuffer + m_DataSize) = ch;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize += sizeof(FX_WCHAR);
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str)
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str)
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock((FX_LPCWSTR)str, str.GetLength() * sizeof(FX_WCHAR));
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideTextBuf& CFX_WideTextBuf::operator << (int i)
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char buf[32];
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_itoa(i, buf, 10);
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_STRSIZE len = (FX_STRSIZE)FXSYS_strlen(buf);
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ExpandBuf(len * sizeof(FX_WCHAR));
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pBuffer != NULL);
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_STRSIZE j = 0; j < len; j ++) {
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *str ++ = buf[j];
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize += len * sizeof(FX_WCHAR);
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideTextBuf& CFX_WideTextBuf::operator << (double f)
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char buf[32];
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ExpandBuf(len * sizeof(FX_WCHAR));
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pBuffer != NULL);
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_STRSIZE i = 0; i < len; i ++) {
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *str ++ = buf[i];
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DataSize += len * sizeof(FX_WCHAR);
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz)
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(lpsz, (FX_STRSIZE)FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR));
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf)
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendBlock(buf.m_pBuffer, buf.m_DataSize);
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_WideTextBuf::operator =(FX_WSTR str)
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_WideStringC CFX_WideTextBuf::GetWideString() const
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_WideTextBuf::GetWideStringL(CFX_WideStringL& wideText) const
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    wideText.Set(CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR)), m_pAllocator);
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BYTE i)
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(&i, 1);
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendByte(i);
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (int i)
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(&i, sizeof(int));
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(&i, sizeof(int));
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_DWORD i)
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(&i, sizeof(FX_DWORD));
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(&i, sizeof(FX_DWORD));
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_FLOAT f)
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(&f, sizeof(FX_FLOAT));
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(&f, sizeof(FX_FLOAT));
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BSTR bstr)
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int len = bstr.GetLength();
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(&len, sizeof(int));
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(bstr, len);
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(&len, sizeof(int));
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(bstr, len);
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_LPCWSTR wstr)
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_STRSIZE len = (FX_STRSIZE)FXSYS_wcslen(wstr);
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(&len, sizeof(int));
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(wstr, len);
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(&len, sizeof(int));
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(wstr, len);
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr)
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString encoded = wstr.UTF16LE_Encode();
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return operator << (encoded);
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ArchiveSaver::Write(const void* pData, FX_STRSIZE dwSize)
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pStream) {
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pStream->WriteBlock(pData, dwSize);
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_SavingBuf.AppendBlock(pData, dwSize);
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize)
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pLoadingBuf = pData;
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LoadingPos = 0;
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LoadingSize = dwSize;
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_ArchiveLoader::IsEOF()
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_LoadingPos >= m_LoadingSize;
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_BYTE& i)
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_LoadingPos >= m_LoadingSize) {
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return *this;
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    i = m_pLoadingBuf[m_LoadingPos++];
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i)
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Read(&i, sizeof(int));
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i)
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Read(&i, sizeof(FX_DWORD));
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i)
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Read(&i, sizeof(FX_FLOAT));
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_ByteString& str)
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_LoadingPos + 4 > m_LoadingSize) {
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return *this;
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int len;
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    operator >> (len);
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    str.Empty();
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (len <= 0 || m_LoadingPos + len > m_LoadingSize) {
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return *this;
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPSTR buffer = str.GetBuffer(len);
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(buffer, m_pLoadingBuf + m_LoadingPos, len);
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    str.ReleaseBuffer(len);
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LoadingPos += len;
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_WideString& str)
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString encoded;
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    operator >> (encoded);
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    str = CFX_WideString::FromUTF16LE((const unsigned short*)(FX_LPCSTR)encoded, encoded.GetLength());
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *this;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_ArchiveLoader::Read(void* pBuf, FX_DWORD dwSize)
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_LoadingPos + dwSize > m_LoadingSize) {
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize);
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LoadingPos += dwSize;
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize)
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pData = pData;
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BitSize = dwSize * 8;
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BitPos = 0;
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_BitStream::ByteAlign()
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int mod = m_BitPos % 8;
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (mod == 0) {
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BitPos += 8 - mod;
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits)
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) {
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nBits == 1) {
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0;
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_BitPos ++;
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return bit;
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD byte_pos = m_BitPos / 8;
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits;
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD result = 0;
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bit_pos) {
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (8 - bit_pos >= bit_left) {
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            result = (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left);
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_BitPos += bit_left;
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return result;
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bit_left -= 8 - bit_pos;
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (bit_left >= 8) {
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bit_left -= 8;
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        result |= m_pData[byte_pos++] << bit_left;
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bit_left) {
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        result |= m_pData[byte_pos] >> (8 - bit_left);
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BitPos += nBits;
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return result;
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator)
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pAllocator(pAllocator)
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_BufSize(size)
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pBuffer(NULL)
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_Length(0)
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid IFX_BufferArchive::Clear()
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Length = 0;
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBuffer) {
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pBuffer);
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBuffer = NULL;
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL IFX_BufferArchive::Flush()
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Length = 0;
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return bRet;
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_INT32 IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size)
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pBuf || size < 1) {
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pBuffer) {
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, m_BufSize);
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pBuffer) {
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE buffer = (FX_LPBYTE)pBuf;
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_STRSIZE temp_size = (FX_STRSIZE)size;
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (temp_size > 0) {
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_STRSIZE buf_size = FX_MIN(m_BufSize - m_Length, (FX_STRSIZE)temp_size);
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(m_pBuffer + m_Length, buffer, buf_size);
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Length += buf_size;
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Length == m_BufSize) {
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!Flush()) {
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return -1;
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        temp_size -= buf_size;
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        buffer += buf_size;
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (FX_INT32)size;
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte)
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AppendBlock(&byte, 1);
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_INT32 IFX_BufferArchive::AppendDWord(FX_DWORD i)
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char buf[32];
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_itoa(i, buf, 10);
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AppendBlock(buf, (size_t)FXSYS_strlen(buf));
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz)
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator)
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : IFX_BufferArchive(size, pAllocator)
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pFile(NULL)
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_bTakeover(FALSE)
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_FileBufferArchive::~CFX_FileBufferArchive()
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Clear();
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_FileBufferArchive::Clear()
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFile && m_bTakeover) {
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pFile->Release();
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFile = NULL;
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bTakeover = FALSE;
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    IFX_BufferArchive::Clear();
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover )
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pFile) {
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFile && m_bTakeover) {
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pFile->Release();
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFile = pFile;
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bTakeover = bTakeover;
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCWSTR filename)
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!filename) {
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFile && m_bTakeover) {
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pFile->Release();
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFile = FX_CreateFileWrite(filename);
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pFile) {
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bTakeover = TRUE;
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCSTR filename)
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!filename) {
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFile && m_bTakeover) {
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pFile->Release();
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFile = FX_CreateFileWrite(filename);
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pFile) {
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bTakeover = TRUE;
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size)
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pFile) {
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pBuf || size < 1) {
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pFile->WriteBlock(pBuf, size);
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
575