Esempio n. 1
0
        private void AddLayoutEntry(CASResult blte)
        {
            if (Layout.ContainsKey(blte.Hash))
            {
                Layout.Remove(blte.Hash);
            }

            // get layout string
            string layoutString;
            uint   size = blte.CompressedSize - 30;

            if (blte.DataHash == CASContainer.BuildConfig.GetKey("root")) // root is always z
            {
                layoutString = "z";
            }
            else if (size >= 1024 * 256) // 256K* seems to be the max
            {
                layoutString = "b:{256K*=z}";
            }
            else if (size > 1024)
            {
                layoutString = "b:{" + (int)Math.Floor(size / 1024d) + "K*=z}"; // closest floored KB
            }
            else
            {
                layoutString = "b:{" + size + "*=z}"; // actual B size
            }
            // string index
            int stridx = LayoutStringTable.IndexOf(layoutString);

            if (stridx == -1)
            {
                stridx = LayoutStringTable.Count - 2; // ignore the 0 byte
                LayoutStringTable.Insert(stridx, layoutString);
            }

            // create the entry
            var entry = new EncodingLayout()
            {
                Size        = size,
                Hash        = blte.Hash,
                StringIndex = (uint)stridx
            };

            Layout.Add(entry.Hash, entry);
        }
Esempio n. 2
0
        public EncodingHandler(BLTEStream blte)
        {
            if (blte.Length != long.Parse(CASContainer.BuildConfig["encoding-size"][0]))
            {
                CASContainer.Settings?.Logger.LogAndThrow(Logging.LogType.Critical, "Encoding File is corrupt.");
            }

            BinaryReader stream = new BinaryReader(blte);

            Header = new EncodingHeader()
            {
                Magic           = stream.ReadBytes(2),
                Version         = stream.ReadByte(),
                ChecksumSizeA   = stream.ReadByte(),
                ChecksumSizeB   = stream.ReadByte(),
                FlagsA          = stream.ReadUInt16(),
                FlagsB          = stream.ReadUInt16(),
                NumEntriesA     = stream.ReadUInt32BE(),
                NumEntriesB     = stream.ReadUInt32BE(),
                StringBlockSize = stream.ReadUInt40BE()
            };

            // stringTableA
            LayoutStringTable.AddRange(Encoding.ASCII.GetString(stream.ReadBytes((int)Header.StringBlockSize)).Split('\0'));

            // skip header block A
            stream.ReadBytes((int)Header.NumEntriesA * 32);

            // encoding table entry block
            for (int i = 0; i < Header.NumEntriesA; i++)
            {
                long start = stream.BaseStream.Position;

                ushort keysCount;
                while ((keysCount = stream.ReadUInt16()) != 0)
                {
                    EncodingEntry entry = new EncodingEntry()
                    {
                        DecompressedSize = stream.ReadUInt32BE(),
                        Hash             = new MD5Hash(stream)
                    };

                    for (int ki = 0; ki < keysCount; ki++)
                    {
                        entry.Keys.Add(new MD5Hash(stream));
                    }

                    Data.Add(entry.Hash, entry);
                }

                if (stream.BaseStream.Position % CHUNK_SIZE != 0)
                {
                    stream.BaseStream.Position += CHUNK_SIZE - ((stream.BaseStream.Position - start) % CHUNK_SIZE);
                }
            }

            // skip header block B
            stream.ReadBytes((int)Header.NumEntriesB * 32);

            // layout table entry block
            for (int i = 0; i < Header.NumEntriesB; i++)
            {
                long start = stream.BaseStream.Position;

                MD5Hash hash;
                while (!(hash = new MD5Hash(stream)).IsEmpty)
                {
                    var entry = new EncodingLayout()
                    {
                        Hash        = hash,
                        StringIndex = stream.ReadUInt32BE(),
                        Size        = stream.ReadUInt40BE()
                    };

                    Layout.Add(entry.Hash, entry);
                }

                if (stream.BaseStream.Position % CHUNK_SIZE != 0)
                {
                    stream.BaseStream.Position += CHUNK_SIZE - ((stream.BaseStream.Position - start) % CHUNK_SIZE);
                }
            }

            stream.ReadBytes((int)(stream.BaseStream.Length - stream.BaseStream.Position)); //EncodingStringTable

            EncodingMap = blte.EncodingMap.ToArray();

            blte?.Dispose();
            stream?.Dispose();
        }