Esempio n. 1
0
        public BitVector ReadBitVector2(int length)
        {
            byte allSet = ReadByte();
            if(allSet == 0)
                return ReadBitVector(length);

            var bits = new BitVector(length);
            for(int i = 0; i < length; i++)
                bits.SetBit(i);
            return bits;
        }
Esempio n. 2
0
        private void ReadSubStreamsInfo(DataReader mReader, FolderInfo[] folders, out int[] numUnpackStreamsInFolders, out List<ulong> unpackSizes, out BitVector crcDefined, out uint[] crcs)
        {
            numUnpackStreamsInFolders = new int[folders.Length];
            for(int i = 0; i < numUnpackStreamsInFolders.Length; i++)
                numUnpackStreamsInFolders[i] = 1;

            BlockType? type;
            for(; ; )
            {
                type = ReadBlockType(mReader);

                if(type == BlockType.NumUnpackStream)
                {
                    for(int i = 0; i < numUnpackStreamsInFolders.Length; i++)
                        numUnpackStreamsInFolders[i] = mReader.ReadPackedUInt31();
                    continue;
                }

                if(type == BlockType.End || type == BlockType.CRC || type == BlockType.Size)
                    break;

                SkipAttribute(mReader);
            }

            for(int i = 0; i < numUnpackStreamsInFolders.Length; i++)
            {
                int numSubstreams = numUnpackStreamsInFolders[i];
                if(numSubstreams == 0)
                    continue;

                ulong sum = 0;
                if(type == BlockType.Size)
                {
                    for(int j = 1; j < numSubstreams; j++)
                    {
                        ulong size = mReader.ReadPackedUInt64();
                        unpackSizes.Add(size);
                        sum += size;
                    }
                }

                unpackSizes.Add(folders[i].GetUnpackSize() - sum);
            }

            if(type == BlockType.Size)
                type = ReadBlockType(mReader);

            int numCRCs = 0;
            int numCRCsTotal = 0;
            for(int i = 0; i < folders.Length; i++)
            {
                int numSubstreams = numUnpackStreamsInFolders[i];
                if(numSubstreams != 1 || folders[i].UnpackCRC == null)
                    numCRCs += numSubstreams;
                numCRCsTotal += numSubstreams;
            }

            for(; ; )
            {
                if(type == BlockType.CRC)
                {
                    BitVector defined2;
                    uint[] crcs2;
                    ReadHashDigests(mReader, numCRCs, out defined2, out crcs2);

                }
                else if(type == BlockType.End)
                    break;
                else
                    SkipAttribute(mReader);

                type = ReadBlockType(mReader);
            }

            if(crcDefined == null)
            {
                throw new NotImplementedException();
            }
        }
Esempio n. 3
0
        public BitVector ReadBitVector(int length)
        {
            byte value = 0;
            byte mask = 0;

            BitVector bits = new BitVector(length);
            for(int i = 0; i < length; i++)
            {
                if(mask == 0)
                {
                    value = ReadByte();
                    mask = 0x80;
                }

                if((value & mask) != 0)
                    bits.SetBit(i);

                mask >>= 1;
            }

            // TODO: Make this a warning, not an exception.
            //while(mask != 0)
            //{
            //    if((value & mask) != 0)
            //        throw new InvalidDataException();
            //
            //    mask >>= 1;
            //}

            return bits;
        }
Esempio n. 4
0
 private void ReadStreamsInfo(DataReader mReader, out ulong[] packSizes, out BitVector packCRCsDefined, out uint[] packCRCs, out FolderInfo[] folders,
     out int[] numUnpackStreamsInFolders, out List<ulong> unpackSizes, out BitVector crcDefined, out uint[] crcs)
 {
     packSizes = null;
     packCRCsDefined = null;
     packCRCs = null;
     folders = null;
     numUnpackStreamsInFolders = null;
     unpackSizes = null;
     crcDefined = null;
     crcs = null;
     for(; ; )
     {
         var type = ReadBlockType(mReader);
         switch(type)
         {
         case BlockType.End:
             return;
         case BlockType.PackInfo:
             ReadPackInfo(mReader, out packSizes, out packCRCsDefined, out packCRCs);
             break;
         case BlockType.UnpackInfo:
             ReadUnpackInfo(mReader, out folders);
             break;
         case BlockType.SubStreamsInfo:
             ReadSubStreamsInfo(mReader, folders, out numUnpackStreamsInFolders, out unpackSizes, out crcDefined, out crcs);
             break;
         default:
             throw new InvalidDataException();
         }
     }
 }
Esempio n. 5
0
        private void ReadPackInfo(DataReader mReader, out ulong[] packSizes, out BitVector packCRCsDefined, out uint[] packCRCs)
        {
            packCRCsDefined = null;
            packCRCs = null;

            ulong dataOffset = mReader.ReadPackedUInt64();
            int numPackStreams = mReader.ReadPackedUInt31();

            WaitAttribute(mReader, BlockType.Size);
            {
                packSizes = new ulong[numPackStreams];
                for(int i = 0; i < numPackStreams; i++)
                    packSizes[i] = mReader.ReadPackedUInt64();
            }

            for(; ; )
            {
                var type = ReadBlockType(mReader);
                if(type == BlockType.End)
                    break;

                if(type == BlockType.CRC)
                    ReadHashDigests(mReader, numPackStreams, out packCRCsDefined, out packCRCs);
                else
                    SkipAttribute(mReader);
            }

            if(packCRCsDefined == null)
            {
                packCRCsDefined = new BitVector(numPackStreams);
                packCRCs = new uint[numPackStreams];
            }
        }
Esempio n. 6
0
 private void ReadHashDigests(DataReader mReader, int count, out BitVector defined, out uint[] digests)
 {
     defined = mReader.ReadBitVector2(count);
     digests = new uint[count];
     for(int i = 0; i < digests.Length; i++)
         if(defined[i])
             digests[i] = mReader.ReadUInt32();
 }
Esempio n. 7
0
        private void ReadHeader(CArchiveDatabaseEx db, IPasswordProvider getTextPassword)
        {
            Log.WriteLine("-- ReadHeader --");
            Log.PushIndent();
            try
            {
                BlockType? type = ReadId();

                if (type == BlockType.ArchiveProperties)
                {
                    ReadArchiveProperties();
                    type = ReadId();
                }

                List<byte[]> dataVector = null;
                if (type == BlockType.AdditionalStreamsInfo)
                {
                    dataVector = ReadAndDecodePackedStreams(db.StartPositionAfterHeader, getTextPassword);
                    type = ReadId();
                }

                List<long> unpackSizes;
                List<uint?> digests;

                if (type == BlockType.MainStreamsInfo)
                {
                    ReadStreamsInfo(dataVector,
                        out db.DataStartPosition,
                        out db.PackSizes,
                        out db.PackCRCs,
                        out db.Folders,
                        out db.NumUnpackStreamsVector,
                        out unpackSizes,
                        out digests);

                    db.DataStartPosition += db.StartPositionAfterHeader;
                    type = ReadId();
                }
                else
                {
                    unpackSizes = new List<long>(db.Folders.Count);
                    digests = new List<uint?>(db.Folders.Count);
                    db.NumUnpackStreamsVector = new List<int>(db.Folders.Count);
                    for (int i = 0; i < db.Folders.Count; i++)
                    {
                        var folder = db.Folders[i];
                        unpackSizes.Add(folder.GetUnpackSize());
                        digests.Add(folder.UnpackCRC);
                        db.NumUnpackStreamsVector.Add(1);
                    }
                }

                db.Files.Clear();

                if (type == BlockType.End)
                    return;

                if (type != BlockType.FilesInfo)
                    throw new InvalidDataException();

                int numFiles = ReadNum();
                Log.WriteLine("NumFiles: " + numFiles);
                db.Files = new List<CFileItem>(numFiles);
                for (int i = 0; i < numFiles; i++)
                    db.Files.Add(new CFileItem());

                BitVector emptyStreamVector = new BitVector(numFiles);
                BitVector emptyFileVector = null;
                BitVector antiFileVector = null;
                int numEmptyStreams = 0;

                for (;;)
                {
                    type = ReadId();
                    if (type == BlockType.End)
                        break;

                    long size = checked((long)ReadNumber()); // TODO: throw invalid data on negative
                    int oldPos = _currentReader.Offset;
                    switch (type)
                    {
                        case BlockType.Name:
                            using (var streamSwitch = new CStreamSwitch())
                            {
                                streamSwitch.Set(this, dataVector);
                                Log.Write("FileNames:");
                                for (int i = 0; i < db.Files.Count; i++)
                                {
                                    db.Files[i].Name = _currentReader.ReadString();
                                    Log.Write("  " + db.Files[i].Name);
                                }
                                Log.WriteLine();
                            }
                            break;
                        case BlockType.WinAttributes:
                            Log.Write("WinAttributes:");
                            ReadAttributeVector(dataVector, numFiles, delegate (int i, uint? attr)
                            {
                                db.Files[i].Attrib = attr;
                                Log.Write("  " + (attr.HasValue ? attr.Value.ToString("x8") : "n/a"));
                            });
                            Log.WriteLine();
                            break;
                        case BlockType.EmptyStream:
                            emptyStreamVector = ReadBitVector(numFiles);

                            Log.Write("EmptyStream: ");
                            for (int i = 0; i < emptyStreamVector.Length; i++)
                            {
                                if (emptyStreamVector[i])
                                {
                                    Log.Write("x");
                                    numEmptyStreams++;
                                }
                                else
                                {
                                    Log.Write(".");
                                }
                            }
                            Log.WriteLine();

                            emptyFileVector = new BitVector(numEmptyStreams);
                            antiFileVector = new BitVector(numEmptyStreams);
                            break;
                        case BlockType.EmptyFile:
                            emptyFileVector = ReadBitVector(numEmptyStreams);
                            Log.Write("EmptyFile: ");
                            for (int i = 0; i < numEmptyStreams; i++)
                                Log.Write(emptyFileVector[i] ? "x" : ".");
                            Log.WriteLine();
                            break;
                        case BlockType.Anti:
                            antiFileVector = ReadBitVector(numEmptyStreams);
                            Log.Write("Anti: ");
                            for (int i = 0; i < numEmptyStreams; i++)
                                Log.Write(antiFileVector[i] ? "x" : ".");
                            Log.WriteLine();
                            break;
                        case BlockType.StartPos:
                            Log.Write("StartPos:");
                            ReadNumberVector(dataVector, numFiles, delegate (int i, long? startPos)
                            {
                                db.Files[i].StartPos = startPos;
                                Log.Write("  " + (startPos.HasValue ? startPos.Value.ToString() : "n/a"));
                            });
                            Log.WriteLine();
                            break;
                        case BlockType.CTime:
                            Log.Write("CTime:");
                            ReadDateTimeVector(dataVector, numFiles, delegate (int i, DateTime? time)
                            {
                                db.Files[i].CTime = time;
                                Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
                            });
                            Log.WriteLine();
                            break;
                        case BlockType.ATime:
                            Log.Write("ATime:");
                            ReadDateTimeVector(dataVector, numFiles, delegate (int i, DateTime? time)
                            {
                                db.Files[i].ATime = time;
                                Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
                            });
                            Log.WriteLine();
                            break;
                        case BlockType.MTime:
                            Log.Write("MTime:");
                            ReadDateTimeVector(dataVector, numFiles, delegate (int i, DateTime? time)
                            {
                                db.Files[i].MTime = time;
                                Log.Write("  " + (time.HasValue ? time.Value.ToString() : "n/a"));
                            });
                            Log.WriteLine();
                            break;
                        case BlockType.Dummy:
                            Log.Write("Dummy: " + size);
                            for (long j = 0; j < size; j++)
                                if (ReadByte() != 0)
                                    throw new InvalidDataException();
                            break;
                        default:
                            SkipData(size);
                            break;
                    }

                    // since 0.3 record sizes must be correct
                    bool checkRecordsSize = (db.MajorVersion > 0 || db.MinorVersion > 2);
                    if (checkRecordsSize && _currentReader.Offset - oldPos != size)
                        throw new InvalidDataException();
                }

                int emptyFileIndex = 0;
                int sizeIndex = 0;
                for (int i = 0; i < numFiles; i++)
                {
                    CFileItem file = db.Files[i];
                    file.HasStream = !emptyStreamVector[i];
                    if (file.HasStream)
                    {
                        file.IsDir = false;
                        file.IsAnti = false;
                        file.Size = unpackSizes[sizeIndex];
                        file.Crc = digests[sizeIndex];
                        sizeIndex++;
                    }
                    else
                    {
                        file.IsDir = !emptyFileVector[emptyFileIndex];
                        file.IsAnti = antiFileVector[emptyFileIndex];
                        emptyFileIndex++;
                        file.Size = 0;
                        file.Crc = null;
                    }
                }
            }
            finally { Log.PopIndent(); }
        }
Esempio n. 8
0
        private BitVector ReadBitVector(int length)
        {
            var bits = new BitVector(length);

            byte data = 0;
            byte mask = 0;

            for (int i = 0; i < length; i++)
            {
                if (mask == 0)
                {
                    data = ReadByte();
                    mask = 0x80;
                }

                if ((data & mask) != 0)
                    bits.SetBit(i);

                mask >>= 1;
            }

            return bits;
        }