public override void Write(BinaryWriter bw, EncodingHeader header)
 {
     bw.Write((byte)1); // EKey count
     bw.WriteUInt40BE(DecompressedSize);
     bw.Write(CKey.Value);
     bw.Write(EKey.Value);
 }
Esempio n. 2
0
        public override void Write(BinaryWriter bw, EncodingHeader header)
        {
            bw.Write((byte)EKeys.Count);
            bw.WriteUInt40BE(DecompressedSize);
            bw.Write(CKey.Value);

            EKeys.ForEach(ekey => bw.Write(ekey.Value));
        }
Esempio n. 3
0
        /// <summary>
        /// Saves the EncodingFile to disk and optionally updates the BuildConfig
        /// </summary>
        /// <param name="directory">Root Directory</param>
        /// <param name="configContainer"></param>
        /// <returns></returns>
        public CASRecord Write(string directory, Configs.ConfigContainer configContainer = null)
        {
            if (Partial)
            {
                throw new NotSupportedException("Writing is not supported for partial EncodingFiles");
            }

            EBlock[] eblocks = new EBlock[_EncodingMap.Length];

            CASRecord record;

            using (var bt = new BlockTableStreamWriter(_EncodingMap[1], 1))
                using (var bw = new BinaryWriter(bt))
                {
                    // ESpecStringTable 1
                    bt.Write(string.Join('\0', ESpecStringTable).GetBytes());
                    EncodingHeader.ESpecTableSize = (uint)bt.Length;

                    // CKeysPageIndices 2, CKeysPageTable 3
                    WritePage(bw, eblocks, 2, EncodingHeader.CKeyPageSize << 10, _CKeyEntries);

                    // EKeysPageIndices 4, EKeysPageTable 5
                    WritePage(bw, eblocks, 4, EncodingHeader.EKeyPageSize << 10, _EKeyEntries);

                    // Header 0
                    bt.AddBlock(_EncodingMap[0], 0);
                    EncodingHeader.Write(bw);

                    // File ESpec 6
                    bt.AddBlock(_EncodingMap[6], 6);
                    bt.Write(GetFileESpec(bt.SubStreams).GetBytes());

                    // finalise
                    record = bt.Finalise();

                    // save
                    string saveLocation = Helpers.GetCDNPath(record.EKey.ToString(), "data", directory, true);
                    using (var fs = File.Create(saveLocation))
                    {
                        bt.WriteTo(fs);
                        record.BLTEPath = saveLocation;
                    }
                }

            // update the build config with the new values
            if (configContainer?.BuildConfig != null)
            {
                configContainer.BuildConfig.SetValue("encoding-size", record.EBlock.DecompressedSize, 0);
                configContainer.BuildConfig.SetValue("encoding-size", record.EBlock.CompressedSize, 1);
                configContainer.BuildConfig.SetValue("encoding", record.CKey, 0);
                configContainer.BuildConfig.SetValue("encoding", record.EKey, 1);
            }

            Checksum = record.CKey;
            return(record);
        }
        public override bool Read(BinaryReader br, EncodingHeader header)
        {
            EKey = new MD5Hash(br.ReadBytes(header.EKeyHashSize));
            if (EKey.IsEmpty)
            {
                return(false);
            }

            ESpecIndex     = br.ReadUInt32BE();
            CompressedSize = br.ReadUInt40BE();

            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a new EncodingFile
        /// </summary>
        public EncodingFile()
        {
            EncodingHeader   = new EncodingHeader();
            ESpecStringTable = new List <string> {
                "z", ""
            };
            _CKeyEntries = new CKeyPageTable(new MD5HashComparer());
            _EKeyEntries = new EKeyPageTable(new MD5HashComparer());

            _EncodingMap = new[]
            {
                new EMap(EType.None, 6),
                new EMap(EType.ZLib, 9),
                new EMap(EType.None, 6),
                new EMap(EType.None, 6),
                new EMap(EType.None, 6),
                new EMap(EType.None, 6),
                new EMap(EType.ZLib, 9),
            };
        }
Esempio n. 6
0
        public override bool Read(BinaryReader br, EncodingHeader header)
        {
            byte keyCount = br.ReadByte();

            if (keyCount == 0)
            {
                return(false);
            }

            DecompressedSize = br.ReadUInt40BE();
            CKey             = new MD5Hash(br.ReadBytes(header.CKeyHashSize));

            EKeys = new List <MD5Hash>(keyCount);
            for (var i = 0; i < keyCount; ++i)
            {
                EKeys.Add(new MD5Hash(br.ReadBytes(header.EKeyHashSize)));
            }

            return(true);
        }
Esempio n. 7
0
        private void Read(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (!stream.CanRead || stream.Length <= 1)
            {
                throw new NotSupportedException($"Unable to read EncodingFile stream");
            }

            using (var br = new BinaryReader(stream))
            {
                EncodingHeader.Read(br);

                // ESpec string table
                byte[] buffer = br.ReadBytes((int)EncodingHeader.ESpecTableSize);
                ESpecStringTable = Text.Encoding.ASCII.GetString(buffer).Split('\0').ToList();

                // skip CKey page table indices
                stream.Seek((int)EncodingHeader.CKeyPageCount * (EncodingHeader.CKeyHashSize + 16), SeekOrigin.Current);

                // read CKey entries
                _CKeyEntries.Capacity = (int)EncodingHeader.CKeyPageCount * 40;
                ReadPage(br, EncodingHeader.CKeyPageSize << 10, EncodingHeader.CKeyPageCount, _CKeyEntries);

                if (!Partial)
                {
                    // skip EKey page table indices
                    stream.Seek((int)EncodingHeader.EKeyPageCount * (EncodingHeader.EKeyHashSize + 16), SeekOrigin.Current);

                    // read EKey entries
                    _EKeyEntries.Capacity = (int)EncodingHeader.CKeyPageCount * 25;
                    ReadPage(br, EncodingHeader.EKeyPageSize << 10, EncodingHeader.EKeyPageCount, _EKeyEntries);

                    // remainder is an ESpec block for the file itself
                }

                Checksum = stream.MD5Hash();
            }
        }
        public override bool Read(BinaryReader br, EncodingHeader header)
        {
            byte keyCount = br.ReadByte();

            if (keyCount == 0)
            {
                return(false);
            }

            DecompressedSize = br.ReadUInt40BE();
            CKey             = new MD5Hash(br.ReadBytes(header.CKeyHashSize));

            EKey = new MD5Hash(br.ReadBytes(header.EKeyHashSize));

            if (keyCount > 1)
            {
                br.BaseStream.Position += (keyCount - 1) * header.EKeyHashSize;
            }

            return(true);
        }
Esempio n. 9
0
        /// <summary>
        /// Writes the page data and calculates the page lookups
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bw"></param>
        /// <param name="pageSize"></param>
        /// <param name="container"></param>
        /// <returns></returns>
        private PageIndexTable WritePageImpl <T>(BinaryWriter bw, int pageSize, IDictionary <MD5Hash, T> container) where T : EncodingEntryBase
        {
            PageIndexTable pageIndices = new PageIndexTable();
            bool           EOFflag     = typeof(T) == typeof(EncodingEncodedEntry);

            using (var md5 = MD5.Create())
            {
                // split entries into pages of pageSize
                var  pages     = EnumerablePartitioner.ConcreteBatch(container.Values, pageSize, (x) => x.Size);
                uint pageCount = (uint)pages.Count();

                // set Header PageCount
                EncodingHeader.SetPageCount <T>(pageCount);

                uint index = pageCount;
                foreach (var page in pages)
                {
                    // write page entries and pad to pageSize
                    page.ForEach(x => x.Write(bw, EncodingHeader));

                    // apply EOF flag (EKey page)
                    if (EOFflag && --index == 0)
                    {
                        bw.Write(new byte[EncodingHeader.EKeyHashSize]);
                        bw.Write(0xFFFFFFFF);
                    }

                    // pad to page size
                    bw.Write(new byte[pageSize - (bw.BaseStream.Position % pageSize)]);

                    // create page index record
                    pageIndices[page[0].Key] = bw.BaseStream.HashSlice(md5, bw.BaseStream.Position - pageSize, pageSize);
                    page.Clear();
                }
            }

            return(pageIndices);
        }
Esempio n. 10
0
 public override void Write(BinaryWriter bw, EncodingHeader header)
 {
     bw.Write(EKey.Value);
     bw.WriteUInt32BE(ESpecIndex);
     bw.WriteUInt40BE(CompressedSize);
 }
Esempio n. 11
0
 public abstract void Write(BinaryWriter bw, EncodingHeader header);
Esempio n. 12
0
 public abstract bool Read(BinaryReader br, EncodingHeader header);