예제 #1
0
        public void Load(Stream stream, bool ownsStream)
        {
            mBaseStream = stream;
            mOwnsStream = ownsStream;

            using (var reader = new EndianBinaryReader(stream, Encoding.Default, true, Endianness.LittleEndian))
            {
                while (reader.Position < reader.BaseStreamLength)
                {
                    var type = reader.ReadByte();
                    if (type == 0xFF)   // end
                    {
                        break;
                    }

                    var isCompressed       = reader.ReadBoolean();
                    var userId             = reader.ReadInt16();
                    var length             = reader.ReadInt32() - 16;
                    var extension          = reader.ReadString(StringBinaryFormat.FixedLength, 4);
                    var decompressedLength = reader.ReadInt32();
                    var offset             = ( int )reader.Position;

                    var entry = new StoredEntry(AllocateHandle(), mBaseStream, offset, type, isCompressed, userId, length, extension, decompressedLength);
                    mEntryMap[entry.Handle] = entry;

                    reader.SeekCurrent(length);
                    reader.Position = AlignmentUtils.Align(reader.Position, 64);
                }
            }
        }
예제 #2
0
        private void ReadEntries()
        {
            mEntryMap = new Dictionary <string, IEntry>(StringComparer.InvariantCultureIgnoreCase);

            using (var reader = new EndianBinaryReader(mBaseStream, Encoding.Default, true, IsBigEndian ? Endianness.BigEndian : Endianness.LittleEndian))
            {
                var stringBuilder = new StringBuilder();

                if (Version == FormatVersion.Version1)
                {
                    while (true)
                    {
                        long entryStartPosition = reader.BaseStream.Position;
                        if (entryStartPosition == reader.BaseStream.Length)
                        {
                            break;
                        }

                        // read entry name
                        while (true)
                        {
                            byte b = reader.ReadByte();
                            if (b == 0)
                            {
                                break;
                            }

                            stringBuilder.Append(( char )b);

                            // just to be safe
                            if (stringBuilder.Length == 252)
                            {
                                break;
                            }
                        }

                        string fileName = stringBuilder.ToString();

                        // set position to length field
                        reader.BaseStream.Position = entryStartPosition + 252;

                        // read entry length
                        int length = reader.ReadInt32();

                        if (fileName.Length == 0 || length <= 0 || length > 1024 * 1024 * 100)
                        {
                            break;
                        }

                        // make an entry
                        var entry = new StoredEntry(mBaseStream, fileName, length, ( int )reader.BaseStream.Position);

                        // clear string builder for next iteration
                        stringBuilder.Clear();

                        reader.BaseStream.Position = AlignmentUtils.Align(reader.BaseStream.Position + entry.Length, 64);

                        mEntryMap[entry.FileName] = entry;
                    }
                }
                else if (Version == FormatVersion.Version2 || Version == FormatVersion.Version2BE || Version == FormatVersion.Version3 || Version == FormatVersion.Version3BE)
                {
                    int entryCount = reader.ReadInt32();
                    int nameLength = 32;
                    if (Version == FormatVersion.Version3)
                    {
                        nameLength = 24;
                    }

                    for (int i = 0; i < entryCount; i++)
                    {
                        long entryStartPosition = reader.BaseStream.Position;
                        if (entryStartPosition == reader.BaseStream.Length)
                        {
                            break;
                        }

                        // read entry name
                        for (int j = 0; j < nameLength; j++)
                        {
                            byte b = reader.ReadByte();

                            if (b != 0)
                            {
                                stringBuilder.Append(( char )b);
                            }
                        }

                        string fileName = stringBuilder.ToString();

                        // read entry length
                        int length = reader.ReadInt32();

                        if (fileName.Length == 0 || length <= 0 || length > 1024 * 1024 * 100)
                        {
                            break;
                        }

                        // make an entry
                        var entry = new StoredEntry(mBaseStream, fileName, length, ( int )reader.BaseStream.Position);

                        // clear string builder for next iteration
                        stringBuilder.Clear();

                        reader.BaseStream.Position += entry.Length;

                        mEntryMap[entry.FileName] = entry;
                    }
                }
            }
        }