User:Shimmy/Variable-length quantity: Difference between revisions

From Rosetta Code
Content added Content deleted
(Created page with "<lang csharp>namespace Vlq { using System; using System.Collections.Generic; using System.Linq; public static class VarLenQuantity { public static ulong ToVlq(u...")
 
No edit summary
Line 2:
{
using System;
using System.Collections.GenericIO;
using System.Linq;
 
public static class VarLenQuantityVariableLengthQuantity
{
/// <summary>
public static ulong ToVlq(ulong integer)
/// Reads a 7-bit encoded variable-length quantity from binary and return it as integer.
/// </summary>
/// <returns></returns>
public uint ReadVariableLengthQuantity(BinaryReader reader)
{
var arrayindex = new byte[8]0;
varuint buffer = ToVlqCollection(integer)0;
byte current;
.SkipWhile(b => b == 0)
.Reverse()do
.ToArray();{
Array.Copy if (buffer,index++ array,== buffer.Length8);
throw new FormatException("Could not read variable-length quantity from provided stream.");
return BitConverter.ToUInt64(array, 0);
 
}
buffer <<= 7;
 
current = reader.ReadByte();
buffer |= (current & 0x7FU);
} while ((current & 0x80) != 0);
 
return buffer;
public static ulong FromVlq(ulong integer)
{
var collection = BitConverter.GetBytes(integer).Reverse();
return FromVlqCollection(collection);
}
 
/// <summary>
public static IEnumerable<byte> ToVlqCollection(ulong integer)
/// Writes the specified integer as a 7-bit encoded variable-length quantity.
/// </summary>
/// <param name="integer"></param>
public void WriteVariableLengthQuantity(BinaryWriter writer, ulong integer)
{
if (integer > Math.Pow(2, 56))
throw new OverflowException("Integer exceeds max value.");
 
var index = 73;
var significantBitReached = false;
var mask = 0x7fUL << (index * 7);
Line 41 ⟶ 50:
if (index > 0)
buffer |= 0x80;
yield return writer.Write((byte)buffer);
}
mask >>= 7;
index--;
}
}
 
if (!significantBitReached && index < 0)
 
writer.Write(new byte());
public static ulong FromVlqCollection(IEnumerable<byte> vlq)
{
ulong integer = 0;
var significantBitReached = false;
 
using (var enumerator = vlq.GetEnumerator())
{
int index = 0;
while (enumerator.MoveNext())
{
var buffer = enumerator.Current;
if (buffer > 0 || significantBitReached)
{
significantBitReached = true;
integer <<= 7;
integer |= (buffer & 0x7fUL);
}
 
if (++index == 8 || (significantBitReached && (buffer & 0x80) != 0x80))
break;
}
}
return integer;
}
 
public static void Main()
{
var integers = new ulong[] { 0x7fUL << 7 * 7, 0x80, 0x2000, 0x3FFF, 0x4000, 0x200000, 0x1fffff };
 
foreach (var original in integers)
{
Console.WriteLine("Original: 0x{0:X}", original);
 
//collection
var seq = ToVlqCollection(original);
Console.WriteLine("Sequence: 0x{0}", seq.Select(b => b.ToString("X2")).Aggregate(string.Concat));
 
var decoded = FromVlqCollection(seq);
Console.WriteLine("Decoded: 0x{0:X}", decoded);
 
//ints
var encoded = ToVlq(original);
Console.WriteLine("Encoded: 0x{0:X}", encoded);
 
decoded = FromVlq(encoded);
Console.WriteLine("Decoded: 0x{0:X}", decoded);
 
Console.WriteLine();
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
}</lang>
}</lang>output<lang>Original: 0xFE000000000000
Sequence: 0xFF80808080808000
Decoded: 0xFE000000000000
Encoded: 0xFF80808080808000
Decoded: 0xFE000000000000
 
Original: 0x80
Sequence: 0x8100
Decoded: 0x80
Encoded: 0x8100
Decoded: 0x80
 
Original: 0x2000
Sequence: 0xC000
Decoded: 0x2000
Encoded: 0xC000
Decoded: 0x2000
 
Original: 0x3FFF
Sequence: 0xFF7F
Decoded: 0x3FFF
Encoded: 0xFF7F
Decoded: 0x3FFF
 
Original: 0x4000
Sequence: 0x818000
Decoded: 0x4000
Encoded: 0x818000
Decoded: 0x4000
 
Original: 0x200000
Sequence: 0x81808000
Decoded: 0x200000
Encoded: 0x81808000
Decoded: 0x200000
 
Original: 0x1FFFFF
Sequence: 0xFFFF7F
Decoded: 0x1FFFFF
Encoded: 0xFFFF7F
Decoded: 0x1FFFFF
 
Press any key to continue...</lang>

Revision as of 00:31, 30 October 2014

<lang csharp>namespace Vlq {

 using System;
 using System.IO;
 public static class VariableLengthQuantity
 {
   /// <summary>
   /// Reads a 7-bit encoded variable-length quantity from binary and return it as integer.
   /// </summary>
   /// <returns></returns>
   public uint ReadVariableLengthQuantity(BinaryReader reader)
   {
     var index = 0;
     uint buffer = 0;
     byte current;
     do
     {
       if (index++ == 8)
         throw new FormatException("Could not read variable-length quantity from provided stream.");
       buffer <<= 7;
       current = reader.ReadByte();
       buffer |= (current & 0x7FU);
     } while ((current & 0x80) != 0);
     return buffer;
   }
   /// <summary>
   /// Writes the specified integer as a 7-bit encoded variable-length quantity.
   /// </summary>
   /// <param name="integer"></param>
   public void WriteVariableLengthQuantity(BinaryWriter writer, ulong integer)
   {
     if (integer > Math.Pow(2, 56))
       throw new OverflowException("Integer exceeds max value.");
     var index = 3;
     var significantBitReached = false;
     var mask = 0x7fUL << (index * 7);
     while (index >= 0)
     {
       var buffer = (mask & integer);
       if (buffer > 0 || significantBitReached)
       {
         significantBitReached = true;
         buffer >>= index * 7;
         if (index > 0)
           buffer |= 0x80;
         writer.Write((byte)buffer);
       }
       mask >>= 7;
       index--;
     }
     if (!significantBitReached && index < 0)
       writer.Write(new byte());
   }
 }

}</lang>