Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Common/StreamBinder.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/StreamBinder.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,150 @@ 1.4 +// StreamBinder.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +#include "StreamBinder.h" 1.9 +#include "../../Common/Defs.h" 1.10 +#include "../../Common/MyCom.h" 1.11 + 1.12 +using namespace NWindows; 1.13 +using namespace NSynchronization; 1.14 + 1.15 +class CSequentialInStreamForBinder: 1.16 + public ISequentialInStream, 1.17 + public CMyUnknownImp 1.18 +{ 1.19 +public: 1.20 + MY_UNKNOWN_IMP 1.21 + 1.22 + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 1.23 +private: 1.24 + CStreamBinder *m_StreamBinder; 1.25 +public: 1.26 + ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); } 1.27 + void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } 1.28 +}; 1.29 + 1.30 +STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize) 1.31 + { return m_StreamBinder->Read(data, size, processedSize); } 1.32 + 1.33 +class CSequentialOutStreamForBinder: 1.34 + public ISequentialOutStream, 1.35 + public CMyUnknownImp 1.36 +{ 1.37 +public: 1.38 + MY_UNKNOWN_IMP 1.39 + 1.40 + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 1.41 + 1.42 +private: 1.43 + CStreamBinder *m_StreamBinder; 1.44 +public: 1.45 + ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); } 1.46 + void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } 1.47 +}; 1.48 + 1.49 +STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) 1.50 + { return m_StreamBinder->Write(data, size, processedSize); } 1.51 + 1.52 + 1.53 +////////////////////////// 1.54 +// CStreamBinder 1.55 +// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished. 1.56 + 1.57 +HRes CStreamBinder::CreateEvents() 1.58 +{ 1.59 + RINOK(_allBytesAreWritenEvent.Create(true)); 1.60 + RINOK(_thereAreBytesToReadEvent.Create()); 1.61 + return _readStreamIsClosedEvent.Create(); 1.62 +} 1.63 + 1.64 +void CStreamBinder::ReInit() 1.65 +{ 1.66 + _thereAreBytesToReadEvent.Reset(); 1.67 + _readStreamIsClosedEvent.Reset(); 1.68 + ProcessedSize = 0; 1.69 +} 1.70 + 1.71 + 1.72 + 1.73 +void CStreamBinder::CreateStreams(ISequentialInStream **inStream, 1.74 + ISequentialOutStream **outStream) 1.75 +{ 1.76 + CSequentialInStreamForBinder *inStreamSpec = new 1.77 + CSequentialInStreamForBinder; 1.78 + CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); 1.79 + inStreamSpec->SetBinder(this); 1.80 + *inStream = inStreamLoc.Detach(); 1.81 + 1.82 + CSequentialOutStreamForBinder *outStreamSpec = new 1.83 + CSequentialOutStreamForBinder; 1.84 + CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec); 1.85 + outStreamSpec->SetBinder(this); 1.86 + *outStream = outStreamLoc.Detach(); 1.87 + 1.88 + _buffer = NULL; 1.89 + _bufferSize= 0; 1.90 + ProcessedSize = 0; 1.91 +} 1.92 + 1.93 +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) 1.94 +{ 1.95 + UInt32 sizeToRead = size; 1.96 + if (size > 0) 1.97 + { 1.98 + RINOK(_thereAreBytesToReadEvent.Lock()); 1.99 + sizeToRead = MyMin(_bufferSize, size); 1.100 + if (_bufferSize > 0) 1.101 + { 1.102 + memcpy(data, _buffer, sizeToRead); 1.103 + _buffer = ((const Byte *)_buffer) + sizeToRead; 1.104 + _bufferSize -= sizeToRead; 1.105 + if (_bufferSize == 0) 1.106 + { 1.107 + _thereAreBytesToReadEvent.Reset(); 1.108 + _allBytesAreWritenEvent.Set(); 1.109 + } 1.110 + } 1.111 + } 1.112 + if (processedSize != NULL) 1.113 + *processedSize = sizeToRead; 1.114 + ProcessedSize += sizeToRead; 1.115 + return S_OK; 1.116 +} 1.117 + 1.118 +void CStreamBinder::CloseRead() 1.119 +{ 1.120 + _readStreamIsClosedEvent.Set(); 1.121 +} 1.122 + 1.123 +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) 1.124 +{ 1.125 + if (size > 0) 1.126 + { 1.127 + _buffer = data; 1.128 + _bufferSize = size; 1.129 + _allBytesAreWritenEvent.Reset(); 1.130 + _thereAreBytesToReadEvent.Set(); 1.131 + 1.132 + HANDLE events[2]; 1.133 + events[0] = _allBytesAreWritenEvent; 1.134 + events[1] = _readStreamIsClosedEvent; 1.135 + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); 1.136 + if (waitResult != WAIT_OBJECT_0 + 0) 1.137 + { 1.138 + // ReadingWasClosed = true; 1.139 + return S_FALSE; 1.140 + } 1.141 + // if(!_allBytesAreWritenEvent.Lock()) 1.142 + // return E_FAIL; 1.143 + } 1.144 + if (processedSize != NULL) 1.145 + *processedSize = size; 1.146 + return S_OK; 1.147 +} 1.148 + 1.149 +void CStreamBinder::CloseWrite() 1.150 +{ 1.151 + // _bufferSize must be = 0 1.152 + _thereAreBytesToReadEvent.Set(); 1.153 +}