Advertisement
Guest User

Untitled

a guest
Sep 18th, 2013
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 1.60 KB | None | 0 0
  1. import std.traits;
  2. import std.stdio;
  3.  
  4. static
  5. ubyte[] packVarint(T)( T value )
  6. if( isIntegral!T && isUnsigned!T )
  7. out( arr )
  8. {
  9.     T d;
  10.     size_t size = d.unpackVarint( &arr[0] );
  11.    
  12.     writeln( "out contract, type=", typeid(T), " isUnsigned=", isUnsigned!T, " arg=", value, " result=", arr );
  13.     stdout.flush;
  14.    
  15.     assert( size == arr.length );
  16.     assert( d == value );
  17. }
  18. body
  19. {
  20.     writeln( "value inside of body: ", value, " type=", typeid( typeof(value) ) );
  21.     stdout.flush;
  22.    
  23.     ubyte[] res;
  24.    
  25.     immutable ubyte maximal = 0b_1000_0000;
  26.    
  27.     while( value >= maximal )
  28.     {
  29.         res ~= cast( ubyte )( value | maximal );
  30.         value >>= 7;
  31.     }
  32.    
  33.     import std.conv: to;
  34.     res ~= to!( ubyte )( value );
  35.    
  36.     return res;
  37. }
  38. unittest
  39. {
  40.     auto v = packVarint!ulong( 300 );
  41.     assert( v.length == 2 );
  42.     assert( v == [ 0b_10101100, 0b_00000010 ] );
  43. }
  44.  
  45. pure size_t unpackVarint( T )( out T result, inout ubyte* data )
  46. if( isIntegral!T && isUnsigned!T )
  47. {
  48.     size_t i;
  49.     size_t res; // big sized type used also for overflow checking
  50.    
  51.     do {
  52.         res |= ( data[i] & 0b_0111_1111 ) << 7 * i;
  53.         enforce( res <= T.max, "Varint is too big for type " ~ T.stringof );
  54.     } while( msbIsSet( &data[i++] ) );
  55.    
  56.     result = cast(T) res;
  57.    
  58.     return i;
  59. }
  60. unittest
  61. {
  62.     ubyte d[2] = [ 0b_10101100, 0b_00000010 ];
  63.     size_t result;
  64.    
  65.     assert( result.unpackVarint( &d[0] ) == d.length );
  66.     assert( result == 300 );
  67. }
  68.  
  69. void main()
  70. {
  71.     for( long i = -100; i < 100; i++ )
  72.         packVarint( i );
  73. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement