Exemple #1
0
static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
{
  for (;;)
  {
    UInt64 type;
    RINOK(SzReadID(sd, &type));
    if (type == attribute)
      return SZ_OK;
    if (type == k7zIdEnd)
      return SZ_ERROR_ARCHIVE;
    RINOK(SzSkeepData(sd));
  }
}
Exemple #2
0
static SRes SzReadPackInfo(
      CSzData *sd,
      uint64_t *dataOffset,
      uint32_t *numPackStreams,
      uint64_t **packSizes,
      uint8_t **packCRCsDefined,
      uint32_t **packCRCs,
      ISzAlloc *alloc)
{
   uint32_t i;
   RINOK(SzReadNumber(sd, dataOffset));
   RINOK(SzReadNumber32(sd, numPackStreams));

   RINOK(SzWaitAttribute(sd, k7zIdSize));

   MY_ALLOC(uint64_t, *packSizes, (size_t)*numPackStreams, alloc);

   for (i = 0; i < *numPackStreams; i++)
   {
      RINOK(SzReadNumber(sd, (*packSizes) + i));
   }

   for (;;)
   {
      uint64_t type;
      RINOK(SzReadID(sd, &type));
      if (type == k7zIdEnd)
         break;
      if (type == k7zIdCRC)
      {
         RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
         continue;
      }
      RINOK(SzSkeepData(sd));
   }
   if (*packCRCsDefined == 0)
   {
      MY_ALLOC(uint8_t, *packCRCsDefined, (size_t)*numPackStreams, alloc);
      MY_ALLOC(uint32_t, *packCRCs, (size_t)*numPackStreams, alloc);
      for (i = 0; i < *numPackStreams; i++)
      {
         (*packCRCsDefined)[i] = 0;
         (*packCRCs)[i] = 0;
      }
   }
   return SZ_OK;
}
Exemple #3
0
static SRes SzReadSubStreamsInfo(
      CSzData *sd,
      uint32_t numFolders,
      CSzFolder *folders,
      uint32_t *numUnpackStreams,
      uint64_t **unpackSizes,
      uint8_t **digestsDefined,
      uint32_t **digests,
      ISzAlloc *allocTemp)
{
   uint64_t type = 0;
   uint32_t i;
   uint32_t si = 0;
   uint32_t numDigests = 0;

   for (i = 0; i < numFolders; i++)
      folders[i].NumUnpackStreams = 1;
   *numUnpackStreams = numFolders;

   for (;;)
   {
      RINOK(SzReadID(sd, &type));
      if (type == k7zIdNumUnpackStream)
      {
         *numUnpackStreams = 0;
         for (i = 0; i < numFolders; i++)
         {
            uint32_t numStreams;
            RINOK(SzReadNumber32(sd, &numStreams));
            folders[i].NumUnpackStreams = numStreams;
            *numUnpackStreams += numStreams;
         }
         continue;
      }
      if (type == k7zIdCRC || type == k7zIdSize)
         break;
      if (type == k7zIdEnd)
         break;
      RINOK(SzSkeepData(sd));
   }

   if (*numUnpackStreams == 0)
   {
      *unpackSizes = 0;
      *digestsDefined = 0;
      *digests = 0;
   }
   else
   {
      *unpackSizes = (uint64_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint64_t));
      RINOM(*unpackSizes);
      *digestsDefined = (uint8_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint8_t));
      RINOM(*digestsDefined);
      *digests = (uint32_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint32_t));
      RINOM(*digests);
   }

   for (i = 0; i < numFolders; i++)
   {
      /*
         v3.13 incorrectly worked with empty folders
         v4.07: we check that folder is empty
         */
      uint64_t sum = 0;
      uint32_t j;
      uint32_t numSubstreams = folders[i].NumUnpackStreams;
      if (numSubstreams == 0)
         continue;
      if (type == k7zIdSize)
         for (j = 1; j < numSubstreams; j++)
         {
            uint64_t size;
            RINOK(SzReadNumber(sd, &size));
            (*unpackSizes)[si++] = size;
            sum += size;
         }
      (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
   }
   if (type == k7zIdSize)
   {
      RINOK(SzReadID(sd, &type));
   }

   for (i = 0; i < *numUnpackStreams; i++)
   {
      (*digestsDefined)[i] = 0;
      (*digests)[i] = 0;
   }


   for (i = 0; i < numFolders; i++)
   {
      uint32_t numSubstreams = folders[i].NumUnpackStreams;
      if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
         numDigests += numSubstreams;
   }


   si = 0;
   for (;;)
   {
      if (type == k7zIdCRC)
      {
         int digestIndex = 0;
         uint8_t *digestsDefined2 = 0;
         uint32_t *digests2 = 0;
         SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
         if (res == SZ_OK)
         {
            for (i = 0; i < numFolders; i++)
            {
               CSzFolder *folder = folders + i;
               uint32_t numSubstreams = folder->NumUnpackStreams;
               if (numSubstreams == 1 && folder->UnpackCRCDefined)
               {
                  (*digestsDefined)[si] = 1;
                  (*digests)[si] = folder->UnpackCRC;
                  si++;
               }
               else
               {
                  uint32_t j;
                  for (j = 0; j < numSubstreams; j++, digestIndex++)
                  {
                     (*digestsDefined)[si] = digestsDefined2[digestIndex];
                     (*digests)[si] = digests2[digestIndex];
                     si++;
                  }
               }
            }
         }
         IAlloc_Free(allocTemp, digestsDefined2);
         IAlloc_Free(allocTemp, digests2);
         RINOK(res);
      }
      else if (type == k7zIdEnd)
         return SZ_OK;
      else
      {
         RINOK(SzSkeepData(sd));
      }
      RINOK(SzReadID(sd, &type));
   }
}
Exemple #4
0
static SRes SzReadUnpackInfo(
      CSzData *sd,
      uint32_t *numFolders,
      CSzFolder **folders,  /* for alloc */
      ISzAlloc *alloc,
      ISzAlloc *allocTemp)
{
   uint32_t i;
   RINOK(SzWaitAttribute(sd, k7zIdFolder));
   RINOK(SzReadNumber32(sd, numFolders));
   {
      RINOK(SzReadSwitch(sd));

      MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);

      for (i = 0; i < *numFolders; i++)
         SzFolder_Init((*folders) + i);

      for (i = 0; i < *numFolders; i++)
      {
         RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
      }
   }

   RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));

   for (i = 0; i < *numFolders; i++)
   {
      uint32_t j;
      CSzFolder *folder = (*folders) + i;
      uint32_t numOutStreams = SzFolder_GetNumOutStreams(folder);

      MY_ALLOC(uint64_t, folder->UnpackSizes, (size_t)numOutStreams, alloc);

      for (j = 0; j < numOutStreams; j++)
      {
         RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
      }
   }

   for (;;)
   {
      uint64_t type;
      RINOK(SzReadID(sd, &type));
      if (type == k7zIdEnd)
         return SZ_OK;
      if (type == k7zIdCRC)
      {
         SRes res;
         uint8_t *crcsDefined = 0;
         uint32_t *crcs = 0;
         res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
         if (res == SZ_OK)
         {
            for (i = 0; i < *numFolders; i++)
            {
               CSzFolder *folder = (*folders) + i;
               folder->UnpackCRCDefined = crcsDefined[i];
               folder->UnpackCRC = crcs[i];
            }
         }
         IAlloc_Free(allocTemp, crcs);
         IAlloc_Free(allocTemp, crcsDefined);
         RINOK(res);
         continue;
      }
      RINOK(SzSkeepData(sd));
   }
}