| |
| /* |
| ** 2012-02-08 |
| ** |
| ** The author disclaims copyright to this source code. In place of |
| ** a legal notice, here is a blessing: |
| ** |
| ** May you do good and not evil. |
| ** May you find forgiveness for yourself and forgive others. |
| ** May you share freely, never taking more than you give. |
| ** |
| ************************************************************************* |
| ** |
| ** SQLite4-compatible varint implementation. |
| */ |
| #include "lsmInt.h" |
| |
| /************************************************************************* |
| ** The following is a copy of the varint.c module from SQLite 4. |
| */ |
| |
| /* |
| ** Decode the varint in z[]. Write the integer value into *pResult and |
| ** return the number of bytes in the varint. |
| */ |
| static int lsmSqlite4GetVarint64(const unsigned char *z, u64 *pResult){ |
| unsigned int x; |
| if( z[0]<=240 ){ |
| *pResult = z[0]; |
| return 1; |
| } |
| if( z[0]<=248 ){ |
| *pResult = (z[0]-241)*256 + z[1] + 240; |
| return 2; |
| } |
| if( z[0]==249 ){ |
| *pResult = 2288 + 256*z[1] + z[2]; |
| return 3; |
| } |
| if( z[0]==250 ){ |
| *pResult = (z[1]<<16) + (z[2]<<8) + z[3]; |
| return 4; |
| } |
| x = (z[1]<<24) + (z[2]<<16) + (z[3]<<8) + z[4]; |
| if( z[0]==251 ){ |
| *pResult = x; |
| return 5; |
| } |
| if( z[0]==252 ){ |
| *pResult = (((u64)x)<<8) + z[5]; |
| return 6; |
| } |
| if( z[0]==253 ){ |
| *pResult = (((u64)x)<<16) + (z[5]<<8) + z[6]; |
| return 7; |
| } |
| if( z[0]==254 ){ |
| *pResult = (((u64)x)<<24) + (z[5]<<16) + (z[6]<<8) + z[7]; |
| return 8; |
| } |
| *pResult = (((u64)x)<<32) + |
| (0xffffffff & ((z[5]<<24) + (z[6]<<16) + (z[7]<<8) + z[8])); |
| return 9; |
| } |
| |
| /* |
| ** Write a 32-bit unsigned integer as 4 big-endian bytes. |
| */ |
| static void lsmVarintWrite32(unsigned char *z, unsigned int y){ |
| z[0] = (unsigned char)(y>>24); |
| z[1] = (unsigned char)(y>>16); |
| z[2] = (unsigned char)(y>>8); |
| z[3] = (unsigned char)(y); |
| } |
| |
| /* |
| ** Write a varint into z[]. The buffer z[] must be at least 9 characters |
| ** long to accommodate the largest possible varint. Return the number of |
| ** bytes of z[] used. |
| */ |
| static int lsmSqlite4PutVarint64(unsigned char *z, u64 x){ |
| unsigned int w, y; |
| if( x<=240 ){ |
| z[0] = (unsigned char)x; |
| return 1; |
| } |
| if( x<=2287 ){ |
| y = (unsigned int)(x - 240); |
| z[0] = (unsigned char)(y/256 + 241); |
| z[1] = (unsigned char)(y%256); |
| return 2; |
| } |
| if( x<=67823 ){ |
| y = (unsigned int)(x - 2288); |
| z[0] = 249; |
| z[1] = (unsigned char)(y/256); |
| z[2] = (unsigned char)(y%256); |
| return 3; |
| } |
| y = (unsigned int)x; |
| w = (unsigned int)(x>>32); |
| if( w==0 ){ |
| if( y<=16777215 ){ |
| z[0] = 250; |
| z[1] = (unsigned char)(y>>16); |
| z[2] = (unsigned char)(y>>8); |
| z[3] = (unsigned char)(y); |
| return 4; |
| } |
| z[0] = 251; |
| lsmVarintWrite32(z+1, y); |
| return 5; |
| } |
| if( w<=255 ){ |
| z[0] = 252; |
| z[1] = (unsigned char)w; |
| lsmVarintWrite32(z+2, y); |
| return 6; |
| } |
| if( w<=32767 ){ |
| z[0] = 253; |
| z[1] = (unsigned char)(w>>8); |
| z[2] = (unsigned char)w; |
| lsmVarintWrite32(z+3, y); |
| return 7; |
| } |
| if( w<=16777215 ){ |
| z[0] = 254; |
| z[1] = (unsigned char)(w>>16); |
| z[2] = (unsigned char)(w>>8); |
| z[3] = (unsigned char)w; |
| lsmVarintWrite32(z+4, y); |
| return 8; |
| } |
| z[0] = 255; |
| lsmVarintWrite32(z+1, w); |
| lsmVarintWrite32(z+5, y); |
| return 9; |
| } |
| |
| /* |
| ** End of SQLite 4 code. |
| *************************************************************************/ |
| |
| int lsmVarintPut64(u8 *aData, i64 iVal){ |
| return lsmSqlite4PutVarint64(aData, (u64)iVal); |
| } |
| |
| int lsmVarintGet64(const u8 *aData, i64 *piVal){ |
| return lsmSqlite4GetVarint64(aData, (u64 *)piVal); |
| } |
| |
| int lsmVarintPut32(u8 *aData, int iVal){ |
| return lsmSqlite4PutVarint64(aData, (u64)iVal); |
| } |
| |
| int lsmVarintGet32(u8 *z, int *piVal){ |
| u64 i; |
| int ret; |
| |
| if( z[0]<=240 ){ |
| *piVal = z[0]; |
| return 1; |
| } |
| if( z[0]<=248 ){ |
| *piVal = (z[0]-241)*256 + z[1] + 240; |
| return 2; |
| } |
| if( z[0]==249 ){ |
| *piVal = 2288 + 256*z[1] + z[2]; |
| return 3; |
| } |
| if( z[0]==250 ){ |
| *piVal = (z[1]<<16) + (z[2]<<8) + z[3]; |
| return 4; |
| } |
| |
| ret = lsmSqlite4GetVarint64(z, &i); |
| *piVal = (int)i; |
| return ret; |
| } |
| |
| int lsmVarintLen32(int n){ |
| u8 aData[9]; |
| return lsmVarintPut32(aData, n); |
| } |
| |
| /* |
| ** The argument is the first byte of a varint. This function returns the |
| ** total number of bytes in the entire varint (including the first byte). |
| */ |
| int lsmVarintSize(u8 c){ |
| if( c<241 ) return 1; |
| if( c<249 ) return 2; |
| return (int)(c - 246); |
| } |