1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// StreamBinder.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StreamBinder.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/Defs.h" 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/MyCom.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NWindows; 10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NSynchronization; 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CSequentialInStreamForBinder: 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public ISequentialInStream, 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public CMyUnknownImp 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 16baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_UNKNOWN_IMP 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncprivate: 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamBinder *m_StreamBinder; 22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); } 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 27baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { return m_StreamBinder->Read(data, size, processedSize); } 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 30baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CSequentialOutStreamForBinder: 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public ISequentialOutStream, 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync public CMyUnknownImp 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 34baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync MY_UNKNOWN_IMP 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 39baa3858d3f5d128a5c8466b700098109edcad5f2repo syncprivate: 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamBinder *m_StreamBinder; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); } 43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; } 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 46baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSTDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { return m_StreamBinder->Write(data, size, processedSize); } 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync////////////////////////// 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// CStreamBinder 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished. 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 54baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRes CStreamBinder::CreateEvents() 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_allBytesAreWritenEvent.Create(true)); 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_thereAreBytesToReadEvent.Create()); 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _readStreamIsClosedEvent.Create(); 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 61baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamBinder::ReInit() 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _thereAreBytesToReadEvent.Reset(); 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _readStreamIsClosedEvent.Reset(); 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ProcessedSize = 0; 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 70baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamBinder::CreateStreams(ISequentialInStream **inStream, 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ISequentialOutStream **outStream) 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSequentialInStreamForBinder *inStreamSpec = new 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSequentialInStreamForBinder; 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec); 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync inStreamSpec->SetBinder(this); 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *inStream = inStreamLoc.Detach(); 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSequentialOutStreamForBinder *outStreamSpec = new 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CSequentialOutStreamForBinder; 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec); 82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStreamSpec->SetBinder(this); 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *outStream = outStreamLoc.Detach(); 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer = NULL; 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bufferSize= 0; 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ProcessedSize = 0; 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 90baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize) 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 sizeToRead = size; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > 0) 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_thereAreBytesToReadEvent.Lock()); 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizeToRead = MyMin(_bufferSize, size); 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_bufferSize > 0) 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync memcpy(data, _buffer, sizeToRead); 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer = ((const Byte *)_buffer) + sizeToRead; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bufferSize -= sizeToRead; 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_bufferSize == 0) 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _thereAreBytesToReadEvent.Reset(); 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _allBytesAreWritenEvent.Set(); 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedSize != NULL) 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = sizeToRead; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ProcessedSize += sizeToRead; 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 115baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamBinder::CloseRead() 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _readStreamIsClosedEvent.Set(); 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 120baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize) 121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > 0) 123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _buffer = data; 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _bufferSize = size; 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _allBytesAreWritenEvent.Reset(); 127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _thereAreBytesToReadEvent.Set(); 128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HANDLE events[2]; 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync events[0] = _allBytesAreWritenEvent; 131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync events[1] = _readStreamIsClosedEvent; 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (waitResult != WAIT_OBJECT_0 + 0) 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // ReadingWasClosed = true; 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // if(!_allBytesAreWritenEvent.Lock()) 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // return E_FAIL; 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (processedSize != NULL) 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync *processedSize = size; 143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 146baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamBinder::CloseWrite() 147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // _bufferSize must be = 0 149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _thereAreBytesToReadEvent.Set(); 150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 151