Advertisement
Guest User

Untitled

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