Mercurial > vba-linux
view src/win32/7zip/7z/CPP/7zip/Common/OutMemStream.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 // OutMemStream.cpp3 #include "StdAfx.h"5 #include "OutMemStream.h"7 void COutMemStream::Free()8 {9 Blocks.Free(_memManager);10 Blocks.LockMode = true;11 }13 void COutMemStream::Init()14 {15 WriteToRealStreamEvent.Reset();16 _unlockEventWasSent = false;17 _realStreamMode = false;18 Free();19 _curBlockPos = 0;20 _curBlockIndex = 0;21 }23 void COutMemStream::DetachData(CMemLockBlocks &blocks)24 {25 Blocks.Detach(blocks, _memManager);26 Free();27 }30 HRESULT COutMemStream::WriteToRealStream()31 {32 RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream));33 Blocks.Free(_memManager);34 return S_OK;35 }37 STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize)38 {39 if (_realStreamMode)40 return OutSeqStream->Write(data, size, processedSize);41 if (processedSize != 0)42 *processedSize = 0;43 while(size != 0)44 {45 if ((int)_curBlockIndex < Blocks.Blocks.Size())46 {47 Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos;48 size_t curSize = _memManager->GetBlockSize() - _curBlockPos;49 if (size < curSize)50 curSize = size;51 memmove(p, data, curSize);52 if (processedSize != 0)53 *processedSize += (UInt32)curSize;54 data = (const void *)((const Byte *)data + curSize);55 size -= (UInt32)curSize;56 _curBlockPos += curSize;58 UInt64 pos64 = GetPos();59 if (pos64 > Blocks.TotalSize)60 Blocks.TotalSize = pos64;61 if (_curBlockPos == _memManager->GetBlockSize())62 {63 _curBlockIndex++;64 _curBlockPos = 0;65 }66 continue;67 }68 HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore };69 DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE);70 switch (waitResult)71 {72 case (WAIT_OBJECT_0 + 0):73 return StopWriteResult;74 case (WAIT_OBJECT_0 + 1):75 {76 _realStreamMode = true;77 RINOK(WriteToRealStream());78 UInt32 processedSize2;79 HRESULT res = OutSeqStream->Write(data, size, &processedSize2);80 if (processedSize != 0)81 *processedSize += processedSize2;82 return res;83 }84 /*85 case (WAIT_OBJECT_0 + 2):86 {87 // it has bug: no write.88 if (!Blocks.SwitchToNoLockMode(_memManager))89 return E_FAIL;90 break;91 }92 */93 case (WAIT_OBJECT_0 + 2):94 break;95 default:96 return E_FAIL;97 }98 Blocks.Blocks.Add(_memManager->AllocateBlock());99 if (Blocks.Blocks.Back() == 0)100 return E_FAIL;101 }102 return S_OK;103 }105 STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)106 {107 if (_realStreamMode)108 {109 if (!OutStream)110 return E_FAIL;111 return OutStream->Seek(offset, seekOrigin, newPosition);112 }113 if (seekOrigin == STREAM_SEEK_CUR)114 {115 if (offset != 0)116 return E_NOTIMPL;117 }118 else if (seekOrigin == STREAM_SEEK_SET)119 {120 if (offset != 0)121 return E_NOTIMPL;122 _curBlockIndex = 0;123 _curBlockPos = 0;124 }125 else126 return E_NOTIMPL;127 if (newPosition != 0)128 *newPosition = GetPos();129 return S_OK;130 }132 STDMETHODIMP COutMemStream::SetSize(Int64 newSize)133 {134 if (_realStreamMode)135 {136 if (!OutStream)137 return E_FAIL;138 return OutStream->SetSize(newSize);139 }140 Blocks.TotalSize = newSize;141 return S_OK;142 }