diff options
Diffstat (limited to 'lib/libsqlite3/tool/varint.c')
-rw-r--r-- | lib/libsqlite3/tool/varint.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/lib/libsqlite3/tool/varint.c b/lib/libsqlite3/tool/varint.c new file mode 100644 index 00000000000..f4a51118b4d --- /dev/null +++ b/lib/libsqlite3/tool/varint.c @@ -0,0 +1,123 @@ +/* +** A utility program to translate SQLite varints into decimal and decimal +** integers into varints. +*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#if defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 i64; + typedef unsigned __int64 u64; +#else + typedef long long int i64; + typedef unsigned long long int u64; +#endif + +static int hexValue(char c){ + if( c>='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +static char toHex(unsigned char c){ + return "0123456789abcdef"[c&0xf]; +} + +static int putVarint(unsigned char *p, u64 v){ + int i, j, n; + unsigned char buf[10]; + if( v & (((u64)0xff000000)<<32) ){ + p[8] = (unsigned char)v; + v >>= 8; + for(i=7; i>=0; i--){ + p[i] = (unsigned char)((v & 0x7f) | 0x80); + v >>= 7; + } + return 9; + } + n = 0; + do{ + buf[n++] = (unsigned char)((v & 0x7f) | 0x80); + v >>= 7; + }while( v!=0 ); + buf[0] &= 0x7f; + for(i=0, j=n-1; j>=0; j--, i++){ + p[i] = buf[j]; + } + return n; +} + + +int main(int argc, char **argv){ + int i; + u64 x; + u64 uX = 0; + i64 iX; + int n; + unsigned char zHex[20]; + + if( argc==1 ){ + fprintf(stderr, + "Usage:\n" + " %s HH HH HH ... Convert varint to decimal\n" + " %s DDDDD Convert decimal to varint\n" + " Add '+' or '-' before DDDDD to disambiguate.\n", + argv[0], argv[0]); + exit(1); + } + if( argc>2 + || (strlen(argv[1])==2 && hexValue(argv[1][0])>=0 && hexValue(argv[1][1])>=0) + ){ + /* Hex to decimal */ + for(i=1; i<argc && i<9; i++){ + if( strlen(argv[i])!=2 ){ + fprintf(stderr, "Not a hex byte: %s\n", argv[i]); + exit(1); + } + x = (hexValue(argv[i][0])<<4) + hexValue(argv[i][1]); + uX = (uX<<7) + (x&0x7f); + if( (x&0x80)==0 ) break; + } + if( i==9 && i<argc ){ + if( strlen(argv[i])!=2 ){ + fprintf(stderr, "Not a hex byte: %s\n", argv[i]); + exit(1); + } + x = (hexValue(argv[i][0])<<4) + hexValue(argv[i][1]); + uX = (uX<<8) + x; + } + i++; + if( i<argc ){ + fprintf(stderr, "Extra arguments: %s...\n", argv[i]); + exit(1); + } + }else{ + char *z = argv[1]; + int sign = 1; + if( z[0]=='+' ) z++; + else if( z[0]=='-' ){ z++; sign = -1; } + uX = 0; + while( z[0] ){ + if( z[0]<'0' || z[0]>'9' ){ + fprintf(stderr, "Not a decimal number: %s", argv[1]); + exit(1); + } + uX = uX*10 + z[0] - '0'; + z++; + } + if( sign<0 ){ + memcpy(&iX, &uX, 8); + iX = -iX; + memcpy(&uX, &iX, 8); + } + } + n = putVarint(zHex, uX); + printf("%lld =", (i64)uX); + for(i=0; i<n; i++){ + printf(" %c%c", toHex(zHex[i]>>4), toHex(zHex[i]&0x0f)); + } + printf("\n"); + return 0; +} |