xref: /sqlite-3.40.0/ext/misc/totype.c (revision 2b1c2aad)
15f8cdac6Sdrh /*
25f8cdac6Sdrh ** 2013-10-14
35f8cdac6Sdrh **
45f8cdac6Sdrh ** The author disclaims copyright to this source code.  In place of
55f8cdac6Sdrh ** a legal notice, here is a blessing:
65f8cdac6Sdrh **
75f8cdac6Sdrh **    May you do good and not evil.
85f8cdac6Sdrh **    May you find forgiveness for yourself and forgive others.
95f8cdac6Sdrh **    May you share freely, never taking more than you give.
105f8cdac6Sdrh **
115f8cdac6Sdrh ******************************************************************************
125f8cdac6Sdrh **
135f8cdac6Sdrh ** This SQLite extension implements functions tointeger(X) and toreal(X).
145f8cdac6Sdrh **
155f8cdac6Sdrh ** If X is an integer, real, or string value that can be
165f8cdac6Sdrh ** losslessly represented as an integer, then tointeger(X)
175f8cdac6Sdrh ** returns the corresponding integer value.
185f8cdac6Sdrh ** If X is an 8-byte BLOB then that blob is interpreted as
195f8cdac6Sdrh ** a signed two-compliment little-endian encoding of an integer
205f8cdac6Sdrh ** and tointeger(X) returns the corresponding integer value.
215f8cdac6Sdrh ** Otherwise tointeger(X) return NULL.
225f8cdac6Sdrh **
235f8cdac6Sdrh ** If X is an integer, real, or string value that can be
245f8cdac6Sdrh ** convert into a real number, preserving at least 15 digits
255f8cdac6Sdrh ** of precision, then toreal(X) returns the corresponding real value.
265f8cdac6Sdrh ** If X is an 8-byte BLOB then that blob is interpreted as
275f8cdac6Sdrh ** a 64-bit IEEE754 big-endian floating point value
285f8cdac6Sdrh ** and toreal(X) returns the corresponding real value.
295f8cdac6Sdrh ** Otherwise toreal(X) return NULL.
305f8cdac6Sdrh **
315f8cdac6Sdrh ** Note that tointeger(X) of an 8-byte BLOB assumes a little-endian
325f8cdac6Sdrh ** encoding whereas toreal(X) of an 8-byte BLOB assumes a big-endian
335f8cdac6Sdrh ** encoding.
345f8cdac6Sdrh */
355f8cdac6Sdrh #include "sqlite3ext.h"
365f8cdac6Sdrh SQLITE_EXTENSION_INIT1
375f8cdac6Sdrh #include <assert.h>
385f8cdac6Sdrh #include <string.h>
395f8cdac6Sdrh 
405f8cdac6Sdrh /*
415f8cdac6Sdrh ** Determine if this is running on a big-endian or little-endian
425f8cdac6Sdrh ** processor
435f8cdac6Sdrh */
445f8cdac6Sdrh #if defined(i386) || defined(__i386__) || defined(_M_IX86)\
455f8cdac6Sdrh                              || defined(__x86_64) || defined(__x86_64__)
460593516fSmistachkin # define TOTYPE_BIGENDIAN    0
470593516fSmistachkin # define TOTYPE_LITTLEENDIAN 1
485f8cdac6Sdrh #else
495f8cdac6Sdrh   const int totype_one = 1;
500593516fSmistachkin # define TOTYPE_BIGENDIAN    (*(char *)(&totype_one)==0)
510593516fSmistachkin # define TOTYPE_LITTLEENDIAN (*(char *)(&totype_one)==1)
525f8cdac6Sdrh #endif
535f8cdac6Sdrh 
545f8cdac6Sdrh /*
555f8cdac6Sdrh ** Constants for the largest and smallest possible 64-bit signed integers.
565f8cdac6Sdrh ** These macros are designed to work correctly on both 32-bit and 64-bit
575f8cdac6Sdrh ** compilers.
585f8cdac6Sdrh */
59bc863b50Smistachkin #ifndef LARGEST_INT64
605f8cdac6Sdrh # define LARGEST_INT64   (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
61bc863b50Smistachkin #endif
62bc863b50Smistachkin 
63bc863b50Smistachkin #ifndef SMALLEST_INT64
645f8cdac6Sdrh # define SMALLEST_INT64  (((sqlite3_int64)-1) - LARGEST_INT64)
65bc863b50Smistachkin #endif
665f8cdac6Sdrh 
675f8cdac6Sdrh /*
685f8cdac6Sdrh ** Return TRUE if character c is a whitespace character
695f8cdac6Sdrh */
totypeIsspace(unsigned char c)705f8cdac6Sdrh static int totypeIsspace(unsigned char c){
710593516fSmistachkin   return c==' ' || c=='\t' || c=='\n' || c=='\v' || c=='\f' || c=='\r';
725f8cdac6Sdrh }
735f8cdac6Sdrh 
745f8cdac6Sdrh /*
755f8cdac6Sdrh ** Return TRUE if character c is a digit
765f8cdac6Sdrh */
totypeIsdigit(unsigned char c)775f8cdac6Sdrh static int totypeIsdigit(unsigned char c){
785f8cdac6Sdrh   return c>='0' && c<='9';
795f8cdac6Sdrh }
805f8cdac6Sdrh 
815f8cdac6Sdrh /*
825f8cdac6Sdrh ** Compare the 19-character string zNum against the text representation
835f8cdac6Sdrh ** value 2^63:  9223372036854775808.  Return negative, zero, or positive
845f8cdac6Sdrh ** if zNum is less than, equal to, or greater than the string.
855f8cdac6Sdrh ** Note that zNum must contain exactly 19 characters.
865f8cdac6Sdrh **
875f8cdac6Sdrh ** Unlike memcmp() this routine is guaranteed to return the difference
885f8cdac6Sdrh ** in the values of the last digit if the only difference is in the
895f8cdac6Sdrh ** last digit.  So, for example,
905f8cdac6Sdrh **
910593516fSmistachkin **      totypeCompare2pow63("9223372036854775800")
925f8cdac6Sdrh **
935f8cdac6Sdrh ** will return -8.
945f8cdac6Sdrh */
totypeCompare2pow63(const char * zNum)955f8cdac6Sdrh static int totypeCompare2pow63(const char *zNum){
965f8cdac6Sdrh   int c = 0;
975f8cdac6Sdrh   int i;
985f8cdac6Sdrh                     /* 012345678901234567 */
995f8cdac6Sdrh   const char *pow63 = "922337203685477580";
1005f8cdac6Sdrh   for(i=0; c==0 && i<18; i++){
1015f8cdac6Sdrh     c = (zNum[i]-pow63[i])*10;
1025f8cdac6Sdrh   }
1035f8cdac6Sdrh   if( c==0 ){
1045f8cdac6Sdrh     c = zNum[18] - '8';
1055f8cdac6Sdrh   }
1065f8cdac6Sdrh   return c;
1075f8cdac6Sdrh }
1085f8cdac6Sdrh 
1095f8cdac6Sdrh /*
1105f8cdac6Sdrh ** Convert zNum to a 64-bit signed integer.
1115f8cdac6Sdrh **
1125f8cdac6Sdrh ** If the zNum value is representable as a 64-bit twos-complement
1135f8cdac6Sdrh ** integer, then write that value into *pNum and return 0.
1145f8cdac6Sdrh **
1155f8cdac6Sdrh ** If zNum is exactly 9223372036854665808, return 2.  This special
1165f8cdac6Sdrh ** case is broken out because while 9223372036854665808 cannot be a
1175f8cdac6Sdrh ** signed 64-bit integer, its negative -9223372036854665808 can be.
1185f8cdac6Sdrh **
1195f8cdac6Sdrh ** If zNum is too big for a 64-bit integer and is not
1205f8cdac6Sdrh ** 9223372036854665808  or if zNum contains any non-numeric text,
1215f8cdac6Sdrh ** then return 1.
1220593516fSmistachkin **
1230593516fSmistachkin ** The string is not necessarily zero-terminated.
1245f8cdac6Sdrh */
totypeAtoi64(const char * zNum,sqlite3_int64 * pNum,int length)1255f8cdac6Sdrh static int totypeAtoi64(const char *zNum, sqlite3_int64 *pNum, int length){
1265f8cdac6Sdrh   sqlite3_uint64 u = 0;
1275f8cdac6Sdrh   int neg = 0; /* assume positive */
1285f8cdac6Sdrh   int i;
1295f8cdac6Sdrh   int c = 0;
1305f8cdac6Sdrh   int nonNum = 0;
1315f8cdac6Sdrh   const char *zStart;
1325f8cdac6Sdrh   const char *zEnd = zNum + length;
1335f8cdac6Sdrh 
1345f8cdac6Sdrh   while( zNum<zEnd && totypeIsspace(*zNum) ) zNum++;
1355f8cdac6Sdrh   if( zNum<zEnd ){
1365f8cdac6Sdrh     if( *zNum=='-' ){
1375f8cdac6Sdrh       neg = 1;
1385f8cdac6Sdrh       zNum++;
1395f8cdac6Sdrh     }else if( *zNum=='+' ){
1405f8cdac6Sdrh       zNum++;
1415f8cdac6Sdrh     }
1425f8cdac6Sdrh   }
1435f8cdac6Sdrh   zStart = zNum;
1445f8cdac6Sdrh   while( zNum<zEnd && zNum[0]=='0' ){ zNum++; } /* Skip leading zeros. */
1455f8cdac6Sdrh   for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i++){
1465f8cdac6Sdrh     u = u*10 + c - '0';
1475f8cdac6Sdrh   }
1485f8cdac6Sdrh   if( u>LARGEST_INT64 ){
1495f8cdac6Sdrh     *pNum = SMALLEST_INT64;
1505f8cdac6Sdrh   }else if( neg ){
1515f8cdac6Sdrh     *pNum = -(sqlite3_int64)u;
1525f8cdac6Sdrh   }else{
1535f8cdac6Sdrh     *pNum = (sqlite3_int64)u;
1545f8cdac6Sdrh   }
1555f8cdac6Sdrh   if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19 || nonNum ){
1565f8cdac6Sdrh     /* zNum is empty or contains non-numeric text or is longer
1575f8cdac6Sdrh     ** than 19 digits (thus guaranteeing that it is too large) */
1585f8cdac6Sdrh     return 1;
1595f8cdac6Sdrh   }else if( i<19 ){
1605f8cdac6Sdrh     /* Less than 19 digits, so we know that it fits in 64 bits */
1615f8cdac6Sdrh     assert( u<=LARGEST_INT64 );
1625f8cdac6Sdrh     return 0;
1635f8cdac6Sdrh   }else{
1645f8cdac6Sdrh     /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
1655f8cdac6Sdrh     c = totypeCompare2pow63(zNum);
1665f8cdac6Sdrh     if( c<0 ){
1675f8cdac6Sdrh       /* zNum is less than 9223372036854775808 so it fits */
1685f8cdac6Sdrh       assert( u<=LARGEST_INT64 );
1695f8cdac6Sdrh       return 0;
1705f8cdac6Sdrh     }else if( c>0 ){
1715f8cdac6Sdrh       /* zNum is greater than 9223372036854775808 so it overflows */
1725f8cdac6Sdrh       return 1;
1735f8cdac6Sdrh     }else{
1745f8cdac6Sdrh       /* zNum is exactly 9223372036854775808.  Fits if negative.  The
1755f8cdac6Sdrh       ** special case 2 overflow if positive */
1765f8cdac6Sdrh       assert( u-1==LARGEST_INT64 );
1775f8cdac6Sdrh       assert( (*pNum)==SMALLEST_INT64 );
1785f8cdac6Sdrh       return neg ? 0 : 2;
1795f8cdac6Sdrh     }
1805f8cdac6Sdrh   }
1815f8cdac6Sdrh }
1820593516fSmistachkin 
1835f8cdac6Sdrh /*
1845f8cdac6Sdrh ** The string z[] is an text representation of a real number.
1855f8cdac6Sdrh ** Convert this string to a double and write it into *pResult.
1865f8cdac6Sdrh **
1870593516fSmistachkin ** The string is not necessarily zero-terminated.
1885f8cdac6Sdrh **
1895f8cdac6Sdrh ** Return TRUE if the result is a valid real number (or integer) and FALSE
1905f8cdac6Sdrh ** if the string is empty or contains extraneous text.  Valid numbers
1915f8cdac6Sdrh ** are in one of these formats:
1925f8cdac6Sdrh **
1935f8cdac6Sdrh **    [+-]digits[E[+-]digits]
1945f8cdac6Sdrh **    [+-]digits.[digits][E[+-]digits]
1955f8cdac6Sdrh **    [+-].digits[E[+-]digits]
1965f8cdac6Sdrh **
1975f8cdac6Sdrh ** Leading and trailing whitespace is ignored for the purpose of determining
1985f8cdac6Sdrh ** validity.
1995f8cdac6Sdrh **
2005f8cdac6Sdrh ** If some prefix of the input string is a valid number, this routine
2015f8cdac6Sdrh ** returns FALSE but it still converts the prefix and writes the result
2025f8cdac6Sdrh ** into *pResult.
2035f8cdac6Sdrh */
totypeAtoF(const char * z,double * pResult,int length)2045f8cdac6Sdrh static int totypeAtoF(const char *z, double *pResult, int length){
2055f8cdac6Sdrh   const char *zEnd = z + length;
2065f8cdac6Sdrh   /* sign * significand * (10 ^ (esign * exponent)) */
2075f8cdac6Sdrh   int sign = 1;    /* sign of significand */
2085f8cdac6Sdrh   sqlite3_int64 s = 0;       /* significand */
2095f8cdac6Sdrh   int d = 0;       /* adjust exponent for shifting decimal point */
2105f8cdac6Sdrh   int esign = 1;   /* sign of exponent */
2115f8cdac6Sdrh   int e = 0;       /* exponent */
2125f8cdac6Sdrh   int eValid = 1;  /* True exponent is either not used or is well-formed */
2135f8cdac6Sdrh   double result;
2145f8cdac6Sdrh   int nDigits = 0;
2155f8cdac6Sdrh   int nonNum = 0;
2165f8cdac6Sdrh 
2175f8cdac6Sdrh   *pResult = 0.0;   /* Default return value, in case of an error */
2185f8cdac6Sdrh 
2195f8cdac6Sdrh   /* skip leading spaces */
2205f8cdac6Sdrh   while( z<zEnd && totypeIsspace(*z) ) z++;
2215f8cdac6Sdrh   if( z>=zEnd ) return 0;
2225f8cdac6Sdrh 
2235f8cdac6Sdrh   /* get sign of significand */
2245f8cdac6Sdrh   if( *z=='-' ){
2255f8cdac6Sdrh     sign = -1;
2265f8cdac6Sdrh     z++;
2275f8cdac6Sdrh   }else if( *z=='+' ){
2285f8cdac6Sdrh     z++;
2295f8cdac6Sdrh   }
2305f8cdac6Sdrh 
2315f8cdac6Sdrh   /* skip leading zeroes */
2325f8cdac6Sdrh   while( z<zEnd && z[0]=='0' ) z++, nDigits++;
2335f8cdac6Sdrh 
2345f8cdac6Sdrh   /* copy max significant digits to significand */
2355f8cdac6Sdrh   while( z<zEnd && totypeIsdigit(*z) && s<((LARGEST_INT64-9)/10) ){
2365f8cdac6Sdrh     s = s*10 + (*z - '0');
2375f8cdac6Sdrh     z++, nDigits++;
2385f8cdac6Sdrh   }
2395f8cdac6Sdrh 
2405f8cdac6Sdrh   /* skip non-significant significand digits
2415f8cdac6Sdrh   ** (increase exponent by d to shift decimal left) */
2425f8cdac6Sdrh   while( z<zEnd && totypeIsdigit(*z) ) z++, nDigits++, d++;
2435f8cdac6Sdrh   if( z>=zEnd ) goto totype_atof_calc;
2445f8cdac6Sdrh 
2455f8cdac6Sdrh   /* if decimal point is present */
2465f8cdac6Sdrh   if( *z=='.' ){
2475f8cdac6Sdrh     z++;
2485f8cdac6Sdrh     /* copy digits from after decimal to significand
2495f8cdac6Sdrh     ** (decrease exponent by d to shift decimal right) */
2505f8cdac6Sdrh     while( z<zEnd && totypeIsdigit(*z) && s<((LARGEST_INT64-9)/10) ){
2515f8cdac6Sdrh       s = s*10 + (*z - '0');
2525f8cdac6Sdrh       z++, nDigits++, d--;
2535f8cdac6Sdrh     }
2545f8cdac6Sdrh     /* skip non-significant digits */
2555f8cdac6Sdrh     while( z<zEnd && totypeIsdigit(*z) ) z++, nDigits++;
2565f8cdac6Sdrh   }
2575f8cdac6Sdrh   if( z>=zEnd ) goto totype_atof_calc;
2585f8cdac6Sdrh 
2595f8cdac6Sdrh   /* if exponent is present */
2605f8cdac6Sdrh   if( *z=='e' || *z=='E' ){
2615f8cdac6Sdrh     z++;
2625f8cdac6Sdrh     eValid = 0;
2635f8cdac6Sdrh     if( z>=zEnd ) goto totype_atof_calc;
2645f8cdac6Sdrh     /* get sign of exponent */
2655f8cdac6Sdrh     if( *z=='-' ){
2665f8cdac6Sdrh       esign = -1;
2675f8cdac6Sdrh       z++;
2685f8cdac6Sdrh     }else if( *z=='+' ){
2695f8cdac6Sdrh       z++;
2705f8cdac6Sdrh     }
2715f8cdac6Sdrh     /* copy digits to exponent */
2725f8cdac6Sdrh     while( z<zEnd && totypeIsdigit(*z) ){
2735f8cdac6Sdrh       e = e<10000 ? (e*10 + (*z - '0')) : 10000;
2745f8cdac6Sdrh       z++;
2755f8cdac6Sdrh       eValid = 1;
2765f8cdac6Sdrh     }
2775f8cdac6Sdrh   }
2785f8cdac6Sdrh 
2795f8cdac6Sdrh   /* skip trailing spaces */
2805f8cdac6Sdrh   if( nDigits && eValid ){
2815f8cdac6Sdrh     while( z<zEnd && totypeIsspace(*z) ) z++;
2825f8cdac6Sdrh   }
2835f8cdac6Sdrh 
2845f8cdac6Sdrh totype_atof_calc:
2855f8cdac6Sdrh   /* adjust exponent by d, and update sign */
2865f8cdac6Sdrh   e = (e*esign) + d;
2875f8cdac6Sdrh   if( e<0 ) {
2885f8cdac6Sdrh     esign = -1;
2895f8cdac6Sdrh     e *= -1;
2905f8cdac6Sdrh   } else {
2915f8cdac6Sdrh     esign = 1;
2925f8cdac6Sdrh   }
2935f8cdac6Sdrh 
2945f8cdac6Sdrh   /* if 0 significand */
2955f8cdac6Sdrh   if( !s ) {
2965f8cdac6Sdrh     /* In the IEEE 754 standard, zero is signed.
2975f8cdac6Sdrh     ** Add the sign if we've seen at least one digit */
2985f8cdac6Sdrh     result = (sign<0 && nDigits) ? -(double)0 : (double)0;
2995f8cdac6Sdrh   } else {
3005f8cdac6Sdrh     /* attempt to reduce exponent */
3015f8cdac6Sdrh     if( esign>0 ){
3025f8cdac6Sdrh       while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
3035f8cdac6Sdrh     }else{
3045f8cdac6Sdrh       while( !(s%10) && e>0 ) e--,s/=10;
3055f8cdac6Sdrh     }
3065f8cdac6Sdrh 
3075f8cdac6Sdrh     /* adjust the sign of significand */
3085f8cdac6Sdrh     s = sign<0 ? -s : s;
3095f8cdac6Sdrh 
3105f8cdac6Sdrh     /* if exponent, scale significand as appropriate
3115f8cdac6Sdrh     ** and store in result. */
3125f8cdac6Sdrh     if( e ){
3135f8cdac6Sdrh       double scale = 1.0;
3145f8cdac6Sdrh       /* attempt to handle extremely small/large numbers better */
3155f8cdac6Sdrh       if( e>307 && e<342 ){
3165f8cdac6Sdrh         while( e%308 ) { scale *= 1.0e+1; e -= 1; }
3175f8cdac6Sdrh         if( esign<0 ){
3185f8cdac6Sdrh           result = s / scale;
3195f8cdac6Sdrh           result /= 1.0e+308;
3205f8cdac6Sdrh         }else{
3215f8cdac6Sdrh           result = s * scale;
3225f8cdac6Sdrh           result *= 1.0e+308;
3235f8cdac6Sdrh         }
3245f8cdac6Sdrh       }else if( e>=342 ){
3255f8cdac6Sdrh         if( esign<0 ){
3265f8cdac6Sdrh           result = 0.0*s;
3275f8cdac6Sdrh         }else{
3285f8cdac6Sdrh           result = 1e308*1e308*s;  /* Infinity */
3295f8cdac6Sdrh         }
3305f8cdac6Sdrh       }else{
3315f8cdac6Sdrh         /* 1.0e+22 is the largest power of 10 than can be
3325f8cdac6Sdrh         ** represented exactly. */
3335f8cdac6Sdrh         while( e%22 ) { scale *= 1.0e+1; e -= 1; }
3345f8cdac6Sdrh         while( e>0 ) { scale *= 1.0e+22; e -= 22; }
3355f8cdac6Sdrh         if( esign<0 ){
3365f8cdac6Sdrh           result = s / scale;
3375f8cdac6Sdrh         }else{
3385f8cdac6Sdrh           result = s * scale;
3395f8cdac6Sdrh         }
3405f8cdac6Sdrh       }
3415f8cdac6Sdrh     } else {
3425f8cdac6Sdrh       result = (double)s;
3435f8cdac6Sdrh     }
3445f8cdac6Sdrh   }
3455f8cdac6Sdrh 
3465f8cdac6Sdrh   /* store the result */
3475f8cdac6Sdrh   *pResult = result;
3485f8cdac6Sdrh 
3495f8cdac6Sdrh   /* return true if number and no extra non-whitespace chracters after */
3505f8cdac6Sdrh   return z>=zEnd && nDigits>0 && eValid && nonNum==0;
3515f8cdac6Sdrh }
3525f8cdac6Sdrh 
3535f8cdac6Sdrh /*
3545f8cdac6Sdrh ** tointeger(X):  If X is any value (integer, double, blob, or string) that
3555f8cdac6Sdrh ** can be losslessly converted into an integer, then make the conversion and
3565f8cdac6Sdrh ** return the result.  Otherwise, return NULL.
3575f8cdac6Sdrh */
tointegerFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)3585f8cdac6Sdrh static void tointegerFunc(
3595f8cdac6Sdrh   sqlite3_context *context,
3605f8cdac6Sdrh   int argc,
3615f8cdac6Sdrh   sqlite3_value **argv
3625f8cdac6Sdrh ){
3635f8cdac6Sdrh   assert( argc==1 );
3645f8cdac6Sdrh   (void)argc;
3655f8cdac6Sdrh   switch( sqlite3_value_type(argv[0]) ){
3665f8cdac6Sdrh     case SQLITE_FLOAT: {
3675f8cdac6Sdrh       double rVal = sqlite3_value_double(argv[0]);
3685f8cdac6Sdrh       sqlite3_int64 iVal = (sqlite3_int64)rVal;
3695f8cdac6Sdrh       if( rVal==(double)iVal ){
3705f8cdac6Sdrh         sqlite3_result_int64(context, iVal);
3715f8cdac6Sdrh       }
3725f8cdac6Sdrh       break;
3735f8cdac6Sdrh     }
3745f8cdac6Sdrh     case SQLITE_INTEGER: {
3755f8cdac6Sdrh       sqlite3_result_int64(context, sqlite3_value_int64(argv[0]));
3765f8cdac6Sdrh       break;
3775f8cdac6Sdrh     }
3785f8cdac6Sdrh     case SQLITE_BLOB: {
3795f8cdac6Sdrh       const unsigned char *zBlob = sqlite3_value_blob(argv[0]);
3805f8cdac6Sdrh       if( zBlob ){
3815f8cdac6Sdrh         int nBlob = sqlite3_value_bytes(argv[0]);
3825f8cdac6Sdrh         if( nBlob==sizeof(sqlite3_int64) ){
3835f8cdac6Sdrh           sqlite3_int64 iVal;
3840593516fSmistachkin           if( TOTYPE_BIGENDIAN ){
3855f8cdac6Sdrh             int i;
3865f8cdac6Sdrh             unsigned char zBlobRev[sizeof(sqlite3_int64)];
3875f8cdac6Sdrh             for(i=0; i<sizeof(sqlite3_int64); i++){
3885f8cdac6Sdrh               zBlobRev[i] = zBlob[sizeof(sqlite3_int64)-1-i];
3895f8cdac6Sdrh             }
3905f8cdac6Sdrh             memcpy(&iVal, zBlobRev, sizeof(sqlite3_int64));
3915f8cdac6Sdrh           }else{
3925f8cdac6Sdrh             memcpy(&iVal, zBlob, sizeof(sqlite3_int64));
3935f8cdac6Sdrh           }
3945f8cdac6Sdrh           sqlite3_result_int64(context, iVal);
3955f8cdac6Sdrh         }
3965f8cdac6Sdrh       }
3975f8cdac6Sdrh       break;
3985f8cdac6Sdrh     }
3995f8cdac6Sdrh     case SQLITE_TEXT: {
4005f8cdac6Sdrh       const unsigned char *zStr = sqlite3_value_text(argv[0]);
4015f8cdac6Sdrh       if( zStr ){
4025f8cdac6Sdrh         int nStr = sqlite3_value_bytes(argv[0]);
4035f8cdac6Sdrh         if( nStr && !totypeIsspace(zStr[0]) ){
4045f8cdac6Sdrh           sqlite3_int64 iVal;
4055f8cdac6Sdrh           if( !totypeAtoi64((const char*)zStr, &iVal, nStr) ){
4065f8cdac6Sdrh             sqlite3_result_int64(context, iVal);
4075f8cdac6Sdrh           }
4085f8cdac6Sdrh         }
4095f8cdac6Sdrh       }
4105f8cdac6Sdrh       break;
4115f8cdac6Sdrh     }
4125f8cdac6Sdrh     default: {
4135f8cdac6Sdrh       assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
4145f8cdac6Sdrh       break;
4155f8cdac6Sdrh     }
4165f8cdac6Sdrh   }
4175f8cdac6Sdrh }
4185f8cdac6Sdrh 
4195f8cdac6Sdrh /*
4205f8cdac6Sdrh ** toreal(X): If X is any value (integer, double, blob, or string) that can
4215f8cdac6Sdrh ** be losslessly converted into a real number, then do so and return that
4225f8cdac6Sdrh ** real number.  Otherwise return NULL.
4235f8cdac6Sdrh */
4245f8cdac6Sdrh #if defined(_MSC_VER)
4250593516fSmistachkin #pragma warning(disable: 4748)
4265f8cdac6Sdrh #pragma optimize("", off)
4275f8cdac6Sdrh #endif
torealFunc(sqlite3_context * context,int argc,sqlite3_value ** argv)4285f8cdac6Sdrh static void torealFunc(
4295f8cdac6Sdrh   sqlite3_context *context,
4305f8cdac6Sdrh   int argc,
4315f8cdac6Sdrh   sqlite3_value **argv
4325f8cdac6Sdrh ){
4335f8cdac6Sdrh   assert( argc==1 );
4345f8cdac6Sdrh   (void)argc;
4355f8cdac6Sdrh   switch( sqlite3_value_type(argv[0]) ){
4365f8cdac6Sdrh     case SQLITE_FLOAT: {
4375f8cdac6Sdrh       sqlite3_result_double(context, sqlite3_value_double(argv[0]));
4385f8cdac6Sdrh       break;
4395f8cdac6Sdrh     }
4405f8cdac6Sdrh     case SQLITE_INTEGER: {
4415f8cdac6Sdrh       sqlite3_int64 iVal = sqlite3_value_int64(argv[0]);
4425f8cdac6Sdrh       double rVal = (double)iVal;
4435f8cdac6Sdrh       if( iVal==(sqlite3_int64)rVal ){
4445f8cdac6Sdrh         sqlite3_result_double(context, rVal);
4455f8cdac6Sdrh       }
4465f8cdac6Sdrh       break;
4475f8cdac6Sdrh     }
4485f8cdac6Sdrh     case SQLITE_BLOB: {
4495f8cdac6Sdrh       const unsigned char *zBlob = sqlite3_value_blob(argv[0]);
4505f8cdac6Sdrh       if( zBlob ){
4515f8cdac6Sdrh         int nBlob = sqlite3_value_bytes(argv[0]);
4525f8cdac6Sdrh         if( nBlob==sizeof(double) ){
4535f8cdac6Sdrh           double rVal;
4540593516fSmistachkin           if( TOTYPE_LITTLEENDIAN ){
4555f8cdac6Sdrh             int i;
4565f8cdac6Sdrh             unsigned char zBlobRev[sizeof(double)];
4575f8cdac6Sdrh             for(i=0; i<sizeof(double); i++){
4585f8cdac6Sdrh               zBlobRev[i] = zBlob[sizeof(double)-1-i];
4595f8cdac6Sdrh             }
4605f8cdac6Sdrh             memcpy(&rVal, zBlobRev, sizeof(double));
4615f8cdac6Sdrh           }else{
4625f8cdac6Sdrh             memcpy(&rVal, zBlob, sizeof(double));
4635f8cdac6Sdrh           }
4645f8cdac6Sdrh           sqlite3_result_double(context, rVal);
4655f8cdac6Sdrh         }
4665f8cdac6Sdrh       }
4675f8cdac6Sdrh       break;
4685f8cdac6Sdrh     }
4695f8cdac6Sdrh     case SQLITE_TEXT: {
4705f8cdac6Sdrh       const unsigned char *zStr = sqlite3_value_text(argv[0]);
4715f8cdac6Sdrh       if( zStr ){
4725f8cdac6Sdrh         int nStr = sqlite3_value_bytes(argv[0]);
4735f8cdac6Sdrh         if( nStr && !totypeIsspace(zStr[0]) && !totypeIsspace(zStr[nStr-1]) ){
4745f8cdac6Sdrh           double rVal;
4755f8cdac6Sdrh           if( totypeAtoF((const char*)zStr, &rVal, nStr) ){
4765f8cdac6Sdrh             sqlite3_result_double(context, rVal);
4775f8cdac6Sdrh             return;
4785f8cdac6Sdrh           }
4795f8cdac6Sdrh         }
4805f8cdac6Sdrh       }
4815f8cdac6Sdrh       break;
4825f8cdac6Sdrh     }
4835f8cdac6Sdrh     default: {
4845f8cdac6Sdrh       assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
4855f8cdac6Sdrh       break;
4865f8cdac6Sdrh     }
4875f8cdac6Sdrh   }
4885f8cdac6Sdrh }
4895f8cdac6Sdrh #if defined(_MSC_VER)
4905f8cdac6Sdrh #pragma optimize("", on)
4910593516fSmistachkin #pragma warning(default: 4748)
4925f8cdac6Sdrh #endif
4935f8cdac6Sdrh 
4945f8cdac6Sdrh #ifdef _WIN32
4955f8cdac6Sdrh __declspec(dllexport)
4965f8cdac6Sdrh #endif
sqlite3_totype_init(sqlite3 * db,char ** pzErrMsg,const sqlite3_api_routines * pApi)4975f8cdac6Sdrh int sqlite3_totype_init(
4985f8cdac6Sdrh   sqlite3 *db,
4995f8cdac6Sdrh   char **pzErrMsg,
5005f8cdac6Sdrh   const sqlite3_api_routines *pApi
5015f8cdac6Sdrh ){
5025f8cdac6Sdrh   int rc = SQLITE_OK;
5035f8cdac6Sdrh   SQLITE_EXTENSION_INIT2(pApi);
5045f8cdac6Sdrh   (void)pzErrMsg;  /* Unused parameter */
50520cee7d0Sdrh   rc = sqlite3_create_function(db, "tointeger", 1,
506*2b1c2aadSdrh         SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
5075f8cdac6Sdrh         tointegerFunc, 0, 0);
5085f8cdac6Sdrh   if( rc==SQLITE_OK ){
50920cee7d0Sdrh     rc = sqlite3_create_function(db, "toreal", 1,
510*2b1c2aadSdrh         SQLITE_UTF8 | SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS, 0,
5115f8cdac6Sdrh         torealFunc, 0, 0);
5125f8cdac6Sdrh   }
5135f8cdac6Sdrh   return rc;
5145f8cdac6Sdrh }
515