1 /* 2 ** A utility program to translate SQLite varints into decimal and decimal 3 ** integers into varints. 4 */ 5 #include <stdio.h> 6 #include <string.h> 7 #include <stdlib.h> 8 9 #if defined(_MSC_VER) || defined(__BORLANDC__) 10 typedef __int64 i64; 11 typedef unsigned __int64 u64; 12 #else 13 typedef long long int i64; 14 typedef unsigned long long int u64; 15 #endif 16 17 static int hexValue(char c){ 18 if( c>='0' && c<='9' ) return c - '0'; 19 if( c>='a' && c<='f' ) return c - 'a' + 10; 20 if( c>='A' && c<='F' ) return c - 'A' + 10; 21 return -1; 22 } 23 24 static char toHex(unsigned char c){ 25 return "0123456789abcdef"[c&0xf]; 26 } 27 28 static int putVarint(unsigned char *p, u64 v){ 29 int i, j, n; 30 unsigned char buf[10]; 31 if( v & (((u64)0xff000000)<<32) ){ 32 p[8] = (unsigned char)v; 33 v >>= 8; 34 for(i=7; i>=0; i--){ 35 p[i] = (unsigned char)((v & 0x7f) | 0x80); 36 v >>= 7; 37 } 38 return 9; 39 } 40 n = 0; 41 do{ 42 buf[n++] = (unsigned char)((v & 0x7f) | 0x80); 43 v >>= 7; 44 }while( v!=0 ); 45 buf[0] &= 0x7f; 46 for(i=0, j=n-1; j>=0; j--, i++){ 47 p[i] = buf[j]; 48 } 49 return n; 50 } 51 52 53 int main(int argc, char **argv){ 54 int i; 55 u64 x; 56 u64 uX = 0; 57 i64 iX; 58 int n; 59 unsigned char zHex[20]; 60 61 if( argc==1 ){ 62 fprintf(stderr, 63 "Usage:\n" 64 " %s HH HH HH ... Convert varint to decimal\n" 65 " %s DDDDD Convert decimal to varint\n" 66 " Add '+' or '-' before DDDDD to disambiguate.\n", 67 argv[0], argv[0]); 68 exit(1); 69 } 70 if( argc>2 71 || (strlen(argv[1])==2 && hexValue(argv[1][0])>=0 && hexValue(argv[1][1])>=0) 72 ){ 73 /* Hex to decimal */ 74 for(i=1; i<argc && i<9; i++){ 75 if( strlen(argv[i])!=2 ){ 76 fprintf(stderr, "Not a hex byte: %s\n", argv[i]); 77 exit(1); 78 } 79 x = (hexValue(argv[i][0])<<4) + hexValue(argv[i][1]); 80 uX = (uX<<7) + (x&0x7f); 81 if( (x&0x80)==0 ) break; 82 } 83 if( i==9 && i<argc ){ 84 if( strlen(argv[i])!=2 ){ 85 fprintf(stderr, "Not a hex byte: %s\n", argv[i]); 86 exit(1); 87 } 88 x = (hexValue(argv[i][0])<<4) + hexValue(argv[i][1]); 89 uX = (uX<<8) + x; 90 } 91 i++; 92 if( i<argc ){ 93 fprintf(stderr, "Extra arguments: %s...\n", argv[i]); 94 exit(1); 95 } 96 }else{ 97 char *z = argv[1]; 98 int sign = 1; 99 if( z[0]=='+' ) z++; 100 else if( z[0]=='-' ){ z++; sign = -1; } 101 uX = 0; 102 while( z[0] ){ 103 if( z[0]<'0' || z[0]>'9' ){ 104 fprintf(stderr, "Not a decimal number: %s", argv[1]); 105 exit(1); 106 } 107 uX = uX*10 + z[0] - '0'; 108 z++; 109 } 110 if( sign<0 ){ 111 memcpy(&iX, &uX, 8); 112 iX = -iX; 113 memcpy(&uX, &iX, 8); 114 } 115 } 116 n = putVarint(zHex, uX); 117 printf("%lld =", (i64)uX); 118 for(i=0; i<n; i++){ 119 printf(" %c%c", toHex(zHex[i]>>4), toHex(zHex[i]&0x0f)); 120 } 121 printf("\n"); 122 return 0; 123 } 124