5 #include "OutMemStream.h"
\r
7 void COutMemStream::Free()
\r
9 Blocks.Free(_memManager);
\r
10 Blocks.LockMode = true;
\r
13 void COutMemStream::Init()
\r
15 WriteToRealStreamEvent.Reset();
\r
16 _unlockEventWasSent = false;
\r
17 _realStreamMode = false;
\r
23 void COutMemStream::DetachData(CMemLockBlocks &blocks)
\r
25 Blocks.Detach(blocks, _memManager);
\r
30 HRESULT COutMemStream::WriteToRealStream()
\r
32 RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream));
\r
33 Blocks.Free(_memManager);
\r
37 STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
\r
39 if (_realStreamMode)
\r
40 return OutSeqStream->Write(data, size, processedSize);
\r
41 if (processedSize != 0)
\r
45 if ((int)_curBlockIndex < Blocks.Blocks.Size())
\r
47 Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos;
\r
48 size_t curSize = _memManager->GetBlockSize() - _curBlockPos;
\r
51 memmove(p, data, curSize);
\r
52 if (processedSize != 0)
\r
53 *processedSize += (UInt32)curSize;
\r
54 data = (const void *)((const Byte *)data + curSize);
\r
55 size -= (UInt32)curSize;
\r
56 _curBlockPos += curSize;
\r
58 UInt64 pos64 = GetPos();
\r
59 if (pos64 > Blocks.TotalSize)
\r
60 Blocks.TotalSize = pos64;
\r
61 if (_curBlockPos == _memManager->GetBlockSize())
\r
68 HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore };
\r
69 DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE);
\r
72 case (WAIT_OBJECT_0 + 0):
\r
73 return StopWriteResult;
\r
74 case (WAIT_OBJECT_0 + 1):
\r
76 _realStreamMode = true;
\r
77 RINOK(WriteToRealStream());
\r
78 UInt32 processedSize2;
\r
79 HRESULT res = OutSeqStream->Write(data, size, &processedSize2);
\r
80 if (processedSize != 0)
\r
81 *processedSize += processedSize2;
\r
85 case (WAIT_OBJECT_0 + 2):
\r
87 // it has bug: no write.
\r
88 if (!Blocks.SwitchToNoLockMode(_memManager))
\r
93 case (WAIT_OBJECT_0 + 2):
\r
98 Blocks.Blocks.Add(_memManager->AllocateBlock());
\r
99 if (Blocks.Blocks.Back() == 0)
\r
105 STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
\r
107 if (_realStreamMode)
\r
111 return OutStream->Seek(offset, seekOrigin, newPosition);
\r
113 if (seekOrigin == STREAM_SEEK_CUR)
\r
118 else if (seekOrigin == STREAM_SEEK_SET)
\r
122 _curBlockIndex = 0;
\r
127 if (newPosition != 0)
\r
128 *newPosition = GetPos();
\r
132 STDMETHODIMP COutMemStream::SetSize(UInt64 newSize)
\r
134 if (_realStreamMode)
\r
138 return OutStream->SetSize(newSize);
\r
140 Blocks.TotalSize = newSize;
\r