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); }
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)); }
/// <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); }
/// <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), }; }
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); }
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); }
/// <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); }
public override void Write(BinaryWriter bw, EncodingHeader header) { bw.Write(EKey.Value); bw.WriteUInt32BE(ESpecIndex); bw.WriteUInt40BE(CompressedSize); }
public abstract void Write(BinaryWriter bw, EncodingHeader header);
public abstract bool Read(BinaryReader br, EncodingHeader header);