예제 #1
0
HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfo &fileInfo, bool &filled, FString &resPath)
{
  filled = false;
  for (;;)
  {
    if (Enumerators.IsEmpty())
    {
      if (Index >= FileNames.Size())
        return S_OK;
      const FString &path = FileNames[Index];
      int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
      resPath.Empty();
      if (pos >= 0)
        resPath = path.Left(pos + 1);

      #ifdef _WIN32
      // it's for "c:" paths/
      if (BasePrefix.IsEmpty() && path.Length() == 2 && path[1] == ':')
      {
        fileInfo.Name = path;
        fileInfo.Attrib = FILE_ATTRIBUTE_DIRECTORY;
        fileInfo.Size = 0;
      }
      else
      #endif
      if (!fileInfo.Find(BasePrefix + path))
      {
        WRes errorCode = GetNormalizedError();
        resPath = path;
        return errorCode;
      }
      Index++;
      break;
    }
    bool found;
    if (!Enumerators.Back().Next(fileInfo, found))
    {
      HRESULT errorCode = GetNormalizedError();
      resPath = Prefixes.Back();
      return errorCode;
    }
    if (found)
    {
      resPath = Prefixes.Back();
      break;
    }
    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }
  resPath += fileInfo.Name;
  if (!FlatMode && fileInfo.IsDir())
  {
    FString prefix = resPath + FCHAR_PATH_SEPARATOR;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + prefix + FCHAR_ANY_MASK));
    Prefixes.Add(prefix);
  }
  filled = true;
  return S_OK;
}
예제 #2
0
파일: 7zIn.cpp 프로젝트: 0963682490/omaha
void CInArchive::ReadUnpackInfo(
    const CObjectVector<CByteBuffer> *dataVector,
    CObjectVector<CFolder> &folders)
{
  WaitAttribute(NID::kFolder);
  CNum numFolders = ReadNum();

  {
    CStreamSwitch streamSwitch;
    streamSwitch.Set(this, dataVector);
    folders.Clear();
    folders.Reserve(numFolders);
    for (CNum i = 0; i < numFolders; i++)
    {
      folders.Add(CFolder());
      GetNextFolderItem(folders.Back());
    }
  }

  WaitAttribute(NID::kCodersUnpackSize);

  CNum i;
  for (i = 0; i < numFolders; i++)
  {
    CFolder &folder = folders[i];
    CNum numOutStreams = folder.GetNumOutStreams();
    folder.UnpackSizes.Reserve(numOutStreams);
    for (CNum j = 0; j < numOutStreams; j++)
      folder.UnpackSizes.Add(ReadNumber());
  }

  for (;;)
  {
    UInt64 type = ReadID();
    if (type == NID::kEnd)
      return;
    if (type == NID::kCRC)
    {
      CBoolVector crcsDefined;
      CRecordVector<UInt32> crcs;
      ReadHashDigests(numFolders, crcsDefined, crcs);
      for (i = 0; i < numFolders; i++)
      {
        CFolder &folder = folders[i];
        folder.UnpackCRCDefined = crcsDefined[i];
        folder.UnpackCRC = crcs[i];
      }
      continue;
    }
    SkipData();
  }
}
예제 #3
0
bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode)
{
    filled = false;
    for (;;)
    {
        if (Enumerators.IsEmpty())
        {
            if (Index >= FileNames.Size())
                return true;
            const UString &path = FileNames[Index];
            int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
            resPath.Empty();
            if (pos >= 0)
                resPath = path.Left(pos + 1);
            if (!NFind::FindFile(BasePrefix + path, fileInfo))
            {
                errorCode = ::GetLastError();
                resPath = path;
                return false;
            }
            Index++;
            break;
        }
        bool found;
        if (!Enumerators.Back().Next(fileInfo, found))
        {
            errorCode = ::GetLastError();
            resPath = Prefixes.Back();
            return false;
        }
        if (found)
        {
            resPath = Prefixes.Back();
            break;
        }
        Enumerators.DeleteBack();
        Prefixes.DeleteBack();
    }
    resPath += fileInfo.Name;
    if (!FlatMode && fileInfo.IsDir())
    {
        UString prefix = resPath + (UString)(wchar_t)kDirDelimiter;
        Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard));
        Prefixes.Add(prefix);
    }
    filled = true;
    return true;
}
예제 #4
0
파일: 7zIn.cpp 프로젝트: 0963682490/omaha
HRESULT CInArchive::ReadAndDecodePackedStreams(
    DECL_EXTERNAL_CODECS_LOC_VARS
    UInt64 baseOffset,
    UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
    #ifndef _NO_CRYPTO
    , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
    #endif
    )
{
  CRecordVector<UInt64> packSizes;
  CBoolVector packCRCsDefined;
  CRecordVector<UInt32> packCRCs;
  CObjectVector<CFolder> folders;
  
  CRecordVector<CNum> numUnpackStreamsInFolders;
  CRecordVector<UInt64> unpackSizes;
  CBoolVector digestsDefined;
  CRecordVector<UInt32> digests;
  
  ReadStreamsInfo(NULL,
    dataOffset,
    packSizes,
    packCRCsDefined,
    packCRCs,
    folders,
    numUnpackStreamsInFolders,
    unpackSizes,
    digestsDefined,
    digests);
  
  // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
  
  CNum packIndex = 0;
  CDecoder decoder(
    #ifdef _ST_MODE
    false
    #else
    true
    #endif
    );
  UInt64 dataStartPos = baseOffset + dataOffset;
  for (int i = 0; i < folders.Size(); i++)
  {
    const CFolder &folder = folders[i];
    dataVector.Add(CByteBuffer());
    CByteBuffer &data = dataVector.Back();
    UInt64 unpackSize64 = folder.GetUnpackSize();
    size_t unpackSize = (size_t)unpackSize64;
    if (unpackSize != unpackSize64)
      ThrowUnsupported();
    data.SetCapacity(unpackSize);
    
    CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
    CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
    outStreamSpec->Init(data, unpackSize);
    
    HRESULT result = decoder.Decode(
      EXTERNAL_CODECS_LOC_VARS
      _stream, dataStartPos,
      &packSizes[packIndex], folder, outStream, NULL
      #ifndef _NO_CRYPTO
      , getTextPassword, passwordIsDefined
      #endif
      #if !defined(_7ZIP_ST) && !defined(_SFX)
      , false, 1
      #endif
      );
    RINOK(result);
    
    if (folder.UnpackCRCDefined)
      if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
        ThrowIncorrect();
    for (int j = 0; j < folder.PackStreams.Size(); j++)
    {
      UInt64 packSize = packSizes[packIndex++];
      dataStartPos += packSize;
      HeadersSize += packSize;
    }
  }
  return S_OK;
}
예제 #5
0
HRESULT CEncoder::Encode(
    DECL_EXTERNAL_CODECS_LOC_VARS
    ISequentialInStream *inStream,
    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
    CFolder &folderItem,
    ISequentialOutStream *outStream,
    CRecordVector<UInt64> &packSizes,
    ICompressProgressInfo *compressProgress)
{
    RINOK(EncoderConstr());

    if (_mixerCoderSpec == NULL)
    {
        RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
    }
    _mixerCoderSpec->ReInit();
    // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);

    CObjectVector<CInOutTempBuffer> inOutTempBuffers;
    CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
    CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
    int numMethods = _bindInfo.Coders.Size();
    int i;
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        inOutTempBuffers.Add(CInOutTempBuffer());
        inOutTempBuffers.Back().Create();
        inOutTempBuffers.Back().InitWriting();
    }
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
        CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
        tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
        tempBuffers.Add(tempBuffer);
        tempBufferSpecs.Add(tempBufferSpec);
    }

    for (i = 0; i < numMethods; i++)
        _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);

    if (_bindInfo.InStreams.IsEmpty())
        return E_FAIL;
    UInt32 mainCoderIndex, mainStreamIndex;
    _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);

    if (inStreamSize != NULL)
    {
        CRecordVector<const UInt64 *> sizePointers;
        for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
            if (i == mainStreamIndex)
                sizePointers.Add(inStreamSize);
            else
                sizePointers.Add(NULL);
        _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
    }


    // UInt64 outStreamStartPos;
    // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));

    CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
        new CSequentialInStreamSizeCount2;
    CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
    CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
        new CSequentialOutStreamSizeCount;
    CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;

    inStreamSizeCountSpec->Init(inStream);
    outStreamSizeCountSpec->SetStream(outStream);
    outStreamSizeCountSpec->Init();

    CRecordVector<ISequentialInStream *> inStreamPointers;
    CRecordVector<ISequentialOutStream *> outStreamPointers;
    inStreamPointers.Add(inStreamSizeCount);
    outStreamPointers.Add(outStreamSizeCount);
    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
        outStreamPointers.Add(tempBuffers[i - 1]);

    for (i = 0; i < _codersInfo.Size(); i++)
    {
        CCoderInfo &encodingInfo = _codersInfo[i];

        CMyComPtr<ICryptoResetInitVector> resetInitVector;
        _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
        if (resetInitVector != NULL)
        {
            resetInitVector->ResetInitVector();
        }

        CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
        _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
        if (writeCoderProperties != NULL)
        {
            CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
            CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
            outStreamSpec->Init();
            writeCoderProperties->WriteCoderProperties(outStream);
            size_t size = outStreamSpec->GetSize();
            encodingInfo.Props.SetCapacity(size);
            memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
        }
    }

    UInt32 progressIndex = mainCoderIndex;

    for (i = 0; i + 1 < _codersInfo.Size(); i++)
    {
        UInt64 m = _codersInfo[i].MethodID;
        if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
            progressIndex = i + 1;
    }

    _mixerCoderSpec->SetProgressCoderIndex(progressIndex);

    RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
                            &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));

    ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
                                    folderItem);

    packSizes.Add(outStreamSizeCountSpec->GetSize());

    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    {
        CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
        RINOK(inOutTempBuffer.WriteToStream(outStream));
        packSizes.Add(inOutTempBuffer.GetDataSize());
    }

    for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
    {
        int binder = _bindInfo.FindBinderForInStream(
                         _bindReverseConverter->DestOutToSrcInMap[i]);
        UInt64 streamSize;
        if (binder < 0)
            streamSize = inStreamSizeCountSpec->GetSize();
        else
            streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
        folderItem.UnpackSizes.Add(streamSize);
    }
    for (i = numMethods - 1; i >= 0; i--)
        folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
    return S_OK;
}
예제 #6
0
HRESULT CEncoder::Encode(ISequentialInStream *inStream,
    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
    CFolder &folderItem,
    ISequentialOutStream *outStream,
    CRecordVector<UInt64> &packSizes,
    ICompressProgressInfo *compressProgress)
{
  if (_mixerCoderSpec == NULL)
  {
    RINOK(CreateMixerCoder(inSizeForReduce));
  }
  _mixerCoderSpec->ReInit();
  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);

  CObjectVector<CInOutTempBuffer> inOutTempBuffers;
  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
  int numMethods = _bindInfo.Coders.Size();
  int i;
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    inOutTempBuffers.Add(CInOutTempBuffer());
    inOutTempBuffers.Back().Create();
    inOutTempBuffers.Back().InitWriting();
  }
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    CSequentialOutTempBufferImp *tempBufferSpec = 
        new CSequentialOutTempBufferImp;
    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
    tempBuffers.Add(tempBuffer);
    tempBufferSpecs.Add(tempBufferSpec);
  }

  for (i = 0; i < numMethods; i++)
    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);

  if (_bindInfo.InStreams.IsEmpty())
    return E_FAIL;
  UInt32 mainCoderIndex, mainStreamIndex;
  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
  _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
  if (inStreamSize != NULL)
  {
    CRecordVector<const UInt64 *> sizePointers;
    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
      if (i == mainStreamIndex)
        sizePointers.Add(inStreamSize);
      else
        sizePointers.Add(NULL);
    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
  }

  
  // UInt64 outStreamStartPos;
  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
  
  CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = 
      new CSequentialInStreamSizeCount2;
  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
  CSequentialOutStreamSizeCount *outStreamSizeCountSpec = 
      new CSequentialOutStreamSizeCount;
  CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;

  inStreamSizeCountSpec->Init(inStream);
  outStreamSizeCountSpec->SetStream(outStream);
  outStreamSizeCountSpec->Init();

  CRecordVector<ISequentialInStream *> inStreamPointers;
  CRecordVector<ISequentialOutStream *> outStreamPointers;
  inStreamPointers.Add(inStreamSizeCount);
  outStreamPointers.Add(outStreamSizeCount);
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
    outStreamPointers.Add(tempBuffers[i - 1]);
  
  RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
  
  ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
      folderItem);
  
  packSizes.Add(outStreamSizeCountSpec->GetSize());
  
  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
  {
    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
    inOutTempBuffer.FlushWrite();
    inOutTempBuffer.InitReading();
    inOutTempBuffer.WriteToStream(outStream);
    packSizes.Add(inOutTempBuffer.GetDataSize());
  }
  
  for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
  {
    int binder = _bindInfo.FindBinderForInStream(
        _bindReverseConverter->DestOutToSrcInMap[i]);
    UInt64 streamSize;
    if (binder < 0)
      streamSize = inStreamSizeCountSpec->GetSize();
    else
      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
    folderItem.UnPackSizes.Add(streamSize);
  }
  for (i = numMethods - 1; i >= 0; i--)
  {
    // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
    for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)
      folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties 
          = _codersInfo[i].AltCoders[j].Properties;
  }
  return S_OK;
}
예제 #7
0
DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath)
{
  filled = false;
  resPath.Empty();

  for (;;)
  {
    #if defined(_WIN32) && !defined(UNDER_CE)
    bool isRootPrefix = (BasePrefix.IsEmpty() || (NName::IsSuperPath(BasePrefix) && BasePrefix[NName::kSuperPathPrefixSize] == 0));
    #endif

    if (Enumerators.IsEmpty())
    {
      if (Index >= FilePaths.Size())
        return S_OK;
      const FString &path = FilePaths[Index++];
      int pos = path.ReverseFind_PathSepar();
      if (pos >= 0)
        resPath.SetFrom(path, pos + 1);

      #if defined(_WIN32) && !defined(UNDER_CE)
      if (isRootPrefix && path.Len() == 2 && NName::IsDrivePath2(path))
      {
        // we use "c:" item as directory item
        fi.ClearBase();
        fi.Name = path;
        fi.SetAsDir();
        fi.Size = 0;
      }
      else
      #endif
      if (!fi.Find(BasePrefix + path))
      {
        DWORD error = GetNormalizedError();
        resPath = path;
        return error;
      }

      break;
    }

    bool found;

    if (Enumerators.Back().Next(fi, found))
    {
      if (found)
      {
        resPath = Prefixes.Back();
        break;
      }
    }
    else
    {
      DWORD error = GetNormalizedError();
      resPath = Prefixes.Back();
      Enumerators.DeleteBack();
      Prefixes.DeleteBack();
      return error;
    }

    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }

  resPath += fi.Name;

  if (EnterToDirs && fi.IsDir())
  {
    FString s = resPath;
    s.Add_PathSepar();
    Prefixes.Add(s);
    s += FCHAR_ANY_MASK;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
  }
  filled = true;
  return S_OK;
}
예제 #8
0
DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath)
{
  filled = false;
  resPath.Empty();
  for (;;)
  {
    if (Enumerators.IsEmpty())
    {
      if (Index >= FilePaths.Size())
        return S_OK;
      const FString &path = FilePaths[Index++];
      int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
      if (pos >= 0)
        resPath.SetFrom(path, pos + 1);

      #ifdef _WIN32
      if (BasePrefix.IsEmpty() && path.Len() == 2 && path[1] == ':')
      {
        // we use "c:" item as directory item
        fi.Clear();
        fi.Name = path;
        fi.SetAsDir();
        fi.Size = 0;
      }
      else
      #endif
      if (!fi.Find(BasePrefix + path))
      {
        DWORD error = GetNormalizedError();
        resPath = path;
        return error;
      }
      break;
    }
    bool found;
    if (Enumerators.Back().Next(fi, found))
    {
      if (found)
      {
        resPath = Prefixes.Back();
        break;
      }
    }
    else
    {
      DWORD error = GetNormalizedError();
      resPath = Prefixes.Back();
      Enumerators.DeleteBack();
      Prefixes.DeleteBack();
      return error;
    }
    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }
  resPath += fi.Name;
  if (EnterToDirs && fi.IsDir())
  {
    FString s = resPath;
    s += FCHAR_PATH_SEPARATOR;
    Prefixes.Add(s);
    s += FCHAR_ANY_MASK;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
  }
  filled = true;
  return S_OK;
}