1
0
mirror of https://github.com/chylex/Brotli-Builder.git synced 2025-01-09 14:42:50 +01:00
Brotli-Builder/BrotliLib/Brotli/BrotliFileStructure.cs

94 lines
3.2 KiB
C#

using System.Collections.Generic;
using BrotliLib.Brotli.Components;
using BrotliLib.Brotli.Encode;
using BrotliLib.IO;
namespace BrotliLib.Brotli{
/// <summary>
/// Represents the object structure of a Brotli-compressed file.
/// https://tools.ietf.org/html/rfc7932#section-2
/// </summary>
public sealed class BrotliFileStructure{
public static BrotliFileStructure NewEmpty(){
BrotliFileStructure bfs = new BrotliFileStructure(WindowSize.Default);
bfs.MetaBlocks.Add(new MetaBlock.LastEmpty());
return bfs;
}
public static BrotliFileStructure FromBytes(byte[] bytes){
return Serializer.FromBits(new BitStream(bytes).GetReader(), null);
}
public static BrotliFileStructure FromEncoder(WindowSize windowSize, IBrotliEncoder encoder, byte[] bytes){
BrotliFileStructure bfs = new BrotliFileStructure(windowSize);
foreach(MetaBlock metaBlock in encoder.GenerateMetaBlocks(bytes)){
bfs.MetaBlocks.Add(metaBlock);
}
return bfs;
}
// Data
public WindowSize WindowSize { get; set; }
public readonly IList<MetaBlock> MetaBlocks = new List<MetaBlock>();
private BrotliFileStructure(WindowSize windowSize){
this.WindowSize = windowSize;
}
private BrotliGlobalState CreateNewContext(){
return new BrotliGlobalState(BrotliDefaultDictionary.Embedded, WindowSize);
}
public BitStream Serialize(){
BitStream stream = new BitStream();
Serializer.ToBits(stream.GetWriter(), this, null);
return stream;
}
public BrotliGlobalState GetDecompressionState(BitStream bitStream){
BrotliGlobalState state = CreateNewContext();
Serializer.FromBits(bitStream.GetReader(), state);
return state;
}
public override string ToString(){
return Serialize().ToString();
}
// Serialization
private static readonly IBitSerializer<BrotliFileStructure, BrotliGlobalState> Serializer = new BitSerializer<BrotliFileStructure, BrotliGlobalState>(
fromBits: (reader, context) => {
WindowSize windowSize = WindowSize.Serializer.FromBits(reader, NoContext.Value);
BrotliFileStructure bfs = new BrotliFileStructure(windowSize);
BrotliGlobalState state = context ?? bfs.CreateNewContext();
while(true){
MetaBlock metaBlock = MetaBlock.Serializer.FromBits(reader, state);
bfs.MetaBlocks.Add(metaBlock);
if (metaBlock.IsLast){
break;
}
}
return bfs;
},
toBits: (writer, obj, context) => {
WindowSize.Serializer.ToBits(writer, obj.WindowSize, NoContext.Value);
BrotliGlobalState state = context ?? obj.CreateNewContext();
foreach(MetaBlock metaBlock in obj.MetaBlocks){
MetaBlock.Serializer.ToBits(writer, metaBlock, state);
}
}
);
}
}