1*f6dc9357SAndroid Build Coastguard Worker // InBuffer.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/Alloc.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "InBuffer.h"
8*f6dc9357SAndroid Build Coastguard Worker
CInBufferBase()9*f6dc9357SAndroid Build Coastguard Worker CInBufferBase::CInBufferBase() throw():
10*f6dc9357SAndroid Build Coastguard Worker _buf(NULL),
11*f6dc9357SAndroid Build Coastguard Worker _bufLim(NULL),
12*f6dc9357SAndroid Build Coastguard Worker _bufBase(NULL),
13*f6dc9357SAndroid Build Coastguard Worker _stream(NULL),
14*f6dc9357SAndroid Build Coastguard Worker _processedSize(0),
15*f6dc9357SAndroid Build Coastguard Worker _bufSize(0),
16*f6dc9357SAndroid Build Coastguard Worker _wasFinished(false),
17*f6dc9357SAndroid Build Coastguard Worker NumExtraBytes(0)
18*f6dc9357SAndroid Build Coastguard Worker {}
19*f6dc9357SAndroid Build Coastguard Worker
Create(size_t bufSize)20*f6dc9357SAndroid Build Coastguard Worker bool CInBuffer::Create(size_t bufSize) throw()
21*f6dc9357SAndroid Build Coastguard Worker {
22*f6dc9357SAndroid Build Coastguard Worker const unsigned kMinBlockSize = 1;
23*f6dc9357SAndroid Build Coastguard Worker if (bufSize < kMinBlockSize)
24*f6dc9357SAndroid Build Coastguard Worker bufSize = kMinBlockSize;
25*f6dc9357SAndroid Build Coastguard Worker if (_bufBase != NULL && _bufSize == bufSize)
26*f6dc9357SAndroid Build Coastguard Worker return true;
27*f6dc9357SAndroid Build Coastguard Worker Free();
28*f6dc9357SAndroid Build Coastguard Worker _bufSize = bufSize;
29*f6dc9357SAndroid Build Coastguard Worker _bufBase = (Byte *)::MidAlloc(bufSize);
30*f6dc9357SAndroid Build Coastguard Worker return (_bufBase != NULL);
31*f6dc9357SAndroid Build Coastguard Worker }
32*f6dc9357SAndroid Build Coastguard Worker
Free()33*f6dc9357SAndroid Build Coastguard Worker void CInBuffer::Free() throw()
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker ::MidFree(_bufBase);
36*f6dc9357SAndroid Build Coastguard Worker _bufBase = NULL;
37*f6dc9357SAndroid Build Coastguard Worker }
38*f6dc9357SAndroid Build Coastguard Worker
Init()39*f6dc9357SAndroid Build Coastguard Worker void CInBufferBase::Init() throw()
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker _processedSize = 0;
42*f6dc9357SAndroid Build Coastguard Worker _buf = _bufBase;
43*f6dc9357SAndroid Build Coastguard Worker _bufLim = _buf;
44*f6dc9357SAndroid Build Coastguard Worker _wasFinished = false;
45*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_NO_EXCEPTIONS
46*f6dc9357SAndroid Build Coastguard Worker ErrorCode = S_OK;
47*f6dc9357SAndroid Build Coastguard Worker #endif
48*f6dc9357SAndroid Build Coastguard Worker NumExtraBytes = 0;
49*f6dc9357SAndroid Build Coastguard Worker }
50*f6dc9357SAndroid Build Coastguard Worker
ReadBlock()51*f6dc9357SAndroid Build Coastguard Worker bool CInBufferBase::ReadBlock()
52*f6dc9357SAndroid Build Coastguard Worker {
53*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_NO_EXCEPTIONS
54*f6dc9357SAndroid Build Coastguard Worker if (ErrorCode != S_OK)
55*f6dc9357SAndroid Build Coastguard Worker return false;
56*f6dc9357SAndroid Build Coastguard Worker #endif
57*f6dc9357SAndroid Build Coastguard Worker if (_wasFinished)
58*f6dc9357SAndroid Build Coastguard Worker return false;
59*f6dc9357SAndroid Build Coastguard Worker _processedSize += (size_t)(_buf - _bufBase);
60*f6dc9357SAndroid Build Coastguard Worker _buf = _bufBase;
61*f6dc9357SAndroid Build Coastguard Worker _bufLim = _bufBase;
62*f6dc9357SAndroid Build Coastguard Worker UInt32 processed;
63*f6dc9357SAndroid Build Coastguard Worker // FIX_ME: we can improve it to support (_bufSize >= (1 << 32))
64*f6dc9357SAndroid Build Coastguard Worker const HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed);
65*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_NO_EXCEPTIONS
66*f6dc9357SAndroid Build Coastguard Worker ErrorCode = result;
67*f6dc9357SAndroid Build Coastguard Worker #else
68*f6dc9357SAndroid Build Coastguard Worker if (result != S_OK)
69*f6dc9357SAndroid Build Coastguard Worker throw CInBufferException(result);
70*f6dc9357SAndroid Build Coastguard Worker #endif
71*f6dc9357SAndroid Build Coastguard Worker _bufLim = _buf + processed;
72*f6dc9357SAndroid Build Coastguard Worker _wasFinished = (processed == 0);
73*f6dc9357SAndroid Build Coastguard Worker return !_wasFinished;
74*f6dc9357SAndroid Build Coastguard Worker }
75*f6dc9357SAndroid Build Coastguard Worker
ReadByte_FromNewBlock(Byte & b)76*f6dc9357SAndroid Build Coastguard Worker bool CInBufferBase::ReadByte_FromNewBlock(Byte &b)
77*f6dc9357SAndroid Build Coastguard Worker {
78*f6dc9357SAndroid Build Coastguard Worker if (!ReadBlock())
79*f6dc9357SAndroid Build Coastguard Worker {
80*f6dc9357SAndroid Build Coastguard Worker // 22.00: we don't increment (NumExtraBytes) here
81*f6dc9357SAndroid Build Coastguard Worker // NumExtraBytes++;
82*f6dc9357SAndroid Build Coastguard Worker b = 0xFF;
83*f6dc9357SAndroid Build Coastguard Worker return false;
84*f6dc9357SAndroid Build Coastguard Worker }
85*f6dc9357SAndroid Build Coastguard Worker b = *_buf++;
86*f6dc9357SAndroid Build Coastguard Worker return true;
87*f6dc9357SAndroid Build Coastguard Worker }
88*f6dc9357SAndroid Build Coastguard Worker
ReadByte_FromNewBlock()89*f6dc9357SAndroid Build Coastguard Worker Byte CInBufferBase::ReadByte_FromNewBlock()
90*f6dc9357SAndroid Build Coastguard Worker {
91*f6dc9357SAndroid Build Coastguard Worker if (!ReadBlock())
92*f6dc9357SAndroid Build Coastguard Worker {
93*f6dc9357SAndroid Build Coastguard Worker NumExtraBytes++;
94*f6dc9357SAndroid Build Coastguard Worker return 0xFF;
95*f6dc9357SAndroid Build Coastguard Worker }
96*f6dc9357SAndroid Build Coastguard Worker return *_buf++;
97*f6dc9357SAndroid Build Coastguard Worker }
98*f6dc9357SAndroid Build Coastguard Worker
ReadBytesPart(Byte * buf,size_t size)99*f6dc9357SAndroid Build Coastguard Worker size_t CInBufferBase::ReadBytesPart(Byte *buf, size_t size)
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker if (size == 0)
102*f6dc9357SAndroid Build Coastguard Worker return 0;
103*f6dc9357SAndroid Build Coastguard Worker size_t rem = (size_t)(_bufLim - _buf);
104*f6dc9357SAndroid Build Coastguard Worker if (rem == 0)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker if (!ReadBlock())
107*f6dc9357SAndroid Build Coastguard Worker return 0;
108*f6dc9357SAndroid Build Coastguard Worker rem = (size_t)(_bufLim - _buf);
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker if (size > rem)
111*f6dc9357SAndroid Build Coastguard Worker size = rem;
112*f6dc9357SAndroid Build Coastguard Worker memcpy(buf, _buf, size);
113*f6dc9357SAndroid Build Coastguard Worker _buf += size;
114*f6dc9357SAndroid Build Coastguard Worker return size;
115*f6dc9357SAndroid Build Coastguard Worker }
116*f6dc9357SAndroid Build Coastguard Worker
ReadBytes(Byte * buf,size_t size)117*f6dc9357SAndroid Build Coastguard Worker size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
118*f6dc9357SAndroid Build Coastguard Worker {
119*f6dc9357SAndroid Build Coastguard Worker size_t num = 0;
120*f6dc9357SAndroid Build Coastguard Worker for (;;)
121*f6dc9357SAndroid Build Coastguard Worker {
122*f6dc9357SAndroid Build Coastguard Worker const size_t rem = (size_t)(_bufLim - _buf);
123*f6dc9357SAndroid Build Coastguard Worker if (size <= rem)
124*f6dc9357SAndroid Build Coastguard Worker {
125*f6dc9357SAndroid Build Coastguard Worker if (size != 0)
126*f6dc9357SAndroid Build Coastguard Worker {
127*f6dc9357SAndroid Build Coastguard Worker memcpy(buf, _buf, size);
128*f6dc9357SAndroid Build Coastguard Worker _buf += size;
129*f6dc9357SAndroid Build Coastguard Worker num += size;
130*f6dc9357SAndroid Build Coastguard Worker }
131*f6dc9357SAndroid Build Coastguard Worker return num;
132*f6dc9357SAndroid Build Coastguard Worker }
133*f6dc9357SAndroid Build Coastguard Worker if (rem != 0)
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker memcpy(buf, _buf, rem);
136*f6dc9357SAndroid Build Coastguard Worker _buf += rem;
137*f6dc9357SAndroid Build Coastguard Worker buf += rem;
138*f6dc9357SAndroid Build Coastguard Worker num += rem;
139*f6dc9357SAndroid Build Coastguard Worker size -= rem;
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker if (!ReadBlock())
142*f6dc9357SAndroid Build Coastguard Worker return num;
143*f6dc9357SAndroid Build Coastguard Worker }
144*f6dc9357SAndroid Build Coastguard Worker
145*f6dc9357SAndroid Build Coastguard Worker /*
146*f6dc9357SAndroid Build Coastguard Worker if ((size_t)(_bufLim - _buf) >= size)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker const Byte *src = _buf;
149*f6dc9357SAndroid Build Coastguard Worker for (size_t i = 0; i < size; i++)
150*f6dc9357SAndroid Build Coastguard Worker buf[i] = src[i];
151*f6dc9357SAndroid Build Coastguard Worker _buf += size;
152*f6dc9357SAndroid Build Coastguard Worker return size;
153*f6dc9357SAndroid Build Coastguard Worker }
154*f6dc9357SAndroid Build Coastguard Worker for (size_t i = 0; i < size; i++)
155*f6dc9357SAndroid Build Coastguard Worker {
156*f6dc9357SAndroid Build Coastguard Worker if (_buf >= _bufLim)
157*f6dc9357SAndroid Build Coastguard Worker if (!ReadBlock())
158*f6dc9357SAndroid Build Coastguard Worker return i;
159*f6dc9357SAndroid Build Coastguard Worker buf[i] = *_buf++;
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker return size;
162*f6dc9357SAndroid Build Coastguard Worker */
163*f6dc9357SAndroid Build Coastguard Worker }
164*f6dc9357SAndroid Build Coastguard Worker
Skip(size_t size)165*f6dc9357SAndroid Build Coastguard Worker size_t CInBufferBase::Skip(size_t size)
166*f6dc9357SAndroid Build Coastguard Worker {
167*f6dc9357SAndroid Build Coastguard Worker size_t processed = 0;
168*f6dc9357SAndroid Build Coastguard Worker for (;;)
169*f6dc9357SAndroid Build Coastguard Worker {
170*f6dc9357SAndroid Build Coastguard Worker const size_t rem = (size_t)(_bufLim - _buf);
171*f6dc9357SAndroid Build Coastguard Worker if (rem >= size)
172*f6dc9357SAndroid Build Coastguard Worker {
173*f6dc9357SAndroid Build Coastguard Worker _buf += size;
174*f6dc9357SAndroid Build Coastguard Worker return processed + size;
175*f6dc9357SAndroid Build Coastguard Worker }
176*f6dc9357SAndroid Build Coastguard Worker _buf += rem;
177*f6dc9357SAndroid Build Coastguard Worker processed += rem;
178*f6dc9357SAndroid Build Coastguard Worker size -= rem;
179*f6dc9357SAndroid Build Coastguard Worker if (!ReadBlock())
180*f6dc9357SAndroid Build Coastguard Worker return processed;
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker }
183