aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/util.c293
1 files changed, 250 insertions, 43 deletions
diff --git a/src/util.c b/src/util.c
index 1aa375bdf..46dc5cb53 100644
--- a/src/util.c
+++ b/src/util.c
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.224 2008/04/28 17:41:31 shane Exp $
+** $Id: util.c,v 1.225 2008/05/01 02:47:04 shane Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@@ -533,41 +533,158 @@ int sqlite3PutVarint32(unsigned char *p, u32 v){
** Return the number of bytes read. The value is stored in *v.
*/
int sqlite3GetVarint(const unsigned char *p, u64 *v){
- u32 x;
- u64 x64;
- int n;
- unsigned char c;
- if( ((c = p[0]) & 0x80)==0 ){
- *v = c;
+ u32 a,b,s;
+
+ a = *p;
+ // a: p0 (unmasked)
+ if (!(a&0x80))
+ {
+ *v = a;
return 1;
}
- x = c & 0x7f;
- if( ((c = p[1]) & 0x80)==0 ){
- *v = (x<<7) | c;
+
+ p++;
+ b = *p;
+ // b: p1 (unmasked)
+ if (!(b&0x80))
+ {
+ a &= 0x7f;
+ a = a<<7;
+ a |= b;
+ *v = a;
return 2;
}
- x = (x<<7) | (c&0x7f);
- if( ((c = p[2]) & 0x80)==0 ){
- *v = (x<<7) | c;
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p0<<14 | p2 (unmasked)
+ if (!(a&0x80))
+ {
+ a &= (0x7f<<14)|(0x7f);
+ b &= 0x7f;
+ b = b<<7;
+ a |= b;
+ *v = a;
return 3;
}
- x = (x<<7) | (c&0x7f);
- if( ((c = p[3]) & 0x80)==0 ){
- *v = (x<<7) | c;
+
+ // CSE1 from below
+ a &= (0x7f<<14)|(0x7f);
+ p++;
+ b = b<<14;
+ b |= *p;
+ // b: p1<<14 | p3 (unmasked)
+ if (!(b&0x80))
+ {
+ b &= (0x7f<<14)|(0x7f);
+ // moved CSE1 up
+ // a &= (0x7f<<14)|(0x7f);
+ a = a<<7;
+ a |= b;
+ *v = a;
return 4;
}
- x64 = (x<<7) | (c&0x7f);
- n = 4;
- do{
- c = p[n++];
- if( n==9 ){
- x64 = (x64<<8) | c;
- break;
- }
- x64 = (x64<<7) | (c&0x7f);
- }while( (c & 0x80)!=0 );
- *v = x64;
- return n;
+
+ // a: p0<<14 | p2 (masked)
+ // b: p1<<14 | p3 (unmasked)
+ // 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked)
+ // moved CSE1 up
+ // a &= (0x7f<<14)|(0x7f);
+ b &= (0x7f<<14)|(0x7f);
+ s = a;
+ // s: p0<<14 | p2 (masked)
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p0<<28 | p2<<14 | p4 (unmasked)
+ if (!(a&0x80))
+ {
+ // we can skip these cause they were (effectively) done above in calc'ing s
+ // a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ // b &= (0x7f<<14)|(0x7f);
+ b = b<<7;
+ a |= b;
+ s = s>>18;
+ *v = ((u64)s)<<32 | a;
+ return 5;
+ }
+
+ // 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked)
+ s = s<<7;
+ s |= b;
+ // s: p0<<21 | p1<<14 | p2<<7 | p3 (masked)
+
+ p++;
+ b = b<<14;
+ b |= *p;
+ // b: p1<<28 | p3<<14 | p5 (unmasked)
+ if (!(b&0x80))
+ {
+ // we can skip this cause it was (effectively) done above in calc'ing s
+ // b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a &= (0x7f<<14)|(0x7f);
+ a = a<<7;
+ a |= b;
+ s = s>>18;
+ *v = ((u64)s)<<32 | a;
+ return 6;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p2<<28 | p4<<14 | p6 (unmasked)
+ if (!(a&0x80))
+ {
+ a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x7f<<14)|(0x7f);
+ b = b<<7;
+ a |= b;
+ s = s>>11;
+ *v = ((u64)s)<<32 | a;
+ return 7;
+ }
+
+ // CSE2 from below
+ a &= (0x7f<<14)|(0x7f);
+ p++;
+ b = b<<14;
+ b |= *p;
+ // b: p3<<28 | p5<<14 | p7 (unmasked)
+ if (!(b&0x80))
+ {
+ b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ // moved CSE2 up
+ // a &= (0x7f<<14)|(0x7f);
+ a = a<<7;
+ a |= b;
+ s = s>>4;
+ *v = ((u64)s)<<32 | a;
+ return 8;
+ }
+
+ p++;
+ a = a<<15;
+ a |= *p;
+ // a: p4<<29 | p6<<15 | p8 (unmasked)
+
+ // moved CSE2 up
+ // a &= (0x7f<<29)|(0x7f<<15)|(0xff);
+ b &= (0x7f<<14)|(0x7f);
+ b = b<<8;
+ a |= b;
+
+ s = s<<4;
+ b = p[-4];
+ b &= 0x7f;
+ b = b>>3;
+ s |= b;
+
+ *v = ((u64)s)<<32 | a;
+
+ return 9;
}
/*
@@ -578,27 +695,117 @@ int sqlite3GetVarint(const unsigned char *p, u64 *v){
** this function assumes the single-byte case has already been handled.
*/
int sqlite3GetVarint32(const unsigned char *p, u32 *v){
- u32 x;
- int n;
- unsigned char c;
+ u32 a,b;
+
+ a = *p;
+ // a: p0 (unmasked)
#ifndef getVarint32
- if( ((signed char*)p)[0]>=0 ){
- *v = p[0];
+ if (!(a&0x80))
+ {
+ *v = a;
return 1;
}
#endif
- x = p[0] & 0x7f;
- if( ((signed char*)p)[1]>=0 ){
- *v = (x<<7) | p[1];
+
+ p++;
+ b = *p;
+ // b: p1 (unmasked)
+ if (!(b&0x80))
+ {
+ a &= 0x7f;
+ a = a<<7;
+ *v = a | b;
return 2;
}
- x = (x<<7) | (p[1] & 0x7f);
- n = 2;
- do{
- x = (x<<7) | ((c = p[n++])&0x7f);
- }while( (c & 0x80)!=0 && n<9 );
- *v = x;
- return n;
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p0<<14 | p2 (unmasked)
+ if (!(a&0x80))
+ {
+ a &= (0x7f<<14)|(0x7f);
+ b &= 0x7f;
+ b = b<<7;
+ *v = a | b;
+ return 3;
+ }
+
+ p++;
+ b = b<<14;
+ b |= *p;
+ // b: p1<<14 | p3 (unmasked)
+ if (!(b&0x80))
+ {
+ b &= (0x7f<<14)|(0x7f);
+ a &= (0x7f<<14)|(0x7f);
+ a = a<<7;
+ *v = a | b;
+ return 4;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p0<<28 | p2<<14 | p4 (unmasked)
+ if (!(a&0x80))
+ {
+ a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b = b<<7;
+ *v = a | b;
+ return 5;
+ }
+
+ p++;
+ b = b<<14;
+ b |= *p;
+ // b: p1<<28 | p3<<14 | p5 (unmasked)
+ if (!(b&0x80))
+ {
+ b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a = a<<7;
+ *v = a | b;
+ return 6;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p2<<28 | p4<<14 | p6 (unmasked)
+ if (!(a&0x80))
+ {
+ a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b = b<<7;
+ *v = a | b;
+ return 7;
+ }
+
+ p++;
+ b = b<<14;
+ b |= *p;
+ // b: p3<<28 | p5<<14 | p7 (unmasked)
+ if (!(b&0x80))
+ {
+ b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ a = a<<7;
+ *v = a | b;
+ return 8;
+ }
+
+ p++;
+ a = a<<14;
+ a |= *p;
+ // a: p4<<28 | p6<<14 | p8 (unmasked)
+
+ a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+ b = b<<7;
+ *v = a | b;
+ return 9;
}
/*