diff src/win32/7zip/7z/CPP/7zip/Archive/Common/CoderMixer2MT.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Archive/Common/CoderMixer2MT.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,230 @@
     1.4 +// CoderMixer2MT.cpp
     1.5 +
     1.6 +#include "StdAfx.h"
     1.7 +
     1.8 +#include "CoderMixer2MT.h"
     1.9 +
    1.10 +namespace NCoderMixer {
    1.11 +
    1.12 +CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
    1.13 +    CCoderInfo2(numInStreams, numOutStreams)
    1.14 +{
    1.15 +  InStreams.Reserve(NumInStreams);
    1.16 +  InStreamPointers.Reserve(NumInStreams);
    1.17 +  OutStreams.Reserve(NumOutStreams);
    1.18 +  OutStreamPointers.Reserve(NumOutStreams);
    1.19 +}
    1.20 +
    1.21 +void CCoder2::Execute() { Code(NULL); }
    1.22 +
    1.23 +void CCoder2::Code(ICompressProgressInfo *progress)
    1.24 +{
    1.25 +  InStreamPointers.Clear();
    1.26 +  OutStreamPointers.Clear();
    1.27 +  UInt32 i;
    1.28 +  for (i = 0; i < NumInStreams; i++)
    1.29 +  {
    1.30 +    if (InSizePointers[i] != NULL)
    1.31 +      InSizePointers[i] = &InSizes[i];
    1.32 +    InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
    1.33 +  }
    1.34 +  for (i = 0; i < NumOutStreams; i++)
    1.35 +  {
    1.36 +    if (OutSizePointers[i] != NULL)
    1.37 +      OutSizePointers[i] = &OutSizes[i];
    1.38 +    OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
    1.39 +  }
    1.40 +  if (Coder)
    1.41 +    Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
    1.42 +        InSizePointers[0], OutSizePointers[0], progress);
    1.43 +  else
    1.44 +    Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
    1.45 +      &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
    1.46 +  {
    1.47 +    int i;
    1.48 +    for (i = 0; i < InStreams.Size(); i++)
    1.49 +      InStreams[i].Release();
    1.50 +    for (i = 0; i < OutStreams.Size(); i++)
    1.51 +      OutStreams[i].Release();
    1.52 +  }
    1.53 +}
    1.54 +
    1.55 +static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
    1.56 +    CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
    1.57 +{
    1.58 +  sizes.Clear();
    1.59 +  sizePointers.Clear();
    1.60 +  for(UInt32 i = 0; i < numItems; i++)
    1.61 +  {
    1.62 +    if (srcSizes == 0 || srcSizes[i] == NULL)
    1.63 +    {
    1.64 +      sizes.Add(0);
    1.65 +      sizePointers.Add(NULL);
    1.66 +    }
    1.67 +    else
    1.68 +    {
    1.69 +      sizes.Add(*srcSizes[i]);
    1.70 +      sizePointers.Add(&sizes.Back());
    1.71 +    }
    1.72 +  }
    1.73 +}
    1.74 +
    1.75 +
    1.76 +void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
    1.77 +{
    1.78 +  SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
    1.79 +  SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
    1.80 +}
    1.81 +
    1.82 +//////////////////////////////////////
    1.83 +// CCoderMixer2MT
    1.84 +
    1.85 +HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
    1.86 +{
    1.87 +  _bindInfo = bindInfo;
    1.88 +  _streamBinders.Clear();
    1.89 +  for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
    1.90 +  {
    1.91 +    _streamBinders.Add(CStreamBinder());
    1.92 +    RINOK(_streamBinders.Back().CreateEvents());
    1.93 +  }
    1.94 +  return S_OK;
    1.95 +}
    1.96 +
    1.97 +void CCoderMixer2MT::AddCoderCommon()
    1.98 +{
    1.99 +  const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
   1.100 +  CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
   1.101 +  _coders.Add(threadCoderInfo);
   1.102 +}
   1.103 +
   1.104 +void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
   1.105 +{
   1.106 +  AddCoderCommon();
   1.107 +  _coders.Back().Coder = coder;
   1.108 +}
   1.109 +
   1.110 +void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
   1.111 +{
   1.112 +  AddCoderCommon();
   1.113 +  _coders.Back().Coder2 = coder;
   1.114 +}
   1.115 +
   1.116 +
   1.117 +void CCoderMixer2MT::ReInit()
   1.118 +{
   1.119 +  for(int i = 0; i < _streamBinders.Size(); i++)
   1.120 +    _streamBinders[i].ReInit();
   1.121 +}
   1.122 +
   1.123 +
   1.124 +HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
   1.125 +{
   1.126 +  /*
   1.127 +  if (_coders.Size() != _bindInfo.Coders.Size())
   1.128 +    throw 0;
   1.129 +  */
   1.130 +  int i;
   1.131 +  for(i = 0; i < _coders.Size(); i++)
   1.132 +  {
   1.133 +    CCoder2 &coderInfo = _coders[i];
   1.134 +    const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
   1.135 +    coderInfo.InStreams.Clear();
   1.136 +    UInt32 j;
   1.137 +    for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
   1.138 +      coderInfo.InStreams.Add(NULL);
   1.139 +    coderInfo.OutStreams.Clear();
   1.140 +    for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
   1.141 +      coderInfo.OutStreams.Add(NULL);
   1.142 +  }
   1.143 +
   1.144 +  for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
   1.145 +  {
   1.146 +    const CBindPair &bindPair = _bindInfo.BindPairs[i];
   1.147 +    UInt32 inCoderIndex, inCoderStreamIndex;
   1.148 +    UInt32 outCoderIndex, outCoderStreamIndex;
   1.149 +    _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
   1.150 +    _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
   1.151 +
   1.152 +    _streamBinders[i].CreateStreams(
   1.153 +        &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
   1.154 +        &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
   1.155 +  }
   1.156 +
   1.157 +  for(i = 0; i < _bindInfo.InStreams.Size(); i++)
   1.158 +  {
   1.159 +    UInt32 inCoderIndex, inCoderStreamIndex;
   1.160 +    _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
   1.161 +    _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
   1.162 +  }
   1.163 +  
   1.164 +  for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
   1.165 +  {
   1.166 +    UInt32 outCoderIndex, outCoderStreamIndex;
   1.167 +    _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
   1.168 +    _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
   1.169 +  }
   1.170 +  return S_OK;
   1.171 +}
   1.172 +
   1.173 +HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
   1.174 +{
   1.175 +  for (int i = 0; i < _coders.Size(); i++)
   1.176 +    if (_coders[i].Result == code)
   1.177 +      return code;
   1.178 +  return S_OK;
   1.179 +}
   1.180 +
   1.181 +STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
   1.182 +      const UInt64 ** /* inSizes */,
   1.183 +      UInt32 numInStreams,
   1.184 +      ISequentialOutStream **outStreams,
   1.185 +      const UInt64 ** /* outSizes */,
   1.186 +      UInt32 numOutStreams,
   1.187 +      ICompressProgressInfo *progress)
   1.188 +{
   1.189 +  if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
   1.190 +      numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
   1.191 +    return E_INVALIDARG;
   1.192 +
   1.193 +  Init(inStreams, outStreams);
   1.194 +
   1.195 +  int i;
   1.196 +  for (i = 0; i < _coders.Size(); i++)
   1.197 +    if (i != _progressCoderIndex)
   1.198 +    {
   1.199 +      RINOK(_coders[i].Create());
   1.200 +    }
   1.201 +
   1.202 +  for (i = 0; i < _coders.Size(); i++)
   1.203 +    if (i != _progressCoderIndex)
   1.204 +      _coders[i].Start();
   1.205 +
   1.206 +  _coders[_progressCoderIndex].Code(progress);
   1.207 +
   1.208 +  for (i = 0; i < _coders.Size(); i++)
   1.209 +    if (i != _progressCoderIndex)
   1.210 +      _coders[i].WaitFinish();
   1.211 +
   1.212 +  RINOK(ReturnIfError(E_ABORT));
   1.213 +  RINOK(ReturnIfError(E_OUTOFMEMORY));
   1.214 +
   1.215 +  for (i = 0; i < _coders.Size(); i++)
   1.216 +  {
   1.217 +    HRESULT result = _coders[i].Result;
   1.218 +    if (result != S_OK && result != E_FAIL && result != S_FALSE)
   1.219 +      return result;
   1.220 +  }
   1.221 +
   1.222 +  RINOK(ReturnIfError(S_FALSE));
   1.223 +
   1.224 +  for (i = 0; i < _coders.Size(); i++)
   1.225 +  {
   1.226 +    HRESULT result = _coders[i].Result;
   1.227 +    if (result != S_OK)
   1.228 +      return result;
   1.229 +  }
   1.230 +  return S_OK;
   1.231 +}
   1.232 +
   1.233 +}