• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(0),
11   _bufLim(0),
12   _bufBase(0),
13   _stream(0),
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 != 0 && _bufSize == bufSize)
26     return true;
27   Free();
28   _bufSize = bufSize;
29   _bufBase = (Byte *)::MidAlloc(bufSize);
30   return (_bufBase != 0);
31 }
32 
Free()33 void CInBuffer::Free() throw()
34 {
35   ::MidFree(_bufBase);
36   _bufBase = 0;
37 }
38 
Init()39 void CInBufferBase::Init() throw()
40 {
41   _processedSize = 0;
42   _buf = _bufBase;
43   _bufLim = _buf;
44   _wasFinished = false;
45   #ifdef _NO_EXCEPTIONS
46   ErrorCode = S_OK;
47   #endif
48   NumExtraBytes = 0;
49 }
50 
ReadBlock()51 bool CInBufferBase::ReadBlock()
52 {
53   #ifdef _NO_EXCEPTIONS
54   if (ErrorCode != S_OK)
55     return false;
56   #endif
57   if (_wasFinished)
58     return false;
59   _processedSize += (_buf - _bufBase);
60   _buf = _bufBase;
61   _bufLim = _bufBase;
62   UInt32 processed;
63   // FIX_ME: we can improve it to support (_bufSize >= (1 << 32))
64   HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed);
65   #ifdef _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     NumExtraBytes++;
81     b = 0xFF;
82     return false;
83   }
84   b = *_buf++;
85   return true;
86 }
87 
ReadByte_FromNewBlock()88 Byte CInBufferBase::ReadByte_FromNewBlock()
89 {
90   if (!ReadBlock())
91   {
92     NumExtraBytes++;
93     return 0xFF;
94   }
95   return *_buf++;
96 }
97 
ReadBytes(Byte * buf,size_t size)98 size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)
99 {
100   size_t num = 0;
101   for (;;)
102   {
103     const size_t rem = _bufLim - _buf;
104     if (size <= rem)
105     {
106       if (size != 0)
107       {
108         memcpy(buf, _buf, size);
109         _buf += size;
110         num += size;
111       }
112       return num;
113     }
114     if (rem != 0)
115     {
116       memcpy(buf, _buf, rem);
117       _buf += rem;
118       buf += rem;
119       num += rem;
120       size -= rem;
121     }
122     if (!ReadBlock())
123       return num;
124   }
125 
126   /*
127   if ((size_t)(_bufLim - _buf) >= size)
128   {
129     const Byte *src = _buf;
130     for (size_t i = 0; i < size; i++)
131       buf[i] = src[i];
132     _buf += size;
133     return size;
134   }
135   for (size_t i = 0; i < size; i++)
136   {
137     if (_buf >= _bufLim)
138       if (!ReadBlock())
139         return i;
140     buf[i] = *_buf++;
141   }
142   return size;
143   */
144 }
145 
Skip(size_t size)146 size_t CInBufferBase::Skip(size_t size)
147 {
148   size_t processed = 0;
149   for (;;)
150   {
151     size_t rem = (_bufLim - _buf);
152     if (rem >= size)
153     {
154       _buf += size;
155       return processed + size;
156     }
157     _buf += rem;
158     processed += rem;
159     size -= rem;
160     if (!ReadBlock())
161       return processed;
162   }
163 }
164