示例#1
0
        private static void ReadPackInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            info.PackPosition = headerBytes.ReadEncodedInt64();
            int count = (int)headerBytes.ReadEncodedInt64();

            info.PackedStreams = new PackedStreamInfo[count];
            for (int i = 0; i < count; i++)
            {
                info.PackedStreams[i] = new PackedStreamInfo();
            }
            var prop = headerBytes.ReadProperty();

            if (prop != HeaderProperty.kSize)
            {
                throw new InvalidFormatException("Expected Size Property");
            }
            for (int i = 0; i < count; i++)
            {
                info.PackedStreams[i].PackedSize = headerBytes.ReadEncodedInt64();
            }
            for (int i = 0; i < count; i++)
            {
                prop = headerBytes.ReadProperty();
                if (prop != HeaderProperty.kCRC)
                {
                    break;
                }
                info.PackedStreams[i].Crc = headerBytes.ReadEncodedInt64();
            }
        }
示例#2
0
        private void ReadUnPackInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            var prop  = headerBytes.ReadProperty();
            int count = (int)headerBytes.ReadEncodedInt64();

            info.Folders = new Folder[count];
            if (headerBytes.ReadByte() != 0)
            {
                throw new NotSupportedException("External flag");
            }

            for (int i = 0; i < count; i++)
            {
                info.Folders[i] = ReadFolder(headerBytes);
            }

            prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kCodersUnPackSize)
            {
                throw new InvalidFormatException("Expected Size Property");
            }

            foreach (var folder in info.Folders)
            {
                int numOutStreams = folder.Coders.Aggregate(0, (sum, coder) => sum + (int)coder.NumberOfOutStreams);

                folder.UnpackedStreamSizes = new ulong[numOutStreams];

                for (uint j = 0; j < numOutStreams; j++)
                {
                    folder.UnpackedStreamSizes[j] = headerBytes.ReadEncodedInt64();
                }
            }


            prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kCRC)
            {
                return;
            }
            uint?[] crcs;
            UnPackDigests(headerBytes, info.Folders.Length, out crcs);
            for (int i = 0; i < info.Folders.Length; i++)
            {
                Folder folder = info.Folders[i];
                folder.UnpackCRC = crcs[i];
            }
            prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kEnd)
            {
                throw new InvalidFormatException("Expected End property");
            }
        }
示例#3
0
        private StreamsInfo ReadPackedStreams(HeaderBuffer headerBytes)
        {
            StreamsInfo info = new StreamsInfo();

            while (true)
            {
                var prop = headerBytes.ReadProperty();
                switch (prop)
                {
                case HeaderProperty.kUnPackInfo:
                {
                    ReadUnPackInfo(info, headerBytes);
                }
                break;

                case HeaderProperty.kPackInfo:
                {
                    ReadPackInfo(info, headerBytes);
                }
                break;

                case HeaderProperty.kSubStreamsInfo:
                {
                    ReadSubStreamsInfo(info, headerBytes);
                }
                break;

                case HeaderProperty.kEnd:
                    return(info);

                default:
                    throw new InvalidFormatException(prop.ToString());
                }
            }
        }
示例#4
0
        private void ReadFileHeader(HeaderBuffer headerBytes)
        {
            while (true)
            {
                var prop = headerBytes.ReadProperty();
                switch (prop)
                {
                case HeaderProperty.kMainStreamsInfo:
                {
                    FilesInfo = ReadPackedStreams(headerBytes);
                }
                break;

                case HeaderProperty.kFilesInfo:
                {
                    Entries = ReadFilesInfo(FilesInfo, headerBytes);
                }
                break;

                case HeaderProperty.kEnd:
                    return;

                default:
                    throw new InvalidFormatException(prop.ToString());
                }
            }
        }
示例#5
0
        private void ReadArchive(HeaderBuffer headerBytes)
        {
            while (true)
            {
                var prop = headerBytes.ReadProperty();
                switch (prop)
                {
                case HeaderProperty.kEncodedHeader:
                {
                    ArchiveInfo = ReadPackedStreams(headerBytes);
                    stream.Seek((long)ArchiveInfo.PackPosition + BaseOffset, SeekOrigin.Begin);
                    var firstFolder = ArchiveInfo.Folders.First();

                    ulong unpackSize = firstFolder.GetUnpackSize();

                    ulong packSize = ArchiveInfo.PackedStreams.Select(x => x.PackedSize)
                                     .Aggregate((ulong)0, (sum, size) => sum + size);

                    byte[]  unpackedBytes = new byte[(int)unpackSize];
                    Decoder decoder       = new Decoder();
                    decoder.SetDecoderProperties(firstFolder.Coders[0].Properties);
                    using (MemoryStream outStream = new MemoryStream(unpackedBytes))
                    {
                        decoder.Code(stream, outStream, (long)(packSize), (long)unpackSize, null);
                    }

                    headerBytes = new HeaderBuffer {
                        Bytes = unpackedBytes
                    };
                }
                break;

                case HeaderProperty.kHeader:
                {
                    ReadFileHeader(headerBytes);
                    return;
                }

                default:
                    throw new NotSupportedException("7Zip header " + prop);
                }
            }
        }
        private static HeaderEntry[] ReadFilesInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            var entries = headerBytes.CreateArray<HeaderEntry>();
            int numEmptyStreams = 0;
            while (true)
            {
                var type = headerBytes.ReadProperty();
                if (type == HeaderProperty.kEnd)
                {
                    break;
                }

                var size = (int)headerBytes.ReadEncodedInt64();

                switch (type)
                {
                    case HeaderProperty.kName:
                        {
                            if (headerBytes.ReadByte() != 0)
                            {
                                throw new InvalidFormatException("Cannot be external");
                            }
                            entries.ForEach(f => f.Name = headerBytes.ReadName());
                            break;
                        }
                    case HeaderProperty.kEmptyStream:
                        {
                            info.EmptyStreamFlags = headerBytes.ReadBoolFlags(entries.Length);
                            numEmptyStreams = info.EmptyStreamFlags.Where(x => x).Count();
                            break;
                        }
                    case HeaderProperty.kEmptyFile: //just read bytes
                    case HeaderProperty.kAnti:
                        {
                            info.EmptyFileFlags = headerBytes.ReadBoolFlags(numEmptyStreams);
                            break;
                        }
                    default:
                        {
                            headerBytes.ReadBytes(size);
                            break;
                        }
                }
            }
            int emptyFileIndex = 0;
            int sizeIndex = 0;
            for (int i = 0; i < entries.Length; i++)
            {
                HeaderEntry file = entries[i];
                file.IsAnti = false;
                if (info.EmptyStreamFlags == null)
                {
                    file.HasStream = true;
                }
                else
                {
                    file.HasStream = !info.EmptyStreamFlags[i];
                }
                if (file.HasStream)
                {
                    file.IsDirectory = false;
                    file.Size = info.UnpackedStreams[sizeIndex].UnpackedSize;
                    file.FileCRC = info.UnpackedStreams[sizeIndex].Digest;
                    sizeIndex++;
                }
                else
                {
                    if (info.EmptyFileFlags == null)
                    {
                        file.IsDirectory = true;
                    }
                    else
                    {
                        file.IsDirectory = !info.EmptyFileFlags[emptyFileIndex];
                    }
                    emptyFileIndex++;
                    file.Size = 0;
                }
            }
            return entries;
        }
        private void ReadUnPackInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            var prop = headerBytes.ReadProperty();
            int count = (int)headerBytes.ReadEncodedInt64();
            info.Folders = new Folder[count];
            if (headerBytes.ReadByte() != 0)
            {
                throw new NotSupportedException("External flag");
            }

            for (int i = 0; i < count; i++)
            {
                info.Folders[i] = ReadFolder(headerBytes);
            }

            prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kCodersUnPackSize)
            {
                throw new InvalidFormatException("Expected Size Property");
            }

            foreach (var folder in info.Folders)
            {
                int numOutStreams = folder.Coders.Aggregate(0, (sum, coder) => sum + (int)coder.NumberOfOutStreams);

                folder.UnpackedStreamSizes = new ulong[numOutStreams];

                for (uint j = 0; j < numOutStreams; j++)
                {
                    folder.UnpackedStreamSizes[j] = headerBytes.ReadEncodedInt64();
                }
            }

            prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kCRC)
            {
                return;
            }
            uint?[] crcs;
            UnPackDigests(headerBytes, info.Folders.Length, out crcs);
            for (int i = 0; i < info.Folders.Length; i++)
            {
                Folder folder = info.Folders[i];
                folder.UnpackCRC = crcs[i];
            } prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kEnd)
            {
                throw new InvalidFormatException("Expected End property");
            }
        }
 private StreamsInfo ReadPackedStreams(HeaderBuffer headerBytes)
 {
     StreamsInfo info = new StreamsInfo();
     while (true)
     {
         var prop = headerBytes.ReadProperty();
         switch (prop)
         {
             case HeaderProperty.kUnPackInfo:
                 {
                     ReadUnPackInfo(info, headerBytes);
                 }
                 break;
             case HeaderProperty.kPackInfo:
                 {
                     ReadPackInfo(info, headerBytes);
                 }
                 break;
             case HeaderProperty.kSubStreamsInfo:
                 {
                     ReadSubStreamsInfo(info, headerBytes);
                 }
                 break;
             case HeaderProperty.kEnd:
                 return info;
             default:
                 throw new InvalidFormatException(prop.ToString());
         }
     }
 }
 private void ReadFileHeader(HeaderBuffer headerBytes)
 {
     while (true)
     {
         var prop = headerBytes.ReadProperty();
         switch (prop)
         {
             case HeaderProperty.kMainStreamsInfo:
                 {
                     FilesInfo = ReadPackedStreams(headerBytes);
                 }
                 break;
             case HeaderProperty.kFilesInfo:
                 {
                     Entries = ReadFilesInfo(FilesInfo, headerBytes);
                 }
                 break;
             case HeaderProperty.kEnd:
                 return;
             default:
                 throw new InvalidFormatException(prop.ToString());
         }
     }
 }
        private void ReadArchive(HeaderBuffer headerBytes)
        {
            while (true)
            {
                var prop = headerBytes.ReadProperty();
                switch (prop)
                {
                    case HeaderProperty.kEncodedHeader:
                        {
                            ArchiveInfo = ReadPackedStreams(headerBytes);
                            stream.Seek((long)ArchiveInfo.PackPosition + BaseOffset, SeekOrigin.Begin);
                            var firstFolder = ArchiveInfo.Folders.First();

                            ulong unpackSize = firstFolder.GetUnpackSize();

                            ulong packSize = ArchiveInfo.PackedStreams.Select(x => x.PackedSize)
                                .Aggregate((ulong)0, (sum, size) => sum + size);

                            byte[] unpackedBytes = new byte[(int)unpackSize];
                            Decoder decoder = new Decoder();
                            decoder.SetDecoderProperties(firstFolder.Coders[0].Properties);
                            using (MemoryStream outStream = new MemoryStream(unpackedBytes))
                            {
                               decoder.Code(stream, outStream, (long)(packSize), (long)unpackSize, null);
                            }

                            headerBytes = new HeaderBuffer { Bytes = unpackedBytes };
                        }
                        break;
                    case HeaderProperty.kHeader:
                        {
                            ReadFileHeader(headerBytes);
                            return;
                        }
                    default:
                        throw new NotSupportedException("7Zip header " + prop);
                }
            }
        }
        private static void ReadSubStreamsInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            info.UnpackedStreams = new List<UnpackedStreamInfo>();
            foreach (var folder in info.Folders)
            {
                folder.UnpackedStreams = new UnpackedStreamInfo[1];
                folder.UnpackedStreams[0] = new UnpackedStreamInfo();
                info.UnpackedStreams.Add(folder.UnpackedStreams[0]);
            }

            bool loop = true;
            var prop = HeaderProperty.kEnd;
            while (loop)
            {
                prop = headerBytes.ReadProperty();
                switch (prop)
                {
                    case HeaderProperty.kNumUnPackStream:
                        {
                            info.UnpackedStreams.Clear();
                            foreach (var folder in info.Folders)
                            {
                                var numStreams = (int)headerBytes.ReadEncodedInt64();
                                folder.UnpackedStreams = new UnpackedStreamInfo[numStreams];
                                folder.UnpackedStreams.Initialize(() => new UnpackedStreamInfo());
                                info.UnpackedStreams.AddRange(folder.UnpackedStreams);
                            }
                        }
                        break;
                    case HeaderProperty.kCRC:
                    case HeaderProperty.kSize:
                    case HeaderProperty.kEnd:
                        {
                            loop = false;
                        }
                        break;
                    default:
                        throw new InvalidFormatException(prop.ToString());
                }
            }

            int si = 0;
            for (int i = 0; i < info.Folders.Length; i++)
            {
                var folder = info.Folders[i];
                ulong sum = 0;
                if (folder.UnpackedStreams.Length == 0)
                {
                    continue;
                }
                if (prop == HeaderProperty.kSize)
                {
                    for (int j = 1; j < folder.UnpackedStreams.Length; j++)
                    {
                        ulong size = headerBytes.ReadEncodedInt64();
                        info.UnpackedStreams[si].UnpackedSize = size;
                        sum += size;
                        si++;
                    }
                }
                info.UnpackedStreams[si].UnpackedSize = folder.GetUnpackSize() - sum;
                si++;
            }
            if (prop == HeaderProperty.kSize)
            {
                prop = headerBytes.ReadProperty();
            }

            int numDigests = 0;
            foreach (var folder in info.Folders)
            {
                if (folder.UnpackedStreams.Length != 1 || !folder.UnpackCRC.HasValue)
                {
                    numDigests += folder.UnpackedStreams.Length;
                }
            }

            si = 0;
            while (true)
            {
                if (prop == HeaderProperty.kCRC)
                {
                    int digestIndex = 0;
                    uint?[] digests2;
                    UnPackDigests(headerBytes, numDigests, out digests2);
                    for (uint i = 0; i < info.Folders.Length; i++)
                    {
                        Folder folder = info.Folders[i];
                        if (folder.UnpackedStreams.Length == 1 && folder.UnpackCRC.HasValue)
                        {
                            info.UnpackedStreams[si].Digest = folder.UnpackCRC;
                            si++;
                        }
                        else
                        {
                            for (uint j = 0; j < folder.UnpackedStreams.Length; j++, digestIndex++)
                            {
                                info.UnpackedStreams[si].Digest = digests2[digestIndex];
                                si++;
                            }
                        }
                    }
                }
                else if (prop == HeaderProperty.kEnd)
                    return;
                prop = headerBytes.ReadProperty();
            }
        }
        private static void ReadPackInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            info.PackPosition = headerBytes.ReadEncodedInt64();
            int count = (int)headerBytes.ReadEncodedInt64();

            info.PackedStreams = new PackedStreamInfo[count];
            for (int i = 0; i < count; i++)
            {
                info.PackedStreams[i] = new PackedStreamInfo();
            }
            var prop = headerBytes.ReadProperty();
            if (prop != HeaderProperty.kSize)
            {
                throw new InvalidFormatException("Expected Size Property");
            }
            for (int i = 0; i < count; i++)
            {
                info.PackedStreams[i].PackedSize = headerBytes.ReadEncodedInt64();

            }
            for (int i = 0; i < count; i++)
            {
                prop = headerBytes.ReadProperty();
                if (prop != HeaderProperty.kCRC)
                {
                    break;
                }
                info.PackedStreams[i].Crc = headerBytes.ReadEncodedInt64();
            }
        }
示例#13
0
        private static void ReadSubStreamsInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            info.UnpackedStreams = new List <UnpackedStreamInfo>();
            foreach (var folder in info.Folders)
            {
                folder.UnpackedStreams    = new UnpackedStreamInfo[1];
                folder.UnpackedStreams[0] = new UnpackedStreamInfo();
                info.UnpackedStreams.Add(folder.UnpackedStreams[0]);
            }

            bool loop = true;
            var  prop = HeaderProperty.kEnd;

            while (loop)
            {
                prop = headerBytes.ReadProperty();
                switch (prop)
                {
                case HeaderProperty.kNumUnPackStream:
                {
                    info.UnpackedStreams.Clear();
                    foreach (var folder in info.Folders)
                    {
                        var numStreams = (int)headerBytes.ReadEncodedInt64();
                        folder.UnpackedStreams = new UnpackedStreamInfo[numStreams];
                        folder.UnpackedStreams.Initialize(() => new UnpackedStreamInfo());
                        info.UnpackedStreams.AddRange(folder.UnpackedStreams);
                    }
                }
                break;

                case HeaderProperty.kCRC:
                case HeaderProperty.kSize:
                case HeaderProperty.kEnd:
                {
                    loop = false;
                }
                break;

                default:
                    throw new InvalidFormatException(prop.ToString());
                }
            }

            int si = 0;

            for (int i = 0; i < info.Folders.Length; i++)
            {
                var   folder = info.Folders[i];
                ulong sum    = 0;
                if (folder.UnpackedStreams.Length == 0)
                {
                    continue;
                }
                if (prop == HeaderProperty.kSize)
                {
                    for (int j = 1; j < folder.UnpackedStreams.Length; j++)
                    {
                        ulong size = headerBytes.ReadEncodedInt64();
                        info.UnpackedStreams[si].UnpackedSize = size;
                        sum += size;
                        si++;
                    }
                }
                info.UnpackedStreams[si].UnpackedSize = folder.GetUnpackSize() - sum;
                si++;
            }
            if (prop == HeaderProperty.kSize)
            {
                prop = headerBytes.ReadProperty();
            }

            int numDigests = 0;

            foreach (var folder in info.Folders)
            {
                if (folder.UnpackedStreams.Length != 1 || !folder.UnpackCRC.HasValue)
                {
                    numDigests += folder.UnpackedStreams.Length;
                }
            }

            si = 0;
            while (true)
            {
                if (prop == HeaderProperty.kCRC)
                {
                    int     digestIndex = 0;
                    uint?[] digests2;
                    UnPackDigests(headerBytes, numDigests, out digests2);
                    for (uint i = 0; i < info.Folders.Length; i++)
                    {
                        Folder folder = info.Folders[i];
                        if (folder.UnpackedStreams.Length == 1 && folder.UnpackCRC.HasValue)
                        {
                            info.UnpackedStreams[si].Digest = folder.UnpackCRC;
                            si++;
                        }
                        else
                        {
                            for (uint j = 0; j < folder.UnpackedStreams.Length; j++, digestIndex++)
                            {
                                info.UnpackedStreams[si].Digest = digests2[digestIndex];
                                si++;
                            }
                        }
                    }
                }
                else if (prop == HeaderProperty.kEnd)
                {
                    return;
                }
                prop = headerBytes.ReadProperty();
            }
        }
示例#14
0
        private static HeaderEntry[] ReadFilesInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            var entries         = headerBytes.CreateArray <HeaderEntry>();
            int numEmptyStreams = 0;

            while (true)
            {
                var type = headerBytes.ReadProperty();
                if (type == HeaderProperty.kEnd)
                {
                    break;
                }

                var size = (int)headerBytes.ReadEncodedInt64();

                switch (type)
                {
                case HeaderProperty.kName:
                {
                    if (headerBytes.ReadByte() != 0)
                    {
                        throw new InvalidFormatException("Cannot be external");
                    }
                    entries.ForEach(f => f.Name = headerBytes.ReadName());
                    break;
                }

                case HeaderProperty.kEmptyStream:
                {
                    info.EmptyStreamFlags = headerBytes.ReadBoolFlags(entries.Length);
                    numEmptyStreams       = info.EmptyStreamFlags.Where(x => x).Count();
                    break;
                }

                case HeaderProperty.kEmptyFile:     //just read bytes
                case HeaderProperty.kAnti:
                {
                    info.EmptyFileFlags = headerBytes.ReadBoolFlags(numEmptyStreams);
                    break;
                }

                default:
                {
                    headerBytes.ReadBytes(size);
                    break;
                }
                }
            }
            int emptyFileIndex = 0;
            int sizeIndex      = 0;

            for (int i = 0; i < entries.Length; i++)
            {
                HeaderEntry file = entries[i];
                file.IsAnti = false;
                if (info.EmptyStreamFlags == null)
                {
                    file.HasStream = true;
                }
                else
                {
                    file.HasStream = !info.EmptyStreamFlags[i];
                }
                if (file.HasStream)
                {
                    file.IsDirectory = false;
                    file.Size        = info.UnpackedStreams[sizeIndex].UnpackedSize;
                    file.FileCRC     = info.UnpackedStreams[sizeIndex].Digest;
                    sizeIndex++;
                }
                else
                {
                    if (info.EmptyFileFlags == null)
                    {
                        file.IsDirectory = true;
                    }
                    else
                    {
                        file.IsDirectory = !info.EmptyFileFlags[emptyFileIndex];
                    }
                    emptyFileIndex++;
                    file.Size = 0;
                }
            }
            return(entries);
        }