Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/other-licenses/7zstub/src/CPP/7zip/Archive/7z/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 22 kB image not shown  

Quelle  7zOut.cpp   Sprache: C

 
// 7zOut.cpp

#include "StdAfx.h"

#include "../../../../C/7zCrc.h"

#include "../../../Common/AutoPtr.h"

#include "../../Common/StreamObjects.h"

#include "7zOut.h"

namespace NArchive {
namespace N7z {

HRESULT COutArchive::WriteSignature()
{
  Byte buf[8];
  memcpy(buf, kSignature, kSignatureSize);
  buf[kSignatureSize] = kMajorVersion;
  buf[kSignatureSize + 1] = 4;
  return WriteDirect(buf, 8);
}

#ifdef _7Z_VOL
HRESULT COutArchive::WriteFinishSignature()
{
  RINOK(WriteDirect(kFinishSignature, kSignatureSize));
  CArchiveVersion av;
  av.Major = kMajorVersion;
  av.Minor = 2;
  RINOK(WriteDirectByte(av.Major));
  return WriteDirectByte(av.Minor);
}
#endif

static void SetUInt32(Byte *p, UInt32 d)
{
  for (int i = 0; i < 4; i++, d >>= 8)
    p[i] = (Byte)d;
}

static void SetUInt64(Byte *p, UInt64 d)
{
  for (int i = 0; i < 8; i++, d >>= 8)
    p[i] = (Byte)d;
}

HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
{
  Byte buf[24];
  SetUInt64(buf + 4, h.NextHeaderOffset);
  SetUInt64(buf + 12, h.NextHeaderSize);
  SetUInt32(buf + 20, h.NextHeaderCRC);
  SetUInt32(buf, CrcCalc(buf + 4, 20));
  return WriteDirect(buf, 24);
}

#ifdef _7Z_VOL
HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
{
  CCRC crc;
  crc.UpdateUInt64(h.NextHeaderOffset);
  crc.UpdateUInt64(h.NextHeaderSize);
  crc.UpdateUInt32(h.NextHeaderCRC);
  crc.UpdateUInt64(h.ArchiveStartOffset);
  crc.UpdateUInt64(h.AdditionalStartBlockSize);
  RINOK(WriteDirectUInt32(crc.GetDigest()));
  RINOK(WriteDirectUInt64(h.NextHeaderOffset));
  RINOK(WriteDirectUInt64(h.NextHeaderSize));
  RINOK(WriteDirectUInt32(h.NextHeaderCRC));
  RINOK(WriteDirectUInt64(h.ArchiveStartOffset));
  return WriteDirectUInt64(h.AdditionalStartBlockSize);
}
#endif

HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
{
  Close();
  #ifdef _7Z_VOL
  // endMarker = false;
  _endMarker = endMarker;
  #endif
  SeqStream = stream;
  if (!endMarker)
  {
    SeqStream.QueryInterface(IID_IOutStream, &Stream);
    if (!Stream)
    {
      return E_NOTIMPL;
      // endMarker = true;
    }
  }
  #ifdef _7Z_VOL
  if (endMarker)
  {
    /*
    CStartHeader sh;
    sh.NextHeaderOffset = (UInt32)(Int32)-1;
    sh.NextHeaderSize = (UInt32)(Int32)-1;
    sh.NextHeaderCRC = 0;
    WriteStartHeader(sh);
    */

  }
  else
  #endif
  {
    if (!Stream)
      return E_FAIL;
    RINOK(WriteSignature());
    RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
  }
  return S_OK;
}

void COutArchive::Close()
{
  SeqStream.Release();
  Stream.Release();
}

HRESULT COutArchive::SkipPrefixArchiveHeader()
{
  #ifdef _7Z_VOL
  if (_endMarker)
    return S_OK;
  #endif
  Byte buf[24];
  memset(buf, 0, 24);
  return WriteDirect(buf, 24);
}

UInt64 COutArchive::GetPos() const
{
  if (_countMode)
    return _countSize;
  if (_writeToStream)
    return _outByte.GetProcessedSize();
  return _outByte2.GetPos();
}

void COutArchive::WriteBytes(const void *data, size_t size)
{
  if (_countMode)
    _countSize += size;
  else if (_writeToStream)
  {
    _outByte.WriteBytes(data, size);
    _crc = CrcUpdate(_crc, data, size);
  }
  else
    _outByte2.WriteBytes(data, size);
}

void COutArchive::WriteByte(Byte b)
{
  if (_countMode)
    _countSize++;
  else if (_writeToStream)
  {
    _outByte.WriteByte(b);
    _crc = CRC_UPDATE_BYTE(_crc, b);
  }
  else
    _outByte2.WriteByte(b);
}

void COutArchive::WriteUInt32(UInt32 value)
{
  for (int i = 0; i < 4; i++)
  {
    WriteByte((Byte)value);
    value >>= 8;
  }
}

void COutArchive::WriteUInt64(UInt64 value)
{
  for (int i = 0; i < 8; i++)
  {
    WriteByte((Byte)value);
    value >>= 8;
  }
}

void COutArchive::WriteNumber(UInt64 value)
{
  Byte firstByte = 0;
  Byte mask = 0x80;
  int i;
  for (i = 0; i < 8; i++)
  {
    if (value < ((UInt64(1) << ( 7  * (i + 1)))))
    {
      firstByte |= Byte(value >> (8 * i));
      break;
    }
    firstByte |= mask;
    mask >>= 1;
  }
  WriteByte(firstByte);
  for (; i > 0; i--)
  {
    WriteByte((Byte)value);
    value >>= 8;
  }
}

static UInt32 GetBigNumberSize(UInt64 value)
{
  int i;
  for (i = 1; i < 9; i++)
    if (value < (((UInt64)1 << (i * 7))))
      break;
  return i;
}

#ifdef _7Z_VOL
UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
{
  UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
  if (nameLength != 0)
  {
    nameLength = (nameLength + 1) * 2;
    result += nameLength + GetBigNumberSize(nameLength) + 2;
  }
  if (props)
  {
    result += 20;
  }
  if (result >= 128)
    result++;
  result += kSignatureSize + 2 + kFinishHeaderSize;
  return result;
}

UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
{
  UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props);
  int testSize;
  if (volSize > headersSizeBase)
    testSize = volSize - headersSizeBase;
  else
    testSize = 1;
  UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props);
  UInt64 pureSize = 1;
  if (volSize > headersSize)
    pureSize = volSize - headersSize;
  return pureSize;
}
#endif

void COutArchive::WriteFolder(const CFolder &folder)
{
  WriteNumber(folder.Coders.Size());
  unsigned i;
  
  for (i = 0; i < folder.Coders.Size(); i++)
  {
    const CCoderInfo &coder = folder.Coders[i];
    {
      UInt64 id = coder.MethodID;
      unsigned idSize;
      for (idSize = 1; idSize < sizeof(id); idSize++)
        if ((id >> (8 * idSize)) == 0)
          break;
      idSize &= 0xF;
      Byte temp[16];
      for (unsigned t = idSize; t != 0; t--, id >>= 8)
        temp[t] = (Byte)(id & 0xFF);
  
      Byte b = (Byte)(idSize);
      bool isComplex = !coder.IsSimpleCoder();
      b |= (isComplex ? 0x10 : 0);

      size_t propsSize = coder.Props.Size();
      b |= ((propsSize != 0) ? 0x20 : 0);
      temp[0] = b;
      WriteBytes(temp, idSize + 1);
      if (isComplex)
      {
        WriteNumber(coder.NumStreams);
        WriteNumber(1); // NumOutStreams;
      }
      if (propsSize == 0)
        continue;
      WriteNumber(propsSize);
      WriteBytes(coder.Props, propsSize);
    }
  }
  
  for (i = 0; i < folder.Bonds.Size(); i++)
  {
    const CBond &bond = folder.Bonds[i];
    WriteNumber(bond.PackIndex);
    WriteNumber(bond.UnpackIndex);
  }
  
  if (folder.PackStreams.Size() > 1)
    for (i = 0; i < folder.PackStreams.Size(); i++)
      WriteNumber(folder.PackStreams[i]);
}

void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
{
  Byte b = 0;
  Byte mask = 0x80;
  FOR_VECTOR (i, boolVector)
  {
    if (boolVector[i])
      b |= mask;
    mask >>= 1;
    if (mask == 0)
    {
      WriteByte(b);
      mask = 0x80;
      b = 0;
    }
  }
  if (mask != 0x80)
    WriteByte(b);
}

static inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }

void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
{
  WriteByte(id);
  WriteNumber(Bv_GetSizeInBytes(boolVector));
  WriteBoolVector(boolVector);
}

unsigned BoolVector_CountSum(const CBoolVector &v);

void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
{
  const unsigned numDefined = BoolVector_CountSum(digests.Defs);
  if (numDefined == 0)
    return;

  WriteByte(NID::kCRC);
  if (numDefined == digests.Defs.Size())
    WriteByte(1);
  else
  {
    WriteByte(0);
    WriteBoolVector(digests.Defs);
  }
  
  for (unsigned i = 0; i < digests.Defs.Size(); i++)
    if (digests.Defs[i])
      WriteUInt32(digests.Vals[i]);
}

void COutArchive::WritePackInfo(
    UInt64 dataOffset,
    const CRecordVector<UInt64> &packSizes,
    const CUInt32DefVector &packCRCs)
{
  if (packSizes.IsEmpty())
    return;
  WriteByte(NID::kPackInfo);
  WriteNumber(dataOffset);
  WriteNumber(packSizes.Size());
  WriteByte(NID::kSize);
  FOR_VECTOR (i, packSizes)
    WriteNumber(packSizes[i]);

  WriteHashDigests(packCRCs);
  
  WriteByte(NID::kEnd);
}

void COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders, const COutFolders &outFolders)
{
  if (folders.IsEmpty())
    return;

  WriteByte(NID::kUnpackInfo);

  WriteByte(NID::kFolder);
  WriteNumber(folders.Size());
  {
    WriteByte(0);
    FOR_VECTOR (i, folders)
      WriteFolder(folders[i]);
  }
  
  WriteByte(NID::kCodersUnpackSize);
  FOR_VECTOR (i, outFolders.CoderUnpackSizes)
    WriteNumber(outFolders.CoderUnpackSizes[i]);
  
  WriteHashDigests(outFolders.FolderUnpackCRCs);
  
  WriteByte(NID::kEnd);
}

void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
    const COutFolders &outFolders,
    const CRecordVector<UInt64> &unpackSizes,
    const CUInt32DefVector &digests)
{
  const CRecordVector<CNum> &numUnpackStreamsInFolders = outFolders.NumUnpackStreamsVector;
  WriteByte(NID::kSubStreamsInfo);

  unsigned i;
  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
    if (numUnpackStreamsInFolders[i] != 1)
    {
      WriteByte(NID::kNumUnpackStream);
      for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
        WriteNumber(numUnpackStreamsInFolders[i]);
      break;
    }
 
  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
    if (numUnpackStreamsInFolders[i] > 1)
    {
      WriteByte(NID::kSize);
      CNum index = 0;
      for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
      {
        CNum num = numUnpackStreamsInFolders[i];
        for (CNum j = 0; j < num; j++)
        {
          if (j + 1 != num)
            WriteNumber(unpackSizes[index]);
          index++;
        }
      }
      break;
    }

  CUInt32DefVector digests2;

  unsigned digestIndex = 0;
  for (i = 0; i < folders.Size(); i++)
  {
    unsigned numSubStreams = (unsigned)numUnpackStreamsInFolders[i];
    if (numSubStreams == 1 && outFolders.FolderUnpackCRCs.ValidAndDefined(i))
      digestIndex++;
    else
      for (unsigned j = 0; j < numSubStreams; j++, digestIndex++)
      {
        digests2.Defs.Add(digests.Defs[digestIndex]);
        digests2.Vals.Add(digests.Vals[digestIndex]);
      }
  }
  WriteHashDigests(digests2);
  WriteByte(NID::kEnd);
}

// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.

void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts)
{
  if (!_useAlign)
    return;

  const unsigned alignSize = (unsigned)1 << alignShifts;
  pos += (unsigned)GetPos();
  pos &= (alignSize - 1);
  if (pos == 0)
    return;
  unsigned skip = alignSize - pos;
  if (skip < 2)
    skip += alignSize;
  skip -= 2;
  WriteByte(NID::kDummy);
  WriteByte((Byte)skip);
  for (unsigned i = 0; i < skip; i++)
    WriteByte(0);
}

void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts)
{
  const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
  const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
  SkipToAligned(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);

  WriteByte(type);
  WriteNumber(dataSize);
  if (numDefined == v.Size())
    WriteByte(1);
  else
  {
    WriteByte(0);
    WriteBoolVector(v);
  }
  WriteByte(0); // 0 means no switching to external stream
}

void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
{
  const unsigned numDefined = BoolVector_CountSum(v.Defs);
  if (numDefined == 0)
    return;

  WriteAlignedBools(v.Defs, numDefined, type, 3);
  
  for (unsigned i = 0; i < v.Defs.Size(); i++)
    if (v.Defs[i])
      WriteUInt64(v.Vals[i]);
}

HRESULT COutArchive::EncodeStream(
    DECL_EXTERNAL_CODECS_LOC_VARS
    CEncoder &encoder, const CByteBuffer &data,
    CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders)
{
  CBufInStream *streamSpec = new CBufInStream;
  CMyComPtr<ISequentialInStream> stream = streamSpec;
  streamSpec->Init(data, data.Size());
  outFolders.FolderUnpackCRCs.Defs.Add(true);
  outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
  // outFolders.NumUnpackStreamsVector.Add(1);
  UInt64 dataSize64 = data.Size();
  UInt64 unpackSize = data.Size();
  RINOK(encoder.Encode(
      EXTERNAL_CODECS_LOC_VARS
      stream,
      // NULL,
      &dataSize64,
      folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
  return S_OK;
}

void COutArchive::WriteHeader(
    const CArchiveDatabaseOut &db,
    // const CHeaderOptions &headerOptions,
    UInt64 &headerOffset)
{
  /*
  bool thereIsSecure = (db.SecureBuf.Size() != 0);
  */

  _useAlign = true;

  {
    UInt64 packSize = 0;
    FOR_VECTOR (i, db.PackSizes)
      packSize += db.PackSizes[i];
    headerOffset = packSize;
  }


  WriteByte(NID::kHeader);

  // Archive Properties

  if (db.Folders.Size() > 0)
  {
    WriteByte(NID::kMainStreamsInfo);
    WritePackInfo(0, db.PackSizes, db.PackCRCs);
    WriteUnpackInfo(db.Folders, (const COutFolders &)db);

    CRecordVector<UInt64> unpackSizes;
    CUInt32DefVector digests;
    FOR_VECTOR (i, db.Files)
    {
      const CFileItem &file = db.Files[i];
      if (!file.HasStream)
        continue;
      unpackSizes.Add(file.Size);
      digests.Defs.Add(file.CrcDefined);
      digests.Vals.Add(file.Crc);
    }

    WriteSubStreamsInfo(db.Folders, (const COutFolders &)db, unpackSizes, digests);
    WriteByte(NID::kEnd);
  }

  if (db.Files.IsEmpty())
  {
    WriteByte(NID::kEnd);
    return;
  }

  WriteByte(NID::kFilesInfo);
  WriteNumber(db.Files.Size());

  {
    /* ---------- Empty Streams ---------- */
    CBoolVector emptyStreamVector;
    emptyStreamVector.ClearAndSetSize(db.Files.Size());
    unsigned numEmptyStreams = 0;
    {
      FOR_VECTOR (i, db.Files)
        if (db.Files[i].HasStream)
          emptyStreamVector[i] = false;
        else
        {
          emptyStreamVector[i] = true;
          numEmptyStreams++;
        }
    }

    if (numEmptyStreams != 0)
    {
      WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
      
      CBoolVector emptyFileVector, antiVector;
      emptyFileVector.ClearAndSetSize(numEmptyStreams);
      antiVector.ClearAndSetSize(numEmptyStreams);
      bool thereAreEmptyFiles = false, thereAreAntiItems = false;
      unsigned cur = 0;
      
      FOR_VECTOR (i, db.Files)
      {
        const CFileItem &file = db.Files[i];
        if (file.HasStream)
          continue;
        emptyFileVector[cur] = !file.IsDir;
        if (!file.IsDir)
          thereAreEmptyFiles = true;
        bool isAnti = db.IsItemAnti(i);
        antiVector[cur] = isAnti;
        if (isAnti)
          thereAreAntiItems = true;
        cur++;
      }
      
      if (thereAreEmptyFiles)
        WritePropBoolVector(NID::kEmptyFile, emptyFileVector);
      if (thereAreAntiItems)
        WritePropBoolVector(NID::kAnti, antiVector);
    }
  }


  {
    /* ---------- Names ---------- */
    
    unsigned numDefined = 0;
    size_t namesDataSize = 0;
    FOR_VECTOR (i, db.Files)
    {
      const UString &name = db.Names[i];
      if (!name.IsEmpty())
        numDefined++;
      namesDataSize += (name.Len() + 1) * 2;
    }
    
    if (numDefined > 0)
    {
      namesDataSize++;
      SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);

      WriteByte(NID::kName);
      WriteNumber(namesDataSize);
      WriteByte(0);
      FOR_VECTOR (i, db.Files)
      {
        const UString &name = db.Names[i];
        for (unsigned t = 0; t <= name.Len(); t++)
        {
          wchar_t c = name[t];
          WriteByte((Byte)c);
          WriteByte((Byte)(c >> 8));
        }
      }
    }
  }

  /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime);
  /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime);
  /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime);
  WriteUInt64DefVector(db.StartPos, NID::kStartPos);
  
  {
    /* ---------- Write Attrib ---------- */
    const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs);
    
    if (numDefined != 0)
    {
      WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2);
      FOR_VECTOR (i, db.Attrib.Defs)
      {
        if (db.Attrib.Defs[i])
          WriteUInt32(db.Attrib.Vals[i]);
      }
    }
  }

  /*
  {
    // ---------- Write IsAux ----------
    if (BoolVector_CountSum(db.IsAux) != 0)
      WritePropBoolVector(NID::kIsAux, db.IsAux);
  }

  {
    // ---------- Write Parent ----------
    CBoolVector boolVector;
    boolVector.Reserve(db.Files.Size());
    unsigned numIsDir = 0;
    unsigned numParentLinks = 0;
    for (i = 0; i < db.Files.Size(); i++)
    {
      const CFileItem &file = db.Files[i];
      bool defined = !file.IsAltStream;
      boolVector.Add(defined);
      if (defined)
        numIsDir++;
      if (file.Parent >= 0)
        numParentLinks++;
    }
    if (numParentLinks > 0)
    {
      // WriteAlignedBools(boolVector, numDefined, NID::kParent, 2);
      const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
      const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
      SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2);
      
      WriteByte(NID::kParent);
      WriteNumber(dataSize);
      if (numIsDir == boolVector.Size())
        WriteByte(1);
      else
      {
        WriteByte(0);
        WriteBoolVector(boolVector);
      }
      for (i = 0; i < db.Files.Size(); i++)
      {
        const CFileItem &file = db.Files[i];
        // if (file.Parent >= 0)
          WriteUInt32(file.Parent);
      }
    }
  }

  if (thereIsSecure)
  {
    UInt64 secureDataSize = 1 + 4 +
       db.SecureBuf.Size() +
       db.SecureSizes.Size() * 4;
    // secureDataSize += db.SecureIDs.Size() * 4;
    for (i = 0; i < db.SecureIDs.Size(); i++)
      secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
    SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2);
    WriteByte(NID::kNtSecure);
    WriteNumber(secureDataSize);
    WriteByte(0);
    WriteUInt32(db.SecureSizes.Size());
    for (i = 0; i < db.SecureSizes.Size(); i++)
      WriteUInt32(db.SecureSizes[i]);
    WriteBytes(db.SecureBuf, db.SecureBuf.Size());
    for (i = 0; i < db.SecureIDs.Size(); i++)
    {
      WriteNumber(db.SecureIDs[i]);
      // WriteUInt32(db.SecureIDs[i]);
    }
  }
  */


  WriteByte(NID::kEnd); // for files
  WriteByte(NID::kEnd); // for headers
}

HRESULT COutArchive::WriteDatabase(
    DECL_EXTERNAL_CODECS_LOC_VARS
    const CArchiveDatabaseOut &db,
    const CCompressionMethodMode *options,
    const CHeaderOptions &headerOptions)
{
  if (!db.CheckNumFiles())
    return E_FAIL;

  UInt64 headerOffset;
  UInt32 headerCRC;
  UInt64 headerSize;
  if (db.IsEmpty())
  {
    headerSize = 0;
    headerOffset = 0;
    headerCRC = CrcCalc(0, 0);
  }
  else
  {
    bool encodeHeaders = false;
    if (options != 0)
      if (options->IsEmpty())
        options = 0;
    if (options != 0)
      if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
        encodeHeaders = true;

    _outByte.SetStream(SeqStream);
    _outByte.Init();
    _crc = CRC_INIT_VAL;
    _countMode = encodeHeaders;
    _writeToStream = true;
    _countSize = 0;
    WriteHeader(db, /* headerOptions, */ headerOffset);

    if (encodeHeaders)
    {
      CByteBuffer buf(_countSize);
      _outByte2.Init((Byte *)buf, _countSize);
      
      _countMode = false;
      _writeToStream = false;
      WriteHeader(db, /* headerOptions, */ headerOffset);
      
      if (_countSize != _outByte2.GetPos())
        return E_FAIL;

      CCompressionMethodMode encryptOptions;
      encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
      encryptOptions.Password = options->Password;
      CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
      CRecordVector<UInt64> packSizes;
      CObjectVector<CFolder> folders;
      COutFolders outFolders;

      RINOK(EncodeStream(
          EXTERNAL_CODECS_LOC_VARS
          encoder, buf,
          packSizes, folders, outFolders));

      _writeToStream = true;
      
      if (folders.Size() == 0)
        throw 1;

      WriteID(NID::kEncodedHeader);
      WritePackInfo(headerOffset, packSizes, CUInt32DefVector());
      WriteUnpackInfo(folders, outFolders);
      WriteByte(NID::kEnd);
      FOR_VECTOR (i, packSizes)
        headerOffset += packSizes[i];
    }
    RINOK(_outByte.Flush());
    headerCRC = CRC_GET_DIGEST(_crc);
    headerSize = _outByte.GetProcessedSize();
  }
  #ifdef _7Z_VOL
  if (_endMarker)
  {
    CFinishHeader h;
    h.NextHeaderSize = headerSize;
    h.NextHeaderCRC = headerCRC;
    h.NextHeaderOffset =
        UInt64(0) - (headerSize +
        4 + kFinishHeaderSize);
    h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset;
    h.AdditionalStartBlockSize = 0;
    RINOK(WriteFinishHeader(h));
    return WriteFinishSignature();
  }
  else
  #endif
  {
    CStartHeader h;
    h.NextHeaderSize = headerSize;
    h.NextHeaderCRC = headerCRC;
    h.NextHeaderOffset = headerOffset;
    RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
    return WriteStartHeader(h);
  }
}

void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value)
{
  while (index >= Defs.Size())
    Defs.Add(false);
  Defs[index] = defined;
  if (!defined)
    return;
  while (index >= Vals.Size())
    Vals.Add(0);
  Vals[index] = value;
}

void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
{
  while (index >= Defs.Size())
    Defs.Add(false);
  Defs[index] = defined;
  if (!defined)
    return;
  while (index >= Vals.Size())
    Vals.Add(0);
  Vals[index] = value;
}

void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name)
{
  unsigned index = Files.Size();
  CTime.SetItem(index, file2.CTimeDefined, file2.CTime);
  ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
  MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
  StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
  Attrib.SetItem(index, file2.AttribDefined, file2.Attrib);
  SetItem_Anti(index, file2.IsAnti);
  // SetItem_Aux(index, file2.IsAux);
  Names.Add(name);
  Files.Add(file);
}

}}

Messung V0.5
C=96 H=91 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.