using System; using System.Diagnostics; using System.IO; using BrotliLib.Brotli; using BrotliLib.Brotli.Encode; using BrotliLib.Brotli.Streaming; using BrotliLib.Markers; using BrotliLib.Markers.Builders; namespace BrotliCalc.Helpers{ abstract class BrotliFile{ private static int? TryGetFileSize(string path){ try{ return (int)new FileInfo(path).Length; }catch(Exception ex){ Debug.WriteLine(ex); return null; } } public string Path { get; } public string Name { get; } public abstract string FullName { get; } public byte[] Contents => contentsLazy.Value; public int? SizeBytes => sizeBytesLazy.Value; private readonly Lazy<byte[]> contentsLazy; private readonly Lazy<int?> sizeBytesLazy; protected BrotliFile(string path, string name){ this.Path = path; this.Name = name; this.contentsLazy = new Lazy<byte[]>(() => File.ReadAllBytes(Path), isThreadSafe: true); this.sizeBytesLazy = new Lazy<int?>(() => TryGetFileSize(Path), isThreadSafe: true); } public override string ToString(){ return FullName; } // Types internal class Uncompressed : BrotliFile{ public override string FullName => Name; public Uncompressed(string path, string name) : base(path, name){} public BrotliFileStructure Encode(IBrotliEncoder encoder){ return BrotliFileStructure.FromEncoder(Parameters.File, Parameters.Compression, Contents, encoder); } public IBrotliFileStream Encoding(IBrotliEncoder encoder){ return new BrotliFileStreamEncoder(Parameters.File, Parameters.Compression, Contents, encoder); } } internal class Compressed : BrotliFile{ public string Identifier { get; } public override string FullName => $"{Name}.{Identifier}{Brotli.CompressedFileExtension}"; public BrotliFileStructure Structure => structureLazy.Value; public BrotliFileReader Reader => BrotliFileReader.FromBytes(Contents, Parameters.File.Dictionary); private readonly Lazy<BrotliFileStructure> structureLazy; public Compressed(string path, string name, string identifier) : base(path, name){ this.Identifier = identifier; this.structureLazy = new Lazy<BrotliFileStructure>(() => BrotliFileStructure.FromBytes(Contents, Parameters.File.Dictionary), isThreadSafe: true); } public BrotliFileStructure Transform(IBrotliTransformer transformer){ return Structure.Transform(transformer, Parameters.Compression); } public IBrotliFileStream Transforming(IBrotliTransformer transformer){ return new BrotliFileStreamTransformer(Reader, Parameters.Compression, transformer); } public void WriteMarkers(StreamWriter stream, bool includeBitCounts, MarkerLevel markerLevel){ var writer = new MarkerTextWriter(stream, includeBitCounts); var reader = BrotliFileReader.FromBytes(Contents, Parameters.File.Dictionary, new MarkerSettings(markerLevel, writer)); while(reader.NextMetaBlock() != null){} } } } }