"Fossies" - the Fresh Open Source Software Archive

Member "UXP-2019.06.08/other-licenses/7zstub/src/CPP/7zip/Common/StreamBinder.cpp" (8 Jun 2019, 3828 Bytes) of package /linux/www/UXP-2019.06.08.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

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