Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | // 7zDecode.cpp |
michael@0 | 2 | |
michael@0 | 3 | #include "StdAfx.h" |
michael@0 | 4 | |
michael@0 | 5 | #include "7zDecode.h" |
michael@0 | 6 | |
michael@0 | 7 | #include "../../IPassword.h" |
michael@0 | 8 | #include "../../Common/LockedStream.h" |
michael@0 | 9 | #include "../../Common/StreamObjects.h" |
michael@0 | 10 | #include "../../Common/ProgressUtils.h" |
michael@0 | 11 | #include "../../Common/LimitedStreams.h" |
michael@0 | 12 | #include "../Common/FilterCoder.h" |
michael@0 | 13 | |
michael@0 | 14 | #include "7zMethods.h" |
michael@0 | 15 | |
michael@0 | 16 | #ifdef COMPRESS_LZMA |
michael@0 | 17 | #include "../../Compress/LZMA/LZMADecoder.h" |
michael@0 | 18 | static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 }; |
michael@0 | 19 | #endif |
michael@0 | 20 | |
michael@0 | 21 | #ifdef COMPRESS_PPMD |
michael@0 | 22 | #include "../../Compress/PPMD/PPMDDecoder.h" |
michael@0 | 23 | static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 }; |
michael@0 | 24 | #endif |
michael@0 | 25 | |
michael@0 | 26 | #ifdef COMPRESS_BCJ_X86 |
michael@0 | 27 | #include "../../Compress/Branch/x86.h" |
michael@0 | 28 | static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 }; |
michael@0 | 29 | #endif |
michael@0 | 30 | |
michael@0 | 31 | #ifdef COMPRESS_BCJ2 |
michael@0 | 32 | #include "../../Compress/Branch/x86_2.h" |
michael@0 | 33 | static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 }; |
michael@0 | 34 | #endif |
michael@0 | 35 | |
michael@0 | 36 | #ifdef COMPRESS_DEFLATE |
michael@0 | 37 | #ifndef COMPRESS_DEFLATE_DECODER |
michael@0 | 38 | #define COMPRESS_DEFLATE_DECODER |
michael@0 | 39 | #endif |
michael@0 | 40 | #endif |
michael@0 | 41 | |
michael@0 | 42 | #ifdef COMPRESS_DEFLATE_DECODER |
michael@0 | 43 | #include "../../Compress/Deflate/DeflateDecoder.h" |
michael@0 | 44 | static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 }; |
michael@0 | 45 | #endif |
michael@0 | 46 | |
michael@0 | 47 | #ifdef COMPRESS_BZIP2 |
michael@0 | 48 | #ifndef COMPRESS_BZIP2_DECODER |
michael@0 | 49 | #define COMPRESS_BZIP2_DECODER |
michael@0 | 50 | #endif |
michael@0 | 51 | #endif |
michael@0 | 52 | |
michael@0 | 53 | #ifdef COMPRESS_BZIP2_DECODER |
michael@0 | 54 | #include "../../Compress/BZip2/BZip2Decoder.h" |
michael@0 | 55 | static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 }; |
michael@0 | 56 | #endif |
michael@0 | 57 | |
michael@0 | 58 | #ifdef COMPRESS_COPY |
michael@0 | 59 | #include "../../Compress/Copy/CopyCoder.h" |
michael@0 | 60 | static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 }; |
michael@0 | 61 | #endif |
michael@0 | 62 | |
michael@0 | 63 | #ifdef CRYPTO_7ZAES |
michael@0 | 64 | #include "../../Crypto/7zAES/7zAES.h" |
michael@0 | 65 | static NArchive::N7z::CMethodID k_7zAES = { { 0x6, 0xF1, 0x07, 0x01 }, 4 }; |
michael@0 | 66 | #endif |
michael@0 | 67 | |
michael@0 | 68 | namespace NArchive { |
michael@0 | 69 | namespace N7z { |
michael@0 | 70 | |
michael@0 | 71 | static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, |
michael@0 | 72 | CBindInfoEx &bindInfo) |
michael@0 | 73 | { |
michael@0 | 74 | bindInfo.Clear(); |
michael@0 | 75 | int i; |
michael@0 | 76 | for (i = 0; i < folder.BindPairs.Size(); i++) |
michael@0 | 77 | { |
michael@0 | 78 | NCoderMixer2::CBindPair bindPair; |
michael@0 | 79 | bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; |
michael@0 | 80 | bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; |
michael@0 | 81 | bindInfo.BindPairs.Add(bindPair); |
michael@0 | 82 | } |
michael@0 | 83 | UInt32 outStreamIndex = 0; |
michael@0 | 84 | for (i = 0; i < folder.Coders.Size(); i++) |
michael@0 | 85 | { |
michael@0 | 86 | NCoderMixer2::CCoderStreamsInfo coderStreamsInfo; |
michael@0 | 87 | const CCoderInfo &coderInfo = folder.Coders[i]; |
michael@0 | 88 | coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; |
michael@0 | 89 | coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; |
michael@0 | 90 | bindInfo.Coders.Add(coderStreamsInfo); |
michael@0 | 91 | const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); |
michael@0 | 92 | bindInfo.CoderMethodIDs.Add(altCoderInfo.MethodID); |
michael@0 | 93 | for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) |
michael@0 | 94 | if (folder.FindBindPairForOutStream(outStreamIndex) < 0) |
michael@0 | 95 | bindInfo.OutStreams.Add(outStreamIndex); |
michael@0 | 96 | } |
michael@0 | 97 | for (i = 0; i < folder.PackStreams.Size(); i++) |
michael@0 | 98 | bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); |
michael@0 | 99 | } |
michael@0 | 100 | |
michael@0 | 101 | static bool AreCodersEqual(const NCoderMixer2::CCoderStreamsInfo &a1, |
michael@0 | 102 | const NCoderMixer2::CCoderStreamsInfo &a2) |
michael@0 | 103 | { |
michael@0 | 104 | return (a1.NumInStreams == a2.NumInStreams) && |
michael@0 | 105 | (a1.NumOutStreams == a2.NumOutStreams); |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | static bool AreBindPairsEqual(const NCoderMixer2::CBindPair &a1, const NCoderMixer2::CBindPair &a2) |
michael@0 | 109 | { |
michael@0 | 110 | return (a1.InIndex == a2.InIndex) && |
michael@0 | 111 | (a1.OutIndex == a2.OutIndex); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) |
michael@0 | 115 | { |
michael@0 | 116 | if (a1.Coders.Size() != a2.Coders.Size()) |
michael@0 | 117 | return false; |
michael@0 | 118 | int i; |
michael@0 | 119 | for (i = 0; i < a1.Coders.Size(); i++) |
michael@0 | 120 | if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) |
michael@0 | 121 | return false; |
michael@0 | 122 | if (a1.BindPairs.Size() != a2.BindPairs.Size()) |
michael@0 | 123 | return false; |
michael@0 | 124 | for (i = 0; i < a1.BindPairs.Size(); i++) |
michael@0 | 125 | if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i])) |
michael@0 | 126 | return false; |
michael@0 | 127 | for (i = 0; i < a1.CoderMethodIDs.Size(); i++) |
michael@0 | 128 | if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i]) |
michael@0 | 129 | return false; |
michael@0 | 130 | if (a1.InStreams.Size() != a2.InStreams.Size()) |
michael@0 | 131 | return false; |
michael@0 | 132 | if (a1.OutStreams.Size() != a2.OutStreams.Size()) |
michael@0 | 133 | return false; |
michael@0 | 134 | return true; |
michael@0 | 135 | } |
michael@0 | 136 | |
michael@0 | 137 | CDecoder::CDecoder(bool multiThread) |
michael@0 | 138 | { |
michael@0 | 139 | #ifndef _ST_MODE |
michael@0 | 140 | multiThread = true; |
michael@0 | 141 | #endif |
michael@0 | 142 | _multiThread = multiThread; |
michael@0 | 143 | _bindInfoExPrevIsDefinded = false; |
michael@0 | 144 | #ifndef EXCLUDE_COM |
michael@0 | 145 | LoadMethodMap(); |
michael@0 | 146 | #endif |
michael@0 | 147 | } |
michael@0 | 148 | |
michael@0 | 149 | HRESULT CDecoder::Decode(IInStream *inStream, |
michael@0 | 150 | UInt64 startPos, |
michael@0 | 151 | const UInt64 *packSizes, |
michael@0 | 152 | const CFolder &folderInfo, |
michael@0 | 153 | ISequentialOutStream *outStream, |
michael@0 | 154 | ICompressProgressInfo *compressProgress |
michael@0 | 155 | #ifndef _NO_CRYPTO |
michael@0 | 156 | , ICryptoGetTextPassword *getTextPassword |
michael@0 | 157 | #endif |
michael@0 | 158 | #ifdef COMPRESS_MT |
michael@0 | 159 | , bool mtMode, UInt32 numThreads |
michael@0 | 160 | #endif |
michael@0 | 161 | ) |
michael@0 | 162 | { |
michael@0 | 163 | CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; |
michael@0 | 164 | |
michael@0 | 165 | CLockedInStream lockedInStream; |
michael@0 | 166 | lockedInStream.Init(inStream); |
michael@0 | 167 | |
michael@0 | 168 | for (int j = 0; j < folderInfo.PackStreams.Size(); j++) |
michael@0 | 169 | { |
michael@0 | 170 | CLockedSequentialInStreamImp *lockedStreamImpSpec = new |
michael@0 | 171 | CLockedSequentialInStreamImp; |
michael@0 | 172 | CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; |
michael@0 | 173 | lockedStreamImpSpec->Init(&lockedInStream, startPos); |
michael@0 | 174 | startPos += packSizes[j]; |
michael@0 | 175 | |
michael@0 | 176 | CLimitedSequentialInStream *streamSpec = new |
michael@0 | 177 | CLimitedSequentialInStream; |
michael@0 | 178 | CMyComPtr<ISequentialInStream> inStream = streamSpec; |
michael@0 | 179 | streamSpec->Init(lockedStreamImp, packSizes[j]); |
michael@0 | 180 | inStreams.Add(inStream); |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | int numCoders = folderInfo.Coders.Size(); |
michael@0 | 184 | |
michael@0 | 185 | CBindInfoEx bindInfo; |
michael@0 | 186 | ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); |
michael@0 | 187 | bool createNewCoders; |
michael@0 | 188 | if (!_bindInfoExPrevIsDefinded) |
michael@0 | 189 | createNewCoders = true; |
michael@0 | 190 | else |
michael@0 | 191 | createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); |
michael@0 | 192 | if (createNewCoders) |
michael@0 | 193 | { |
michael@0 | 194 | int i; |
michael@0 | 195 | _decoders.Clear(); |
michael@0 | 196 | // _decoders2.Clear(); |
michael@0 | 197 | |
michael@0 | 198 | _mixerCoder.Release(); |
michael@0 | 199 | |
michael@0 | 200 | if (_multiThread) |
michael@0 | 201 | { |
michael@0 | 202 | _mixerCoderMTSpec = new NCoderMixer2::CCoderMixer2MT; |
michael@0 | 203 | _mixerCoder = _mixerCoderMTSpec; |
michael@0 | 204 | _mixerCoderCommon = _mixerCoderMTSpec; |
michael@0 | 205 | } |
michael@0 | 206 | else |
michael@0 | 207 | { |
michael@0 | 208 | #ifdef _ST_MODE |
michael@0 | 209 | _mixerCoderSTSpec = new NCoderMixer2::CCoderMixer2ST; |
michael@0 | 210 | _mixerCoder = _mixerCoderSTSpec; |
michael@0 | 211 | _mixerCoderCommon = _mixerCoderSTSpec; |
michael@0 | 212 | #endif |
michael@0 | 213 | } |
michael@0 | 214 | _mixerCoderCommon->SetBindInfo(bindInfo); |
michael@0 | 215 | |
michael@0 | 216 | for (i = 0; i < numCoders; i++) |
michael@0 | 217 | { |
michael@0 | 218 | const CCoderInfo &coderInfo = folderInfo.Coders[i]; |
michael@0 | 219 | const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); |
michael@0 | 220 | #ifndef EXCLUDE_COM |
michael@0 | 221 | CMethodInfo methodInfo; |
michael@0 | 222 | if (!GetMethodInfo(altCoderInfo.MethodID, methodInfo)) |
michael@0 | 223 | return E_NOTIMPL; |
michael@0 | 224 | #endif |
michael@0 | 225 | |
michael@0 | 226 | if (coderInfo.IsSimpleCoder()) |
michael@0 | 227 | { |
michael@0 | 228 | CMyComPtr<ICompressCoder> decoder; |
michael@0 | 229 | CMyComPtr<ICompressFilter> filter; |
michael@0 | 230 | |
michael@0 | 231 | #ifdef COMPRESS_LZMA |
michael@0 | 232 | if (altCoderInfo.MethodID == k_LZMA) |
michael@0 | 233 | decoder = new NCompress::NLZMA::CDecoder; |
michael@0 | 234 | #endif |
michael@0 | 235 | |
michael@0 | 236 | #ifdef COMPRESS_PPMD |
michael@0 | 237 | if (altCoderInfo.MethodID == k_PPMD) |
michael@0 | 238 | decoder = new NCompress::NPPMD::CDecoder; |
michael@0 | 239 | #endif |
michael@0 | 240 | |
michael@0 | 241 | #ifdef COMPRESS_BCJ_X86 |
michael@0 | 242 | if (altCoderInfo.MethodID == k_BCJ_X86) |
michael@0 | 243 | filter = new CBCJ_x86_Decoder; |
michael@0 | 244 | #endif |
michael@0 | 245 | |
michael@0 | 246 | #ifdef COMPRESS_DEFLATE_DECODER |
michael@0 | 247 | if (altCoderInfo.MethodID == k_Deflate) |
michael@0 | 248 | decoder = new NCompress::NDeflate::NDecoder::CCOMCoder; |
michael@0 | 249 | #endif |
michael@0 | 250 | |
michael@0 | 251 | #ifdef COMPRESS_BZIP2_DECODER |
michael@0 | 252 | if (altCoderInfo.MethodID == k_BZip2) |
michael@0 | 253 | decoder = new NCompress::NBZip2::CDecoder; |
michael@0 | 254 | #endif |
michael@0 | 255 | |
michael@0 | 256 | #ifdef COMPRESS_COPY |
michael@0 | 257 | if (altCoderInfo.MethodID == k_Copy) |
michael@0 | 258 | decoder = new NCompress::CCopyCoder; |
michael@0 | 259 | #endif |
michael@0 | 260 | |
michael@0 | 261 | #ifdef CRYPTO_7ZAES |
michael@0 | 262 | if (altCoderInfo.MethodID == k_7zAES) |
michael@0 | 263 | filter = new NCrypto::NSevenZ::CDecoder; |
michael@0 | 264 | #endif |
michael@0 | 265 | |
michael@0 | 266 | if (filter) |
michael@0 | 267 | { |
michael@0 | 268 | CFilterCoder *coderSpec = new CFilterCoder; |
michael@0 | 269 | decoder = coderSpec; |
michael@0 | 270 | coderSpec->Filter = filter; |
michael@0 | 271 | } |
michael@0 | 272 | #ifndef EXCLUDE_COM |
michael@0 | 273 | if (decoder == 0) |
michael@0 | 274 | { |
michael@0 | 275 | RINOK(_libraries.CreateCoderSpec(methodInfo.FilePath, |
michael@0 | 276 | methodInfo.Decoder, &decoder)); |
michael@0 | 277 | } |
michael@0 | 278 | #endif |
michael@0 | 279 | |
michael@0 | 280 | if (decoder == 0) |
michael@0 | 281 | return E_NOTIMPL; |
michael@0 | 282 | |
michael@0 | 283 | _decoders.Add((IUnknown *)decoder); |
michael@0 | 284 | |
michael@0 | 285 | if (_multiThread) |
michael@0 | 286 | _mixerCoderMTSpec->AddCoder(decoder); |
michael@0 | 287 | #ifdef _ST_MODE |
michael@0 | 288 | else |
michael@0 | 289 | _mixerCoderSTSpec->AddCoder(decoder, false); |
michael@0 | 290 | #endif |
michael@0 | 291 | } |
michael@0 | 292 | else |
michael@0 | 293 | { |
michael@0 | 294 | CMyComPtr<ICompressCoder2> decoder; |
michael@0 | 295 | |
michael@0 | 296 | #ifdef COMPRESS_BCJ2 |
michael@0 | 297 | if (altCoderInfo.MethodID == k_BCJ2) |
michael@0 | 298 | decoder = new CBCJ2_x86_Decoder; |
michael@0 | 299 | #endif |
michael@0 | 300 | |
michael@0 | 301 | #ifndef EXCLUDE_COM |
michael@0 | 302 | if (decoder == 0) |
michael@0 | 303 | { |
michael@0 | 304 | RINOK(_libraries.CreateCoder2(methodInfo.FilePath, |
michael@0 | 305 | methodInfo.Decoder, &decoder)); |
michael@0 | 306 | } |
michael@0 | 307 | #endif |
michael@0 | 308 | |
michael@0 | 309 | if (decoder == 0) |
michael@0 | 310 | return E_NOTIMPL; |
michael@0 | 311 | |
michael@0 | 312 | _decoders.Add((IUnknown *)decoder); |
michael@0 | 313 | if (_multiThread) |
michael@0 | 314 | _mixerCoderMTSpec->AddCoder2(decoder); |
michael@0 | 315 | #ifdef _ST_MODE |
michael@0 | 316 | else |
michael@0 | 317 | _mixerCoderSTSpec->AddCoder2(decoder, false); |
michael@0 | 318 | #endif |
michael@0 | 319 | } |
michael@0 | 320 | } |
michael@0 | 321 | _bindInfoExPrev = bindInfo; |
michael@0 | 322 | _bindInfoExPrevIsDefinded = true; |
michael@0 | 323 | } |
michael@0 | 324 | int i; |
michael@0 | 325 | _mixerCoderCommon->ReInit(); |
michael@0 | 326 | |
michael@0 | 327 | UInt32 packStreamIndex = 0, unPackStreamIndex = 0; |
michael@0 | 328 | UInt32 coderIndex = 0; |
michael@0 | 329 | // UInt32 coder2Index = 0; |
michael@0 | 330 | |
michael@0 | 331 | for (i = 0; i < numCoders; i++) |
michael@0 | 332 | { |
michael@0 | 333 | const CCoderInfo &coderInfo = folderInfo.Coders[i]; |
michael@0 | 334 | const CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front(); |
michael@0 | 335 | CMyComPtr<IUnknown> &decoder = _decoders[coderIndex]; |
michael@0 | 336 | |
michael@0 | 337 | { |
michael@0 | 338 | CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; |
michael@0 | 339 | HRESULT result = decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); |
michael@0 | 340 | if (setDecoderProperties) |
michael@0 | 341 | { |
michael@0 | 342 | const CByteBuffer &properties = altCoderInfo.Properties; |
michael@0 | 343 | size_t size = properties.GetCapacity(); |
michael@0 | 344 | if (size > 0xFFFFFFFF) |
michael@0 | 345 | return E_NOTIMPL; |
michael@0 | 346 | if (size > 0) |
michael@0 | 347 | { |
michael@0 | 348 | RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size)); |
michael@0 | 349 | } |
michael@0 | 350 | } |
michael@0 | 351 | } |
michael@0 | 352 | |
michael@0 | 353 | #ifdef COMPRESS_MT |
michael@0 | 354 | if (mtMode) |
michael@0 | 355 | { |
michael@0 | 356 | CMyComPtr<ICompressSetCoderMt> setCoderMt; |
michael@0 | 357 | decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); |
michael@0 | 358 | if (setCoderMt) |
michael@0 | 359 | { |
michael@0 | 360 | RINOK(setCoderMt->SetNumberOfThreads(numThreads)); |
michael@0 | 361 | } |
michael@0 | 362 | } |
michael@0 | 363 | #endif |
michael@0 | 364 | |
michael@0 | 365 | #ifndef _NO_CRYPTO |
michael@0 | 366 | { |
michael@0 | 367 | CMyComPtr<ICryptoSetPassword> cryptoSetPassword; |
michael@0 | 368 | HRESULT result = decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); |
michael@0 | 369 | if (cryptoSetPassword) |
michael@0 | 370 | { |
michael@0 | 371 | if (getTextPassword == 0) |
michael@0 | 372 | return E_FAIL; |
michael@0 | 373 | CMyComBSTR password; |
michael@0 | 374 | RINOK(getTextPassword->CryptoGetTextPassword(&password)); |
michael@0 | 375 | CByteBuffer buffer; |
michael@0 | 376 | UString unicodePassword(password); |
michael@0 | 377 | const UInt32 sizeInBytes = unicodePassword.Length() * 2; |
michael@0 | 378 | buffer.SetCapacity(sizeInBytes); |
michael@0 | 379 | for (int i = 0; i < unicodePassword.Length(); i++) |
michael@0 | 380 | { |
michael@0 | 381 | wchar_t c = unicodePassword[i]; |
michael@0 | 382 | ((Byte *)buffer)[i * 2] = (Byte)c; |
michael@0 | 383 | ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); |
michael@0 | 384 | } |
michael@0 | 385 | RINOK(cryptoSetPassword->CryptoSetPassword( |
michael@0 | 386 | (const Byte *)buffer, sizeInBytes)); |
michael@0 | 387 | } |
michael@0 | 388 | } |
michael@0 | 389 | #endif |
michael@0 | 390 | |
michael@0 | 391 | coderIndex++; |
michael@0 | 392 | |
michael@0 | 393 | UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; |
michael@0 | 394 | UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; |
michael@0 | 395 | CRecordVector<const UInt64 *> packSizesPointers; |
michael@0 | 396 | CRecordVector<const UInt64 *> unPackSizesPointers; |
michael@0 | 397 | packSizesPointers.Reserve(numInStreams); |
michael@0 | 398 | unPackSizesPointers.Reserve(numOutStreams); |
michael@0 | 399 | UInt32 j; |
michael@0 | 400 | for (j = 0; j < numOutStreams; j++, unPackStreamIndex++) |
michael@0 | 401 | unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]); |
michael@0 | 402 | |
michael@0 | 403 | for (j = 0; j < numInStreams; j++, packStreamIndex++) |
michael@0 | 404 | { |
michael@0 | 405 | int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); |
michael@0 | 406 | if (bindPairIndex >= 0) |
michael@0 | 407 | packSizesPointers.Add( |
michael@0 | 408 | &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); |
michael@0 | 409 | else |
michael@0 | 410 | { |
michael@0 | 411 | int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); |
michael@0 | 412 | if (index < 0) |
michael@0 | 413 | return E_FAIL; |
michael@0 | 414 | packSizesPointers.Add(&packSizes[index]); |
michael@0 | 415 | } |
michael@0 | 416 | } |
michael@0 | 417 | |
michael@0 | 418 | _mixerCoderCommon->SetCoderInfo(i, |
michael@0 | 419 | &packSizesPointers.Front(), |
michael@0 | 420 | &unPackSizesPointers.Front()); |
michael@0 | 421 | } |
michael@0 | 422 | UInt32 mainCoder, temp; |
michael@0 | 423 | bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); |
michael@0 | 424 | |
michael@0 | 425 | if (_multiThread) |
michael@0 | 426 | _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); |
michael@0 | 427 | /* |
michael@0 | 428 | else |
michael@0 | 429 | _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; |
michael@0 | 430 | */ |
michael@0 | 431 | |
michael@0 | 432 | if (numCoders == 0) |
michael@0 | 433 | return 0; |
michael@0 | 434 | CRecordVector<ISequentialInStream *> inStreamPointers; |
michael@0 | 435 | inStreamPointers.Reserve(inStreams.Size()); |
michael@0 | 436 | for (i = 0; i < inStreams.Size(); i++) |
michael@0 | 437 | inStreamPointers.Add(inStreams[i]); |
michael@0 | 438 | ISequentialOutStream *outStreamPointer = outStream; |
michael@0 | 439 | return _mixerCoder->Code(&inStreamPointers.Front(), NULL, |
michael@0 | 440 | inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); |
michael@0 | 441 | } |
michael@0 | 442 | |
michael@0 | 443 | }} |