/// <summary> /// CopyToken Help derived bit masks are used by the Unpack CopyToken (section 2.4.1.3.19.2) /// and the Pack CopyToken (section 2.4.1.3.19.3) algorithms. CopyToken Help also derives the /// maximum length for a CopySequence (section 2.4.1.3.19) which is used by the Matching /// algorithm (section 2.4.1.3.19.4). /// The pseudocode uses the state variables described in State Variables (section 2.4.1.2): /// DecompressedCurrent and DecompressedChunkStart. /// </summary> internal static CopyTokenHelpResult CopyTokenHelp(long difference) { var result = new CopyTokenHelpResult(); // SET BitCount TO the smallest integer that is GREATER THAN OR EQUAL TO LOGARITHM base 2 // of difference result.BitCount = 0; while ((1 << result.BitCount) < difference) { result.BitCount += 1; } // The number of bits used to encode Length MUST be greater than or equal to four. The // number of bits used to encode Length MUST be less than or equal to 12 // SET BitCount TO the maximum of BitCount and 4 if (result.BitCount < 4) { result.BitCount = 4; } if (result.BitCount > 12) { throw new Exception(); } // SET LengthMask TO 0xFFFF RIGHT SHIFT BY BitCount result.LengthMask = (UInt16)(0xffff >> result.BitCount); // SET OffsetMask TO BITWISE NOT LengthMask result.OffsetMask = (UInt16)(~result.LengthMask); // SET MaximumLength TO (0xFFFF RIGHT SHIFT BY BitCount) PLUS 3 result.MaximumLength = (UInt16)((0xffff >> result.BitCount) + 3); return(result); }
// page 69 public static CopyTokenHelpResult CopyTokenHelp(int DecompressedCurrent, int DecompressedChunkStart) { var difference = DecompressedCurrent - DecompressedChunkStart; var result = new CopyTokenHelpResult(); result.BitCount = Math.Max((ushort)Math.Ceiling(Math.Log(difference, 2)), (ushort)4); result.LengthMask = (ushort)(0xFFFF >> result.BitCount); result.OffsetMask = (ushort)(~result.LengthMask); // bitwise not result.MaximumLength = (ushort)((0xFFFF >> result.BitCount) + 3); return(result); }