| /* |
| ** 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; |
| } |