1
0
mirror of https://github.com/chylex/Brotli-Builder.git synced 2025-08-16 21:31:47 +02:00
Files
BrotliBuilder
BrotliCalc
BrotliImpl
BrotliLib
Brotli
Components
Compressed
Data
BlockLengthCode.cs
BlockSwitchCommand.cs
BlockSwitchTracker.cs
BlockTypeCode.cs
DistanceCode.Type.Complex.cs
DistanceCode.Type.Direct.cs
DistanceCode.Type.Last.cs
DistanceCode.cs
DistanceInfo.cs
InsertCopyCommand.cs
InsertCopyLengthCode.cs
InsertCopyLengths.cs
Literal.cs
Header
MetaBlock.Type.Compressed.cs
MetaBlock.Type.LastEmpty.cs
MetaBlock.Type.PaddedEmpty.cs
MetaBlock.Type.Uncompressed.cs
MetaBlock.cs
WindowSize.cs
Dictionary
Encode
Output
Parameters
Streaming
Utils
BrotliFileStructure.cs
BrotliGlobalState.cs
Collections
Exceptions
Markers
Numbers
Serialization
BrotliLib.csproj
LICENSE-BROTLI.txt
UnitTests
.gitignore
BrotliBuilder.sln
LICENSE
README.md

99 lines
3.4 KiB
C#

using System;
using BrotliLib.Brotli.Components.Header;
using BrotliLib.Brotli.Encode.Build;
using BrotliLib.Brotli.Utils;
using BrotliLib.Markers.Serialization;
using BrotliLib.Serialization;
namespace BrotliLib.Brotli.Components.Data{
public sealed class BlockSwitchCommand{
private const int FinalCommandLengthPlaceholder = -1;
/// <summary>
/// Next block type.
/// </summary>
public byte Type { get; }
/// <summary>
/// Next block length, or an invalid value when <see cref="IsFinalPlaceholder"/> is true.
/// </summary>
public int Length { get; }
/// <summary>
/// Returns true if the command was generated by <see cref="BlockSwitchBuilder.AddFinalBlock"/>.
/// </summary>
public bool IsFinalPlaceholder => Length == FinalCommandLengthPlaceholder;
public BlockSwitchCommand(byte type, int length){
BlockLengthCode.CheckBounds(length);
this.Type = type;
this.Length = length;
}
internal BlockSwitchCommand(byte type){
this.Type = type;
this.Length = FinalCommandLengthPlaceholder;
}
// Object
public override bool Equals(object obj){
return obj is BlockSwitchCommand command &&
Type == command.Type &&
Length == command.Length;
}
public override int GetHashCode(){
return HashCode.Combine(Type, Length);
}
public override string ToString(){
return "Type = " + Type + ", Length = " + Length;
}
// Context
public sealed class Context{
public BlockTypeInfo Info { get; }
public BlockTypeTracker Tracker { get; }
public Context(BlockTypeInfo info, BlockTypeTracker tracker){
this.Info = info;
this.Tracker = tracker;
}
}
// Serialization
public static readonly BitDeserializer<BlockSwitchCommand, Context> Deserialize = MarkedBitDeserializer.Title<BlockSwitchCommand, Context>(
"Block Switch Command",
(reader, context) => {
var info = context.Info;
var typeCode = reader.ReadValue(info.TypeCodeTree!.Root, "BTYPE (code)");
byte typeValue = reader.MarkValue("BTYPE (value)", () => context.Tracker.NextType(typeCode));
var lengthCode = reader.ReadValue(info.LengthCodeTree!.Root, "BLEN (code)");
int lengthValue = reader.ReadValue(BlockLengthCode.Deserialize, lengthCode, "BLEN (value)");
return new BlockSwitchCommand(typeValue, lengthValue);
}
);
public static readonly BitSerializer<BlockSwitchCommand, Context> Serialize = (writer, obj, context) => {
var info = context.Info;
var typeCodes = context.Tracker.FindCodes(obj.Type);
writer.WriteBits(info.TypeCodeTree!.FindShortest(typeCodes, (code, available) => available.Contains(code)).Value);
int lengthValue = obj.Length;
var lengthEntry = info.LengthCodeTree!.FindShortest(lengthValue, (code, value) => code.CanEncodeValue(value));
writer.WriteBits(lengthEntry.Value);
BlockLengthCode.Serialize(writer, lengthValue, lengthEntry.Key);
};
}
}