From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../7zstub/src/CPP/7zip/Common/StreamBinder.cpp | 156 +++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 other-licenses/7zstub/src/CPP/7zip/Common/StreamBinder.cpp (limited to 'other-licenses/7zstub/src/CPP/7zip/Common/StreamBinder.cpp') diff --git a/other-licenses/7zstub/src/CPP/7zip/Common/StreamBinder.cpp b/other-licenses/7zstub/src/CPP/7zip/Common/StreamBinder.cpp new file mode 100644 index 0000000000..a6627db213 --- /dev/null +++ b/other-licenses/7zstub/src/CPP/7zip/Common/StreamBinder.cpp @@ -0,0 +1,156 @@ +// StreamBinder.cpp + +#include "StdAfx.h" + +#include "../../Common/MyCom.h" + +#include "StreamBinder.h" + +class CBinderInStream: + public ISequentialInStream, + public CMyUnknownImp +{ + CStreamBinder *_binder; +public: + MY_UNKNOWN_IMP1(ISequentialInStream) + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + ~CBinderInStream() { _binder->CloseRead(); } + CBinderInStream(CStreamBinder *binder): _binder(binder) {} +}; + +STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize) + { return _binder->Read(data, size, processedSize); } + +class CBinderOutStream: + public ISequentialOutStream, + public CMyUnknownImp +{ + CStreamBinder *_binder; +public: + MY_UNKNOWN_IMP1(ISequentialOutStream) + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + ~CBinderOutStream() { _binder->CloseWrite(); } + CBinderOutStream(CStreamBinder *binder): _binder(binder) {} +}; + +STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) + { return _binder->Write(data, size, processedSize); } + + + +WRes CStreamBinder::CreateEvents() +{ + RINOK(_canWrite_Event.Create()); + RINOK(_canRead_Event.Create()); + return _readingWasClosed_Event.Create(); +} + +void CStreamBinder::ReInit() +{ + _canWrite_Event.Reset(); + _canRead_Event.Reset(); + _readingWasClosed_Event.Reset(); + + // _readingWasClosed = false; + _readingWasClosed2 = false; + + _waitWrite = true; + _bufSize = 0; + _buf = NULL; + ProcessedSize = 0; + // WritingWasCut = false; +} + + +void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream) +{ + // _readingWasClosed = false; + _readingWasClosed2 = false; + + _waitWrite = true; + _bufSize = 0; + _buf = NULL; + ProcessedSize = 0; + // WritingWasCut = false; + + CBinderInStream *inStreamSpec = new CBinderInStream(this); + CMyComPtr inStreamLoc(inStreamSpec); + *inStream = inStreamLoc.Detach(); + + CBinderOutStream *outStreamSpec = new CBinderOutStream(this); + CMyComPtr outStreamLoc(outStreamSpec); + *outStream = outStreamLoc.Detach(); +} + +// (_canRead_Event && _bufSize == 0) means that stream is finished. + +HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size != 0) + { + if (_waitWrite) + { + RINOK(_canRead_Event.Lock()); + _waitWrite = false; + } + if (size > _bufSize) + size = _bufSize; + if (size != 0) + { + memcpy(data, _buf, size); + _buf = ((const Byte *)_buf) + size; + ProcessedSize += size; + if (processedSize) + *processedSize = size; + _bufSize -= size; + if (_bufSize == 0) + { + _waitWrite = true; + _canRead_Event.Reset(); + _canWrite_Event.Set(); + } + } + } + return S_OK; +} + +HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + + if (!_readingWasClosed2) + { + _buf = data; + _bufSize = size; + _canRead_Event.Set(); + + /* + _canWrite_Event.Lock(); + if (_readingWasClosed) + _readingWasClosed2 = true; + */ + + HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event }; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + if (waitResult >= WAIT_OBJECT_0 + 2) + return E_FAIL; + + size -= _bufSize; + if (size != 0) + { + if (processedSize) + *processedSize = size; + return S_OK; + } + // if (waitResult == WAIT_OBJECT_0 + 1) + _readingWasClosed2 = true; + } + + // WritingWasCut = true; + return k_My_HRESULT_WritingWasCut; +} -- cgit v1.2.3