blob: 20b0859ce243c57e173d9a8cfe17ed0cca10ddcb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include "Portable.h"
#include "WindowIn.h"
namespace NStream {
namespace NWindow {
CIn::CIn():
m_BufferBase(0)
{}
void CIn::Free()
{
delete []m_BufferBase;
m_BufferBase = 0;
}
void CIn::Create(UINT32 aKeepSizeBefore, UINT32 aKeepSizeAfter, UINT32 aKeepSizeReserv)
{
m_KeepSizeBefore = aKeepSizeBefore;
m_KeepSizeAfter = aKeepSizeAfter;
m_KeepSizeReserv = aKeepSizeReserv;
m_BlockSize = aKeepSizeBefore + aKeepSizeAfter + aKeepSizeReserv;
Free();
m_BufferBase = new BYTE[m_BlockSize];
m_PointerToLastSafePosition = m_BufferBase + m_BlockSize - aKeepSizeAfter;
}
CIn::~CIn()
{
Free();
}
HRESULT CIn::Init(ISequentialInStream *aStream)
{
m_Stream = aStream;
m_Buffer = m_BufferBase;
m_Pos = 0;
m_StreamPos = 0;
m_StreamEndWasReached = false;
return ReadBlock();
}
///////////////////////////////////////////
// ReadBlock
// In State:
// (m_Buffer + m_StreamPos) <= (m_BufferBase + m_BlockSize)
// Out State:
// m_PosLimit <= m_BlockSize - m_KeepSizeAfter;
// if(m_StreamEndWasReached == false):
// m_StreamPos >= m_Pos + m_KeepSizeAfter
// m_PosLimit = m_StreamPos - m_KeepSizeAfter;
// else
//
HRESULT CIn::ReadBlock()
{
if(m_StreamEndWasReached)
return S_OK;
while(true)
{
UINT32 aSize = (m_BufferBase + m_BlockSize) - (m_Buffer + m_StreamPos);
if(aSize == 0)
return S_OK;
UINT32 aNumReadBytes;
RETURN_IF_NOT_S_OK(m_Stream->Read(m_Buffer + m_StreamPos,
aSize, &aNumReadBytes));
if(aNumReadBytes == 0)
{
m_PosLimit = m_StreamPos;
const BYTE *aPointerToPostion = m_Buffer + m_PosLimit;
if(aPointerToPostion > m_PointerToLastSafePosition)
m_PosLimit = m_PointerToLastSafePosition - m_Buffer;
m_StreamEndWasReached = true;
return S_OK;
}
m_StreamPos += aNumReadBytes;
if(m_StreamPos >= m_Pos + m_KeepSizeAfter)
{
m_PosLimit = m_StreamPos - m_KeepSizeAfter;
return S_OK;
}
}
}
void CIn::MoveBlock()
{
BeforeMoveBlock();
UINT32 anOffset = (m_Buffer + m_Pos - m_KeepSizeBefore) - m_BufferBase;
UINT32 aNumBytes = (m_Buffer + m_StreamPos) - (m_BufferBase + anOffset);
memmove(m_BufferBase, m_BufferBase + anOffset, aNumBytes);
m_Buffer -= anOffset;
AfterMoveBlock();
}
}}
|