/// <summary> /// Constructs an <see cref="InsertCopyLengthCode"/> that can encode the stored lengths, and can therefore be used as context in the <see cref="Serialize"/>. /// </summary> public InsertCopyLengthCode MakeCode(ImplicitDistanceCodeZero implicitDCZ) { int insertCode = CollectionHelper.FindRangeIndex(InsertCodeRanges, InsertLength); int copyCode = CollectionHelper.FindRangeIndex(CopyCodeRanges, CopyLength); return(new InsertCopyLengthCode(insertCode, copyCode, implicitDCZ)); }
public static bool Decide(this ImplicitDistanceCodeZero strategy, int insertCode, int copyCode) { return(strategy switch { ImplicitDistanceCodeZero.Disable => false, ImplicitDistanceCodeZero.PreferEnabled => insertCode <= 7 && copyCode <= 15, ImplicitDistanceCodeZero.ForceEnabled when insertCode > 7 => throw new ArgumentOutOfRangeException(nameof(insertCode), "Insert code must be in the range [0; 7] when using implied distance code zero."), ImplicitDistanceCodeZero.ForceEnabled when copyCode > 15 => throw new ArgumentOutOfRangeException(nameof(copyCode), "Copy code must be in the range [0; 15] when using implied distance code zero."), ImplicitDistanceCodeZero.ForceEnabled => true, _ => throw new InvalidOperationException("Invalid implicit distance code zero strategy: " + strategy), });
/// <summary> /// Initializes the code with the concrete insert and copy codes, and the flag which determines whether to use an implied distance code zero. /// </summary> public InsertCopyLengthCode(int insertCode, int copyCode, ImplicitDistanceCodeZero implicitDCZ) { if (insertCode < 0 || insertCode > 23) { throw new ArgumentOutOfRangeException(nameof(insertCode), "Insert code must be in the range [0; 23]."); } if (copyCode < 0 || copyCode > 23) { throw new ArgumentOutOfRangeException(nameof(copyCode), "Copy code must be in the range [0; 23]."); } bool useDistanceCodeZero = implicitDCZ.Decide(insertCode, copyCode); int cell = DetermineCellIndex(insertCode, copyCode, useDistanceCodeZero); this.CompactedCode = (64 * cell) + ((insertCode & 0b111) << 3) | (copyCode & 0b111); this.InsertCode = insertCode; this.CopyCode = copyCode; this.UseDistanceCodeZero = useDistanceCodeZero; }