xref: /aosp_15_r20/external/lzma/CPP/7zip/Common/InBuffer.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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