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