Mercurial > vba-linux
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Common/OutMemStream.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,142 @@ 1.4 +// OutMemStream.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "OutMemStream.h" 1.9 + 1.10 +void COutMemStream::Free() 1.11 +{ 1.12 + Blocks.Free(_memManager); 1.13 + Blocks.LockMode = true; 1.14 +} 1.15 + 1.16 +void COutMemStream::Init() 1.17 +{ 1.18 + WriteToRealStreamEvent.Reset(); 1.19 + _unlockEventWasSent = false; 1.20 + _realStreamMode = false; 1.21 + Free(); 1.22 + _curBlockPos = 0; 1.23 + _curBlockIndex = 0; 1.24 +} 1.25 + 1.26 +void COutMemStream::DetachData(CMemLockBlocks &blocks) 1.27 +{ 1.28 + Blocks.Detach(blocks, _memManager); 1.29 + Free(); 1.30 +} 1.31 + 1.32 + 1.33 +HRESULT COutMemStream::WriteToRealStream() 1.34 +{ 1.35 + RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)); 1.36 + Blocks.Free(_memManager); 1.37 + return S_OK; 1.38 +} 1.39 + 1.40 +STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize) 1.41 +{ 1.42 + if (_realStreamMode) 1.43 + return OutSeqStream->Write(data, size, processedSize); 1.44 + if (processedSize != 0) 1.45 + *processedSize = 0; 1.46 + while(size != 0) 1.47 + { 1.48 + if ((int)_curBlockIndex < Blocks.Blocks.Size()) 1.49 + { 1.50 + Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos; 1.51 + size_t curSize = _memManager->GetBlockSize() - _curBlockPos; 1.52 + if (size < curSize) 1.53 + curSize = size; 1.54 + memmove(p, data, curSize); 1.55 + if (processedSize != 0) 1.56 + *processedSize += (UInt32)curSize; 1.57 + data = (const void *)((const Byte *)data + curSize); 1.58 + size -= (UInt32)curSize; 1.59 + _curBlockPos += curSize; 1.60 + 1.61 + UInt64 pos64 = GetPos(); 1.62 + if (pos64 > Blocks.TotalSize) 1.63 + Blocks.TotalSize = pos64; 1.64 + if (_curBlockPos == _memManager->GetBlockSize()) 1.65 + { 1.66 + _curBlockIndex++; 1.67 + _curBlockPos = 0; 1.68 + } 1.69 + continue; 1.70 + } 1.71 + HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore }; 1.72 + DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE); 1.73 + switch (waitResult) 1.74 + { 1.75 + case (WAIT_OBJECT_0 + 0): 1.76 + return StopWriteResult; 1.77 + case (WAIT_OBJECT_0 + 1): 1.78 + { 1.79 + _realStreamMode = true; 1.80 + RINOK(WriteToRealStream()); 1.81 + UInt32 processedSize2; 1.82 + HRESULT res = OutSeqStream->Write(data, size, &processedSize2); 1.83 + if (processedSize != 0) 1.84 + *processedSize += processedSize2; 1.85 + return res; 1.86 + } 1.87 + /* 1.88 + case (WAIT_OBJECT_0 + 2): 1.89 + { 1.90 + // it has bug: no write. 1.91 + if (!Blocks.SwitchToNoLockMode(_memManager)) 1.92 + return E_FAIL; 1.93 + break; 1.94 + } 1.95 + */ 1.96 + case (WAIT_OBJECT_0 + 2): 1.97 + break; 1.98 + default: 1.99 + return E_FAIL; 1.100 + } 1.101 + Blocks.Blocks.Add(_memManager->AllocateBlock()); 1.102 + if (Blocks.Blocks.Back() == 0) 1.103 + return E_FAIL; 1.104 + } 1.105 + return S_OK; 1.106 +} 1.107 + 1.108 +STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) 1.109 +{ 1.110 + if (_realStreamMode) 1.111 + { 1.112 + if (!OutStream) 1.113 + return E_FAIL; 1.114 + return OutStream->Seek(offset, seekOrigin, newPosition); 1.115 + } 1.116 + if (seekOrigin == STREAM_SEEK_CUR) 1.117 + { 1.118 + if (offset != 0) 1.119 + return E_NOTIMPL; 1.120 + } 1.121 + else if (seekOrigin == STREAM_SEEK_SET) 1.122 + { 1.123 + if (offset != 0) 1.124 + return E_NOTIMPL; 1.125 + _curBlockIndex = 0; 1.126 + _curBlockPos = 0; 1.127 + } 1.128 + else 1.129 + return E_NOTIMPL; 1.130 + if (newPosition != 0) 1.131 + *newPosition = GetPos(); 1.132 + return S_OK; 1.133 +} 1.134 + 1.135 +STDMETHODIMP COutMemStream::SetSize(Int64 newSize) 1.136 +{ 1.137 + if (_realStreamMode) 1.138 + { 1.139 + if (!OutStream) 1.140 + return E_FAIL; 1.141 + return OutStream->SetSize(newSize); 1.142 + } 1.143 + Blocks.TotalSize = newSize; 1.144 + return S_OK; 1.145 +}