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