tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CoderMixer2.h (10803B)


      1 // CoderMixer2.h
      2 
      3 #ifndef __CODER_MIXER2_H
      4 #define __CODER_MIXER2_H
      5 
      6 #include "../../../Common/MyCom.h"
      7 #include "../../../Common/MyVector.h"
      8 
      9 #include "../../ICoder.h"
     10 
     11 #include "../../Common/CreateCoder.h"
     12 
     13 #ifdef _7ZIP_ST
     14  #define USE_MIXER_ST
     15 #else
     16  #define USE_MIXER_MT
     17  #ifndef _SFX
     18    #define USE_MIXER_ST
     19  #endif
     20 #endif
     21 
     22 #ifdef USE_MIXER_MT
     23 #include "../../Common/StreamBinder.h"
     24 #include "../../Common/VirtThread.h"
     25 #endif
     26 
     27 
     28 
     29 #ifdef USE_MIXER_ST
     30 
     31 class CSequentialInStreamCalcSize:
     32  public ISequentialInStream,
     33  public CMyUnknownImp
     34 {
     35 public:
     36  MY_UNKNOWN_IMP1(ISequentialInStream)
     37 
     38  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
     39 private:
     40  CMyComPtr<ISequentialInStream> _stream;
     41  UInt64 _size;
     42  bool _wasFinished;
     43 public:
     44  void SetStream(ISequentialInStream *stream) { _stream = stream;  }
     45  void Init()
     46  {
     47    _size = 0;
     48    _wasFinished = false;
     49  }
     50  void ReleaseStream() { _stream.Release(); }
     51  UInt64 GetSize() const { return _size; }
     52  bool WasFinished() const { return _wasFinished; }
     53 };
     54 
     55 
     56 class COutStreamCalcSize:
     57  public ISequentialOutStream,
     58  public IOutStreamFinish,
     59  public CMyUnknownImp
     60 {
     61  CMyComPtr<ISequentialOutStream> _stream;
     62  UInt64 _size;
     63 public:
     64  MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStreamFinish)
     65  
     66  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
     67  STDMETHOD(OutStreamFinish)();
     68  
     69  void SetStream(ISequentialOutStream *stream) { _stream = stream; }
     70  void ReleaseStream() { _stream.Release(); }
     71  void Init() { _size = 0; }
     72  UInt64 GetSize() const { return _size; }
     73 };
     74 
     75 #endif
     76 
     77 
     78  
     79 namespace NCoderMixer2 {
     80 
     81 struct CBond
     82 {
     83  UInt32 PackIndex;
     84  UInt32 UnpackIndex;
     85 
     86  UInt32 Get_InIndex(bool encodeMode) const { return encodeMode ? UnpackIndex : PackIndex; }
     87  UInt32 Get_OutIndex(bool encodeMode) const { return encodeMode ? PackIndex : UnpackIndex; }
     88 };
     89 
     90 
     91 struct CCoderStreamsInfo
     92 {
     93  UInt32 NumStreams;
     94 };
     95 
     96 
     97 struct CBindInfo
     98 {
     99  CRecordVector<CCoderStreamsInfo> Coders;
    100  CRecordVector<CBond> Bonds;
    101  CRecordVector<UInt32> PackStreams;
    102  unsigned UnpackCoder;
    103 
    104  unsigned GetNum_Bonds_and_PackStreams() const { return Bonds.Size() + PackStreams.Size(); }
    105 
    106  int FindBond_for_PackStream(UInt32 packStream) const
    107  {
    108    FOR_VECTOR (i, Bonds)
    109      if (Bonds[i].PackIndex == packStream)
    110        return i;
    111    return -1;
    112  }
    113 
    114  int FindBond_for_UnpackStream(UInt32 unpackStream) const
    115  {
    116    FOR_VECTOR (i, Bonds)
    117      if (Bonds[i].UnpackIndex == unpackStream)
    118        return i;
    119    return -1;
    120  }
    121 
    122  bool SetUnpackCoder()
    123  {
    124    bool isOk = false;
    125    FOR_VECTOR(i, Coders)
    126    {
    127      if (FindBond_for_UnpackStream(i) < 0)
    128      {
    129        if (isOk)
    130          return false;
    131        UnpackCoder = i;
    132        isOk = true;
    133      }
    134    }
    135    return isOk;
    136  }
    137  
    138  bool IsStream_in_PackStreams(UInt32 streamIndex) const
    139  {
    140    return FindStream_in_PackStreams(streamIndex) >= 0;
    141  }
    142 
    143  int FindStream_in_PackStreams(UInt32 streamIndex) const
    144  {
    145    FOR_VECTOR(i, PackStreams)
    146      if (PackStreams[i] == streamIndex)
    147        return i;
    148    return -1;
    149  }
    150 
    151  
    152  // that function is used before Maps is calculated
    153 
    154  UInt32 GetStream_for_Coder(UInt32 coderIndex) const
    155  {
    156    UInt32 streamIndex = 0;
    157    for (UInt32 i = 0; i < coderIndex; i++)
    158      streamIndex += Coders[i].NumStreams;
    159    return streamIndex;
    160  }
    161  
    162  // ---------- Maps Section ----------
    163  
    164  CRecordVector<UInt32> Coder_to_Stream;
    165  CRecordVector<UInt32> Stream_to_Coder;
    166 
    167  void ClearMaps();
    168  bool CalcMapsAndCheck();
    169 
    170  // ---------- End of Maps Section ----------
    171 
    172  void Clear()
    173  {
    174    Coders.Clear();
    175    Bonds.Clear();
    176    PackStreams.Clear();
    177 
    178    ClearMaps();
    179  }
    180  
    181  void GetCoder_for_Stream(UInt32 streamIndex, UInt32 &coderIndex, UInt32 &coderStreamIndex) const
    182  {
    183    coderIndex = Stream_to_Coder[streamIndex];
    184    coderStreamIndex = streamIndex - Coder_to_Stream[coderIndex];
    185  }
    186 };
    187 
    188 
    189 
    190 class CCoder
    191 {
    192  CLASS_NO_COPY(CCoder);
    193 public:
    194  CMyComPtr<ICompressCoder> Coder;
    195  CMyComPtr<ICompressCoder2> Coder2;
    196  UInt32 NumStreams;
    197 
    198  UInt64 UnpackSize;
    199  const UInt64 *UnpackSizePointer;
    200 
    201  CRecordVector<UInt64> PackSizes;
    202  CRecordVector<const UInt64 *> PackSizePointers;
    203 
    204  bool Finish;
    205 
    206  CCoder(): Finish(false) {}
    207 
    208  void SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish);
    209 
    210  HRESULT CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const;
    211 
    212  IUnknown *GetUnknown() const
    213  {
    214    return Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
    215  }
    216 
    217  HRESULT QueryInterface(REFGUID iid, void** pp) const
    218  {
    219    return GetUnknown()->QueryInterface(iid, pp);
    220  }
    221 };
    222 
    223 
    224 
    225 class CMixer
    226 {
    227  bool Is_PackSize_Correct_for_Stream(UInt32 streamIndex);
    228 
    229 protected:
    230  CBindInfo _bi;
    231 
    232  int FindBond_for_Stream(bool forInputStream, UInt32 streamIndex) const
    233  {
    234    if (EncodeMode == forInputStream)
    235      return _bi.FindBond_for_UnpackStream(streamIndex);
    236    else
    237      return _bi.FindBond_for_PackStream(streamIndex);
    238  }
    239 
    240  CBoolVector IsFilter_Vector;
    241  CBoolVector IsExternal_Vector;
    242  bool EncodeMode;
    243 public:
    244  unsigned MainCoderIndex;
    245 
    246  // bool InternalPackSizeError;
    247 
    248  CMixer(bool encodeMode):
    249      EncodeMode(encodeMode),
    250      MainCoderIndex(0)
    251      // , InternalPackSizeError(false)
    252      {}
    253 
    254  /*
    255  Sequence of calling:
    256 
    257      SetBindInfo();
    258      for each coder
    259        AddCoder();
    260      SelectMainCoder();
    261 
    262      for each file
    263      {
    264        ReInit()
    265        for each coder
    266          SetCoderInfo();
    267        Code();
    268      }
    269  */
    270 
    271  virtual HRESULT SetBindInfo(const CBindInfo &bindInfo)
    272  {
    273    _bi = bindInfo;
    274    IsFilter_Vector.Clear();
    275    MainCoderIndex = 0;
    276    return S_OK;
    277  }
    278 
    279  virtual void AddCoder(const CCreatedCoder &cod) = 0;
    280  virtual CCoder &GetCoder(unsigned index) = 0;
    281  virtual void SelectMainCoder(bool useFirst) = 0;
    282  virtual void ReInit() = 0;
    283  virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0;
    284  virtual HRESULT Code(
    285      ISequentialInStream * const *inStreams,
    286      ISequentialOutStream * const *outStreams,
    287      ICompressProgressInfo *progress,
    288      bool &dataAfterEnd_Error) = 0;
    289  virtual UInt64 GetBondStreamSize(unsigned bondIndex) const = 0;
    290 
    291  bool Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex);
    292  bool Is_PackSize_Correct_for_Coder(UInt32 coderIndex);
    293  bool IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex);
    294 };
    295 
    296 
    297 
    298 
    299 #ifdef USE_MIXER_ST
    300 
    301 struct CCoderST: public CCoder
    302 {
    303  bool CanRead;
    304  bool CanWrite;
    305  
    306  CCoderST(): CanRead(false), CanWrite(false) {}
    307 };
    308 
    309 
    310 struct CStBinderStream
    311 {
    312  CSequentialInStreamCalcSize *InStreamSpec;
    313  COutStreamCalcSize *OutStreamSpec;
    314  CMyComPtr<IUnknown> StreamRef;
    315 
    316  CStBinderStream(): InStreamSpec(NULL), OutStreamSpec(NULL) {}
    317 };
    318 
    319 
    320 class CMixerST:
    321  public IUnknown,
    322  public CMixer,
    323  public CMyUnknownImp
    324 {
    325  HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
    326      UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
    327  HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
    328      UInt32 inStreamIndex, ISequentialInStream **inStreamRes);
    329  HRESULT GetOutStream(ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */
    330      UInt32 outStreamIndex, ISequentialOutStream **outStreamRes);
    331 
    332  HRESULT FinishStream(UInt32 streamIndex);
    333  HRESULT FinishCoder(UInt32 coderIndex);
    334 
    335 public:
    336  CObjectVector<CCoderST> _coders;
    337  
    338  CObjectVector<CStBinderStream> _binderStreams;
    339 
    340  MY_UNKNOWN_IMP
    341 
    342  CMixerST(bool encodeMode);
    343  ~CMixerST();
    344 
    345  virtual void AddCoder(const CCreatedCoder &cod);
    346  virtual CCoder &GetCoder(unsigned index);
    347  virtual void SelectMainCoder(bool useFirst);
    348  virtual void ReInit();
    349  virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
    350    { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
    351  virtual HRESULT Code(
    352      ISequentialInStream * const *inStreams,
    353      ISequentialOutStream * const *outStreams,
    354      ICompressProgressInfo *progress,
    355      bool &dataAfterEnd_Error);
    356  virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
    357 
    358  HRESULT GetMainUnpackStream(
    359      ISequentialInStream * const *inStreams,
    360      ISequentialInStream **inStreamRes);
    361 };
    362 
    363 #endif
    364 
    365 
    366 
    367 
    368 #ifdef USE_MIXER_MT
    369 
    370 class CCoderMT: public CCoder, public CVirtThread
    371 {
    372  CLASS_NO_COPY(CCoderMT)
    373  CRecordVector<ISequentialInStream*> InStreamPointers;
    374  CRecordVector<ISequentialOutStream*> OutStreamPointers;
    375 
    376 private:
    377  void Execute();
    378 public:
    379  bool EncodeMode;
    380  HRESULT Result;
    381  CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
    382  CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
    383 
    384  void Release()
    385  {
    386    InStreamPointers.Clear();
    387    OutStreamPointers.Clear();
    388    unsigned i;
    389    for (i = 0; i < InStreams.Size(); i++)
    390      InStreams[i].Release();
    391    for (i = 0; i < OutStreams.Size(); i++)
    392      OutStreams[i].Release();
    393  }
    394 
    395  class CReleaser
    396  {
    397    CLASS_NO_COPY(CReleaser)
    398    CCoderMT &_c;
    399  public:
    400    CReleaser(CCoderMT &c): _c(c) {}
    401    ~CReleaser() { _c.Release(); }
    402  };
    403 
    404  CCoderMT(): EncodeMode(false) {}
    405  ~CCoderMT() { CVirtThread::WaitThreadFinish(); }
    406  
    407  void Code(ICompressProgressInfo *progress);
    408 };
    409 
    410 
    411 class CMixerMT:
    412  public IUnknown,
    413  public CMixer,
    414  public CMyUnknownImp
    415 {
    416  CObjectVector<CStreamBinder> _streamBinders;
    417 
    418  HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
    419  HRESULT ReturnIfError(HRESULT code);
    420 
    421 public:
    422  CObjectVector<CCoderMT> _coders;
    423 
    424  MY_UNKNOWN_IMP
    425 
    426  virtual HRESULT SetBindInfo(const CBindInfo &bindInfo);
    427  virtual void AddCoder(const CCreatedCoder &cod);
    428  virtual CCoder &GetCoder(unsigned index);
    429  virtual void SelectMainCoder(bool useFirst);
    430  virtual void ReInit();
    431  virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
    432    { _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
    433  virtual HRESULT Code(
    434      ISequentialInStream * const *inStreams,
    435      ISequentialOutStream * const *outStreams,
    436      ICompressProgressInfo *progress,
    437      bool &dataAfterEnd_Error);
    438  virtual UInt64 GetBondStreamSize(unsigned bondIndex) const;
    439 
    440  CMixerMT(bool encodeMode): CMixer(encodeMode) {}
    441 };
    442 
    443 #endif
    444 
    445 }
    446 
    447 #endif