diff options
author | drh <drh@noemail.net> | 2014-07-24 16:23:51 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2014-07-24 16:23:51 +0000 |
commit | 35c3d8cc75623d1fe890c8aaaaabb174e5de8d23 (patch) | |
tree | 2e2cfdc5e4f43a0595f60d7b92f546a88d13366e /src/util.c | |
parent | f257b4c61332fc7d64ad870e912338d0f31ef027 (diff) | |
parent | ba5b09319e2f79707bcc55a84a5f059ea0949334 (diff) | |
download | sqlite-35c3d8cc75623d1fe890c8aaaaabb174e5de8d23.tar.gz sqlite-35c3d8cc75623d1fe890c8aaaaabb174e5de8d23.zip |
Merge recent trunk changes into the sessions branch.
FossilOrigin-Name: a9db017eabdefafcda87c497e8bafa07002ac0fe
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/src/util.c b/src/util.c index 4fe07a862..619af7f75 100644 --- a/src/util.c +++ b/src/util.c @@ -475,9 +475,9 @@ static int compare2pow63(const char *zNum, int incr){ return c; } - /* -** Convert zNum to a 64-bit signed integer. +** Convert zNum to a 64-bit signed integer. zNum must be decimal. This +** routine does *not* accept hexadecimal notation. ** ** If the zNum value is representable as a 64-bit twos-complement ** integer, then write that value into *pNum and return 0. @@ -566,9 +566,43 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ } /* +** Transform a UTF-8 integer literal, in either decimal or hexadecimal, +** into a 64-bit signed integer. This routine accepts hexadecimal literals, +** whereas sqlite3Atoi64() does not. +** +** Returns: +** +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Integer too large for a 64-bit signed integer or is malformed +** 2 Special case of 9223372036854775808 +*/ +int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + && sqlite3Isxdigit(z[2]) + ){ + u64 u = 0; + int i, k; + for(i=2; z[i]=='0'; i++){} + for(k=i; sqlite3Isxdigit(z[k]); k++){ + u = u*16 + sqlite3HexToInt(z[k]); + } + memcpy(pOut, &u, 8); + return (z[k]==0 && k-i<=16) ? 0 : 1; + }else +#endif /* SQLITE_OMIT_HEX_INTEGER */ + { + return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); + } +} + +/* ** If zNum represents an integer that will fit in 32-bits, then set ** *pValue to that integer and return true. Otherwise return false. ** +** This routine accepts both decimal and hexadecimal notation for integers. +** ** Any non-numeric characters that following zNum are ignored. ** This is different from sqlite3Atoi64() which requires the ** input number to be zero-terminated. @@ -583,7 +617,25 @@ int sqlite3GetInt32(const char *zNum, int *pValue){ }else if( zNum[0]=='+' ){ zNum++; } - while( zNum[0]=='0' ) zNum++; +#ifndef SQLITE_OMIT_HEX_INTEGER + else if( zNum[0]=='0' + && (zNum[1]=='x' || zNum[1]=='X') + && sqlite3Isxdigit(zNum[2]) + ){ + u32 u = 0; + zNum += 2; + while( zNum[0]=='0' ) zNum++; + for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ + u = u*16 + sqlite3HexToInt(zNum[i]); + } + if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ + memcpy(pValue, &u, 4); + return 1; + }else{ + return 0; + } + } +#endif for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ v = v*10 + c; } |