Since some people disapprove of white space cleanups mixed in regular commits
[coreboot.git] / util / cbfstool / lzma / C / 7zip / Compress / LZ / LZInWindow.cpp
1 // LZInWindow.cpp
2
3 #include "StdAfx.h"
4
5 #include "LZInWindow.h"
6 #include "../../../Common/MyCom.h"
7 #include "../../../Common/Alloc.h"
8
9 void CLZInWindow::Free()
10 {
11   ::BigFree(_bufferBase);
12   _bufferBase = 0;
13 }
14
15 bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
16 {
17   _keepSizeBefore = keepSizeBefore;
18   _keepSizeAfter = keepSizeAfter;
19   UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
20   if (_bufferBase == 0 || _blockSize != blockSize)
21   {
22     Free();
23     _blockSize = blockSize;
24     if (_blockSize != 0)
25       _bufferBase = (Byte *)::BigAlloc(_blockSize);
26   }
27   _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
28   if (_blockSize == 0)
29     return true;
30   return (_bufferBase != 0);
31 }
32
33 void CLZInWindow::SetStream(ISequentialInStream *stream)
34 {
35   _stream = stream;
36 }
37
38 HRESULT CLZInWindow::Init()
39 {
40   _buffer = _bufferBase;
41   _pos = 0;
42   _streamPos = 0;
43   _streamEndWasReached = false;
44   return ReadBlock();
45 }
46
47 /*
48 void CLZInWindow::ReleaseStream()
49 {
50   _stream.Release();
51 }
52 */
53
54 ///////////////////////////////////////////
55 // ReadBlock
56
57 // In State:
58 //   (_buffer + _streamPos) <= (_bufferBase + _blockSize)
59 // Out State:
60 //   _posLimit <= _blockSize - _keepSizeAfter;
61 //   if(_streamEndWasReached == false):
62 //     _streamPos >= _pos + _keepSizeAfter
63 //     _posLimit = _streamPos - _keepSizeAfter;
64 //   else
65 //
66
67 HRESULT CLZInWindow::ReadBlock()
68 {
69   if(_streamEndWasReached)
70     return S_OK;
71   while(true)
72   {
73     UInt32 size = (UInt32)(_bufferBase - _buffer) + _blockSize - _streamPos;
74     if(size == 0)
75       return S_OK;
76     UInt32 numReadBytes;
77     RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes));
78     if(numReadBytes == 0)
79     {
80       _posLimit = _streamPos;
81       const Byte *pointerToPostion = _buffer + _posLimit;
82       if(pointerToPostion > _pointerToLastSafePosition)
83         _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer);
84       _streamEndWasReached = true;
85       return S_OK;
86     }
87     _streamPos += numReadBytes;
88     if(_streamPos >= _pos + _keepSizeAfter)
89     {
90       _posLimit = _streamPos - _keepSizeAfter;
91       return S_OK;
92     }
93   }
94 }
95
96 void CLZInWindow::MoveBlock()
97 {
98   UInt32 offset = (UInt32)(_buffer - _bufferBase) + _pos - _keepSizeBefore;
99   // we need one additional byte, since MovePos moves on 1 byte.
100   if (offset > 0)
101     offset--;
102   UInt32 numBytes = (UInt32)(_buffer - _bufferBase) + _streamPos -  offset;
103   memmove(_bufferBase, _bufferBase + offset, numBytes);
104   _buffer -= offset;
105 }