Skip to content

Commit

Permalink
v4.0.0 - Adding support for ILIntSigned encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
monoman committed Aug 11, 2021
1 parent f644b50 commit c441b2f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ public class UlongExtensionsTests
[TestCase(18446744073709551615, ExpectedResult = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 7 })]
public byte[] AsILIntToByteArray(ulong value) => value.AsILInt();

[TestCase(0UL, ExpectedResult = 0L)]
[TestCase(2UL, ExpectedResult = 1L)]
[TestCase(0xFEUL, ExpectedResult = 127L)]
[TestCase(1UL, ExpectedResult = -1L)]
[TestCase(3UL, ExpectedResult = -2L)]
[TestCase(0xFFUL, ExpectedResult = -128L)]
public long AsSignedILInt(ulong value) => value.AsSignedILInt();

[TestCase(0L, ExpectedResult = 0UL)]
[TestCase(1L, ExpectedResult = 2UL)]
[TestCase(127L, ExpectedResult = 0xFEUL)]
[TestCase(-1L, ExpectedResult = 1UL)]
[TestCase(-2L, ExpectedResult = 3UL)]
[TestCase(-128L, ExpectedResult = 0xFFUL)]
public ulong AsUnsignedILInt(long value) => value.AsUnsignedILInt();

[TestCase((ulong)0, ExpectedResult = 1)]
[TestCase((ulong)ILIntHelpers.ILINT_BASE - 1, ExpectedResult = 1)]
[TestCase((ulong)ILIntHelpers.ILINT_BASE, ExpectedResult = 2)]
Expand Down
3 changes: 2 additions & 1 deletion InterlockLedger.Tags.ILInt/Extensions/ByteArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public static class ByteArrayExtensions
/// <summary>Decode ILInt from buffer bytes.</summary>
/// <param name="buffer">The buffer.</param>
/// <returns>Decoded ILInt value.</returns>
public static ulong ILIntDecode(this byte[] buffer) => ILIntDecode(buffer.Required(nameof(buffer)), 0, buffer.Length);
public static ulong ILIntDecode(this byte[] buffer)
=> buffer.Required(nameof(buffer)).ILIntDecode(0, buffer.Length);

/// <summary>Decode ILInt from a range of bytes from the buffer.</summary>
/// <param name="buffer">The buffer.</param>
Expand Down
36 changes: 36 additions & 0 deletions InterlockLedger.Tags.ILInt/Extensions/UlongExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,42 @@ public static class UlongExtensions
/// <returns>ILInt encoded value as an array of bytes.</returns>
public static byte[] AsILInt(this ulong value) => value.ILIntEncode();

/*
* To overcome this limitation, the ILInt standard defines a signed value transformation, called ILIntSignEnc and its reverse ILIntSignDec. The ideia behind this transformation is to encode the negative numbers in a way that minimize the number of msb set and thus use less space when encoded using ILInt.
ILIntSignEnc is defined as follows:
Convert the signed 64-bit value into an unsigned v value using two's complement;
If the sign bit (bit 63) of v is set, let e be not (v shl 1);
If the sign bit (bit 63) of v is not set, let e be (v shl 1);
Return e;
where shl is a bitwise shift lef operation and not is a bitwise not.
ILIntSignDec is defined as follows:
If bit 0 of e is set, let d be e shr 1;
If bit 1 of e is set, let d be not (e shr 1);
Let r be e converted to a 64-bit signed value using two's complement;
Return r;
where shr is an unsigned shift right operation and not is a bitwise not.
Using this encoding, the sign bit is moved to the least significant bit and the value is always converted to a small value if its absolute value is small.
*/

public static long AsSignedILInt(this ulong value) {
unchecked {
var d = (long)(value >> 1);
return (value & 1) == 0 ? d : ~d;
}
}

public static ulong AsUnsignedILInt(this long value) {
unchecked {
var s = (ulong)(value << 1);
return ((ulong)value & 0x8000000000000000ul) != 0 ? ~s : s;
}
}

/// <summary>Encode the value as an ILInt in the provided buffer, in the specified range.</summary>
/// <param name="value">The value.</param>
/// <param name="buffer">The buffer.</param>
Expand Down

0 comments on commit c441b2f

Please sign in to comment.