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