mirror of
https://github.com/chylex/Brotli-Builder.git
synced 2025-04-17 11:15:43 +02:00
Implement Brotli literal context mode serialization
This commit is contained in:
parent
87d65a8b6f
commit
3fe5a82239
91
BrotliLib/Brotli/Components/Utils/LiteralContextMode.cs
Normal file
91
BrotliLib/Brotli/Components/Utils/LiteralContextMode.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using BrotliLib.IO;
|
||||||
|
|
||||||
|
namespace BrotliLib.Brotli.Components.Utils{
|
||||||
|
/// <summary>
|
||||||
|
/// Lists functions for context modeling of literals.
|
||||||
|
/// https://tools.ietf.org/html/rfc7932#section-7.1
|
||||||
|
/// </summary>
|
||||||
|
public enum LiteralContextMode{
|
||||||
|
LSB6 = 0b00,
|
||||||
|
MSB6 = 0b01,
|
||||||
|
UTF8 = 0b10,
|
||||||
|
Signed = 0b11
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LiteralContextModes{
|
||||||
|
public static int DetermineContextID(this LiteralContextMode mode, byte mostRecentByte, byte secondRecentByte){
|
||||||
|
switch(mode){
|
||||||
|
case LiteralContextMode.LSB6: return mostRecentByte & 0x3F;
|
||||||
|
case LiteralContextMode.MSB6: return mostRecentByte >> 2;
|
||||||
|
case LiteralContextMode.UTF8: return LUT0[mostRecentByte] | LUT1[secondRecentByte];
|
||||||
|
case LiteralContextMode.Signed: return (LUT2[mostRecentByte] << 3) | LUT2[secondRecentByte];
|
||||||
|
default: throw new InvalidOperationException("Invalid literal context mode: "+mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly IBitSerializer<LiteralContextMode, NoContext> Serializer = new BitSerializer<LiteralContextMode, NoContext>(
|
||||||
|
fromBits: (reader, context) => (LiteralContextMode)reader.NextChunk(2),
|
||||||
|
toBits: (writer, obj, context) => writer.WriteChunk(2, (int)obj)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Magic
|
||||||
|
|
||||||
|
private static readonly byte[] LUT0 = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,
|
||||||
|
44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12,
|
||||||
|
12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48,
|
||||||
|
52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,
|
||||||
|
12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,
|
||||||
|
60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0,
|
||||||
|
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||||
|
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||||
|
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||||
|
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||||
|
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||||
|
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||||
|
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||||
|
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly byte[] LUT1 = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
|
||||||
|
1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly byte[] LUT2 = {
|
||||||
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ open System
|
|||||||
open BrotliLib.IO
|
open BrotliLib.IO
|
||||||
open BrotliLib.Brotli.Components
|
open BrotliLib.Brotli.Components
|
||||||
open BrotliLib.Brotli.Components.Header
|
open BrotliLib.Brotli.Components.Header
|
||||||
|
open BrotliLib.Brotli.Components.Utils
|
||||||
|
|
||||||
|
|
||||||
module Helper =
|
module Helper =
|
||||||
@ -101,3 +102,12 @@ module DistanceParameters =
|
|||||||
[<InlineData(4, 16)>]
|
[<InlineData(4, 16)>]
|
||||||
let ``constructing distance parameters with invalid value throws exception`` (pb: byte, db: byte) =
|
let ``constructing distance parameters with invalid value throws exception`` (pb: byte, db: byte) =
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(fun () -> DistanceParameters(pb, db) |> ignore)
|
Assert.Throws<ArgumentOutOfRangeException>(fun () -> DistanceParameters(pb, db) |> ignore)
|
||||||
|
|
||||||
|
|
||||||
|
module LiteralContextMode =
|
||||||
|
let values: obj array seq = Enum.GetValues(typeof<LiteralContextMode>) :?> (LiteralContextMode[]) |> Seq.map(fun value -> [| value |])
|
||||||
|
|
||||||
|
[<Theory>]
|
||||||
|
[<MemberData("values")>]
|
||||||
|
let ``converting to and from bits yields same object`` (mode: LiteralContextMode) =
|
||||||
|
Assert.Equal(mode, Helper.convert mode NoContext.Value LiteralContextModes.Serializer)
|
||||||
|
Loading…
Reference in New Issue
Block a user