Example #1
0
        protected override FileIndexEntry[] ReadEntries()
        {
            var entries = new List <FileIndexEntry>();

            var length = (int)(_fileInfo.Length / 3 / 4);

            using var index = new FileStream(_indexPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            var binaryReader = new BinaryReader(index);

            var count = (int)(index.Length / 12);

            for (var i = 0; i < count && i < length; ++i)
            {
                var entry = new FileIndexEntry
                {
                    Lookup = binaryReader.ReadInt32(),
                    Length = binaryReader.ReadInt32(),
                    Extra  = binaryReader.ReadInt32()
                };

                entries.Add(entry);
            }

            for (var i = count; i < length; ++i)
            {
                var entry = new FileIndexEntry
                {
                    Lookup = -1,
                    Length = -1,
                    Extra  = -1
                };

                entries.Add(entry);
            }

            return(entries.ToArray());
        }
Example #2
0
        protected override FileIndexEntry[] ReadEntries()
        {
            var length   = Length;
            var dataPath = DataPath;
            var entries  = new FileIndexEntry[length];

            for (var i = 0; i < entries.Length; i++)
            {
                entries[i].Lookup = -1;
            }

            using var index = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            var fileInfo   = new FileInfo(dataPath);
            var uopPattern = Path.GetFileNameWithoutExtension(fileInfo.Name).ToLowerInvariant();

            using var binaryReader = new BinaryReader(index);
            binaryReader.BaseStream.Seek(0, SeekOrigin.Begin);

            if (binaryReader.ReadInt32() != UOP_MAGIC_NUMBER)
            {
                throw new ArgumentException("Bad UOP file.");
            }

            binaryReader.ReadInt64(); // version + signature
            var nextBlock = binaryReader.ReadInt64();

            binaryReader.ReadInt32(); // block capacity
            var count = binaryReader.ReadInt32();

            var hashes = new Dictionary <ulong, int>();

            for (var i = 0; i < length; i++)
            {
                var entryName = $"build/{uopPattern}/{i:D8}{_extension}";
                var hash      = CreateHash(entryName);

                if (!hashes.ContainsKey(hash))
                {
                    hashes.Add(hash, i);
                }
            }

            binaryReader.BaseStream.Seek(nextBlock, SeekOrigin.Begin);

            do
            {
                var filesCount = binaryReader.ReadInt32();
                nextBlock = binaryReader.ReadInt64();

                for (var i = 0; i < filesCount; i++)
                {
                    var offset             = binaryReader.ReadInt64();
                    var headerLength       = binaryReader.ReadInt32();
                    var compressedLength   = binaryReader.ReadInt32();
                    var decompressedLength = binaryReader.ReadInt32();
                    var hash = binaryReader.ReadUInt64();
                    binaryReader.ReadUInt32(); // Adler32
                    var flag = binaryReader.ReadInt16();

                    var entryLength = flag == 1 ? compressedLength : decompressedLength;

                    if (offset == 0)
                    {
                        continue;
                    }

                    if (hashes.TryGetValue(hash, out var idx))
                    {
                        if (idx < 0 || idx > entries.Length)
                        {
                            throw new IndexOutOfRangeException("hashes dictionary and files collection have different count of entries!");
                        }

                        entries[idx].Lookup = (int)(offset + headerLength);
                        entries[idx].Length = entryLength;

                        if (_hasExtra)
                        {
                            var cursorPosition = binaryReader.BaseStream.Position;

                            binaryReader.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin);

                            var extra = binaryReader.ReadBytes(8);

                            var extra1 = (ushort)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]);
                            var extra2 = (ushort)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]);

                            entries[idx].Lookup += 8;
                            entries[idx].Extra   = extra1 << 16 | extra2;

                            binaryReader.BaseStream.Seek(cursorPosition, SeekOrigin.Begin);
                        }
                    }
                }
            }while (binaryReader.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0);

            return(entries);
        }