other-licenses/7zstub/src/7zip/Common/StreamBinder.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial