misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
changeset 13881 99b265e0d1d0
parent 13880 5f819b90d479
child 13882 b172a5d40eee
equal deleted inserted replaced
13880:5f819b90d479 13881:99b265e0d1d0
     1 // CoderMixer2MT.cpp
       
     2 
       
     3 #include "StdAfx.h"
       
     4 
       
     5 #include "CoderMixer2MT.h"
       
     6 
       
     7 namespace NCoderMixer {
       
     8 
       
     9 CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): 
       
    10     CCoderInfo2(numInStreams, numOutStreams)
       
    11 {
       
    12   InStreams.Reserve(NumInStreams);
       
    13   InStreamPointers.Reserve(NumInStreams);
       
    14   OutStreams.Reserve(NumOutStreams);
       
    15   OutStreamPointers.Reserve(NumOutStreams);
       
    16 }
       
    17 
       
    18 void CCoder2::Execute() { Code(NULL); }
       
    19 
       
    20 void CCoder2::Code(ICompressProgressInfo *progress)
       
    21 {
       
    22   InStreamPointers.Clear();
       
    23   OutStreamPointers.Clear();
       
    24   UInt32 i;
       
    25   for (i = 0; i < NumInStreams; i++)
       
    26   {
       
    27     if (InSizePointers[i] != NULL)
       
    28       InSizePointers[i] = &InSizes[i];
       
    29     InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
       
    30   }
       
    31   for (i = 0; i < NumOutStreams; i++)
       
    32   {
       
    33     if (OutSizePointers[i] != NULL)
       
    34       OutSizePointers[i] = &OutSizes[i];
       
    35     OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
       
    36   }
       
    37   if (Coder)
       
    38     Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], 
       
    39         InSizePointers[0], OutSizePointers[0], progress);
       
    40   else
       
    41     Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
       
    42       &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
       
    43   {
       
    44     int i;
       
    45     for (i = 0; i < InStreams.Size(); i++)
       
    46       InStreams[i].Release();
       
    47     for (i = 0; i < OutStreams.Size(); i++)
       
    48       OutStreams[i].Release();
       
    49   }
       
    50 }
       
    51 
       
    52 static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, 
       
    53     CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
       
    54 {
       
    55   sizes.Clear();
       
    56   sizePointers.Clear();
       
    57   for(UInt32 i = 0; i < numItems; i++)
       
    58   {
       
    59     if (srcSizes == 0 || srcSizes[i] == NULL)
       
    60     {
       
    61       sizes.Add(0);
       
    62       sizePointers.Add(NULL);
       
    63     }
       
    64     else
       
    65     {
       
    66       sizes.Add(*srcSizes[i]);
       
    67       sizePointers.Add(&sizes.Back());
       
    68     }
       
    69   }
       
    70 }
       
    71 
       
    72 
       
    73 void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
       
    74 {
       
    75   SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
       
    76   SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
       
    77 }
       
    78 
       
    79 //////////////////////////////////////
       
    80 // CCoderMixer2MT
       
    81 
       
    82 HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
       
    83 {  
       
    84   _bindInfo = bindInfo; 
       
    85   _streamBinders.Clear();
       
    86   for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
       
    87   {
       
    88     _streamBinders.Add(CStreamBinder());
       
    89     RINOK(_streamBinders.Back().CreateEvents());
       
    90   }
       
    91   return S_OK;
       
    92 }
       
    93 
       
    94 void CCoderMixer2MT::AddCoderCommon()
       
    95 {
       
    96   const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
       
    97   CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
       
    98   _coders.Add(threadCoderInfo);
       
    99 }
       
   100 
       
   101 void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
       
   102 {
       
   103   AddCoderCommon();
       
   104   _coders.Back().Coder = coder;
       
   105 }
       
   106 
       
   107 void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
       
   108 {
       
   109   AddCoderCommon();
       
   110   _coders.Back().Coder2 = coder;
       
   111 }
       
   112 
       
   113 
       
   114 void CCoderMixer2MT::ReInit()
       
   115 {
       
   116   for(int i = 0; i < _streamBinders.Size(); i++)
       
   117     _streamBinders[i].ReInit();
       
   118 }
       
   119 
       
   120 
       
   121 HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) 
       
   122 {
       
   123   /*
       
   124   if (_coders.Size() != _bindInfo.Coders.Size())
       
   125     throw 0;
       
   126   */
       
   127   int i;
       
   128   for(i = 0; i < _coders.Size(); i++)
       
   129   {
       
   130     CCoder2 &coderInfo = _coders[i];
       
   131     const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
       
   132     coderInfo.InStreams.Clear();
       
   133     UInt32 j;
       
   134     for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
       
   135       coderInfo.InStreams.Add(NULL);
       
   136     coderInfo.OutStreams.Clear();
       
   137     for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
       
   138       coderInfo.OutStreams.Add(NULL);
       
   139   }
       
   140 
       
   141   for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
       
   142   {
       
   143     const CBindPair &bindPair = _bindInfo.BindPairs[i];
       
   144     UInt32 inCoderIndex, inCoderStreamIndex;
       
   145     UInt32 outCoderIndex, outCoderStreamIndex;
       
   146     _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
       
   147     _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
       
   148 
       
   149     _streamBinders[i].CreateStreams(
       
   150         &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
       
   151         &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
       
   152   }
       
   153 
       
   154   for(i = 0; i < _bindInfo.InStreams.Size(); i++)
       
   155   {
       
   156     UInt32 inCoderIndex, inCoderStreamIndex;
       
   157     _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
       
   158     _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
       
   159   }
       
   160   
       
   161   for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
       
   162   {
       
   163     UInt32 outCoderIndex, outCoderStreamIndex;
       
   164     _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
       
   165     _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
       
   166   }
       
   167   return S_OK;
       
   168 }
       
   169 
       
   170 HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
       
   171 {
       
   172   for (int i = 0; i < _coders.Size(); i++)
       
   173     if (_coders[i].Result == code)
       
   174       return code;
       
   175   return S_OK;
       
   176 }
       
   177 
       
   178 STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
       
   179       const UInt64 ** /* inSizes */, 
       
   180       UInt32 numInStreams,
       
   181       ISequentialOutStream **outStreams, 
       
   182       const UInt64 ** /* outSizes */,
       
   183       UInt32 numOutStreams,
       
   184       ICompressProgressInfo *progress)
       
   185 {
       
   186   if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
       
   187       numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
       
   188     return E_INVALIDARG;
       
   189 
       
   190   Init(inStreams, outStreams);
       
   191 
       
   192   int i;
       
   193   for (i = 0; i < _coders.Size(); i++)
       
   194     if (i != _progressCoderIndex)
       
   195     {
       
   196       RINOK(_coders[i].Create());
       
   197     }
       
   198 
       
   199   for (i = 0; i < _coders.Size(); i++)
       
   200     if (i != _progressCoderIndex)
       
   201       _coders[i].Start();
       
   202 
       
   203   _coders[_progressCoderIndex].Code(progress);
       
   204 
       
   205   for (i = 0; i < _coders.Size(); i++)
       
   206     if (i != _progressCoderIndex)
       
   207       _coders[i].WaitFinish();
       
   208 
       
   209   RINOK(ReturnIfError(E_ABORT));
       
   210   RINOK(ReturnIfError(E_OUTOFMEMORY));
       
   211   RINOK(ReturnIfError(S_FALSE));
       
   212 
       
   213   for (i = 0; i < _coders.Size(); i++)
       
   214   {
       
   215     HRESULT result = _coders[i].Result;
       
   216     if (result != S_OK && result != E_FAIL)
       
   217       return result;
       
   218   }
       
   219   for (i = 0; i < _coders.Size(); i++)
       
   220   {
       
   221     HRESULT result = _coders[i].Result;
       
   222     if (result != S_OK)
       
   223       return result;
       
   224   }
       
   225   return S_OK;
       
   226 }
       
   227 
       
   228 }