예제 #1
0
        private Folder ReadFolder(HeaderBuffer headerBytes)
        {
            Folder folder = new Folder(this);

            folder.Coders = headerBytes.CreateArray <CodersInfo>();

            int numInStreams  = 0;
            int numOutStreams = 0;

            foreach (var coder in folder.Coders)
            {
                byte mainByte = headerBytes.ReadByte();
                int  size     = (byte)(mainByte & 0xF);
                coder.Method = headerBytes.ReadBytes(size);
                if ((mainByte & 0x10) != 0)
                {
                    coder.NumberOfInStreams  = headerBytes.ReadEncodedInt64();
                    coder.NumberOfOutStreams = headerBytes.ReadEncodedInt64();
                }
                else
                {
                    coder.NumberOfInStreams  = 1;
                    coder.NumberOfOutStreams = 1;
                }
                if ((mainByte & 0x20) != 0)
                {
                    ulong propertiesSize = headerBytes.ReadEncodedInt64();
                    coder.Properties = headerBytes.ReadBytes((int)propertiesSize);
                }
                while ((mainByte & 0x80) != 0)
                {
                    mainByte = headerBytes.ReadByte();
                    headerBytes.ReadBytes(mainByte & 0xF);
                    if ((mainByte & 0x10) != 0)
                    {
                        headerBytes.ReadEncodedInt64();
                        headerBytes.ReadEncodedInt64();
                    }
                    if ((mainByte & 0x20) != 0)
                    {
                        ulong propertiesSize = headerBytes.ReadEncodedInt64();
                        headerBytes.ReadBytes((int)propertiesSize);
                    }
                }
                numInStreams  += (int)coder.NumberOfInStreams;
                numOutStreams += (int)coder.NumberOfOutStreams;
            }

            int numBindPairs = numOutStreams - 1;

            folder.BindPairs = new BindPair[numBindPairs];

            for (int i = 0; i < numBindPairs; i++)
            {
                BindPair bindpair = new BindPair();
                folder.BindPairs[i] = bindpair;
                bindpair.InIndex    = headerBytes.ReadEncodedInt64();
                bindpair.OutIndex   = headerBytes.ReadEncodedInt64();
            }


            int numPackedStreams = numInStreams - numBindPairs;

            folder.PackedStreamIndices = new ulong[numPackedStreams];

            if (numPackedStreams == 1)
            {
                uint pi = 0;
                for (uint j = 0; j < numInStreams; j++)
                {
                    if (!folder.BindPairs.Where(x => x.InIndex == j).Any())
                    {
                        folder.PackedStreamIndices[pi++] = j;
                        break;
                    }
                }
            }
            else
            {
                for (uint i = 0; i < numPackedStreams; i++)
                {
                    folder.PackedStreamIndices[i] = headerBytes.ReadEncodedInt64();
                }
            }
            return(folder);
        }
예제 #2
0
        private static HeaderEntry[] ReadFilesInfo(StreamsInfo info, HeaderBuffer headerBytes)
        {
            var entries = headerBytes.CreateArray <HeaderEntry>();

            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);
                    break;
                }

                case HeaderProperty.kEmptyFile:
                {
                    info.EmptyFileFlags = headerBytes.ReadBoolFlags(entries.Length);
                    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);
        }