summaryrefslogtreecommitdiffstats
path: root/ext/lsm1/lsm_varint.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/lsm1/lsm_varint.c')
-rw-r--r--ext/lsm1/lsm_varint.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/ext/lsm1/lsm_varint.c b/ext/lsm1/lsm_varint.c
new file mode 100644
index 0000000..c550a64
--- /dev/null
+++ b/ext/lsm1/lsm_varint.c
@@ -0,0 +1,196 @@
+
+/*
+** 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);
+}