wasCSharpSQLite – Blame information for rev 3
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Text; |
||
4 | |||
5 | using i64 = System.Int64; |
||
6 | |||
7 | using u8 = System.Byte; |
||
8 | using u32 = System.UInt32; |
||
9 | using u64 = System.UInt64; |
||
10 | |||
11 | using Pgno = System.UInt32; |
||
12 | |||
13 | |||
14 | namespace Community.CsharpSqlite |
||
15 | { |
||
16 | using sqlite_int64 = System.Int64; |
||
17 | using System.Globalization; |
||
18 | |||
19 | public partial class Sqlite3 |
||
20 | { |
||
21 | /* |
||
22 | ** 2001 September 15 |
||
23 | ** |
||
24 | ** The author disclaims copyright to this source code. In place of |
||
25 | ** a legal notice, here is a blessing: |
||
26 | ** |
||
27 | ** May you do good and not evil. |
||
28 | ** May you find forgiveness for yourself and forgive others. |
||
29 | ** May you share freely, never taking more than you give. |
||
30 | ** |
||
31 | ************************************************************************* |
||
32 | ** Utility functions used throughout sqlite. |
||
33 | ** |
||
34 | ** This file contains functions for allocating memory, comparing |
||
35 | ** strings, and stuff like that. |
||
36 | ** |
||
37 | ************************************************************************* |
||
38 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
39 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
40 | ** |
||
41 | ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 |
||
42 | ** |
||
43 | ************************************************************************* |
||
44 | */ |
||
45 | //#include "sqliteInt.h" |
||
46 | //#include <stdarg.h> |
||
47 | //#if SQLITE_HAVE_ISNAN |
||
48 | //# include <math.h> |
||
49 | //#endif |
||
50 | |||
51 | /* |
||
52 | ** Routine needed to support the testcase() macro. |
||
53 | */ |
||
54 | #if SQLITE_COVERAGE_TEST |
||
55 | void sqlite3Coverage(int x){ |
||
56 | static uint dummy = 0; |
||
57 | dummy += (uint)x; |
||
58 | } |
||
59 | #endif |
||
60 | |||
61 | #if !SQLITE_OMIT_FLOATING_POINT |
||
62 | /* |
||
63 | ** Return true if the floating point value is Not a Number (NaN). |
||
64 | ** |
||
65 | ** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. |
||
66 | ** Otherwise, we have our own implementation that works on most systems. |
||
67 | */ |
||
68 | static bool sqlite3IsNaN( double x ) |
||
69 | { |
||
70 | //// bool rc; /* The value return */ |
||
71 | ////#if !(SQLITE_HAVE_ISNAN) |
||
72 | /* |
||
73 | ** Systems that support the isnan() library function should probably |
||
74 | ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have |
||
75 | ** found that many systems do not have a working isnan() function so |
||
76 | ** this implementation is provided as an alternative. |
||
77 | ** |
||
78 | ** This NaN test sometimes fails if compiled on GCC with -ffast-math. |
||
79 | ** On the other hand, the use of -ffast-math comes with the following |
||
80 | ** warning: |
||
81 | ** |
||
82 | ** This option [-ffast-math] should never be turned on by any |
||
83 | ** -O option since it can result in incorrect output for programs |
||
84 | ** which depend on an exact implementation of IEEE or ISO |
||
85 | ** rules/specifications for math functions. |
||
86 | ** |
||
87 | ** Under MSVC, this NaN test may fail if compiled with a floating- |
||
88 | ** point precision mode other than /fp:precise. From the MSDN |
||
89 | ** documentation: |
||
90 | ** |
||
91 | ** The compiler [with /fp:precise] will properly handle comparisons |
||
92 | ** involving NaN. For example, x != x evaluates to true if x is NaN |
||
93 | ** ... |
||
94 | */ |
||
95 | ////#if __FAST_MATH__ |
||
96 | ////# error SQLite will not work correctly with the -ffast-math option of GCC. |
||
97 | ////#endif |
||
98 | //// double y = x; |
||
99 | //// double z = y; |
||
100 | //// rc = ( y != z ); |
||
101 | ////#else //* if defined(SQLITE_HAVE_ISNAN) */ |
||
102 | ////rc = isnan(x); |
||
103 | ////#endif //* SQLITE_HAVE_ISNAN */ |
||
104 | |||
105 | bool rc = double.IsNaN(x); |
||
106 | |||
107 | testcase( rc ); |
||
108 | return rc; |
||
109 | } |
||
110 | #endif //* SQLITE_OMIT_FLOATING_POINT */ |
||
111 | |||
112 | /* |
||
113 | ** Compute a string length that is limited to what can be stored in |
||
114 | ** lower 30 bits of a 32-bit signed integer. |
||
115 | ** |
||
116 | ** The value returned will never be negative. Nor will it ever be greater |
||
117 | ** than the actual length of the string. For very long strings (greater |
||
118 | ** than 1GiB) the value returned might be less than the true string length. |
||
119 | */ |
||
120 | static int sqlite3Strlen30( int z ) |
||
121 | { |
||
122 | return 0x3fffffff & z; |
||
123 | } |
||
124 | static int sqlite3Strlen30( StringBuilder z ) |
||
125 | { |
||
126 | //string z2 = z; |
||
127 | if ( z == null ) |
||
128 | return 0; |
||
129 | //while( *z2 ){ z2++; } |
||
130 | //return 0x3fffffff & (int)(z2 - z); |
||
131 | int iLen = z.ToString().IndexOf( '\0' ); |
||
132 | return 0x3fffffff & ( iLen == -1 ? z.Length : iLen ); |
||
133 | } |
||
134 | static int sqlite3Strlen30( string z ) |
||
135 | { |
||
136 | //string z2 = z; |
||
137 | if ( z == null ) |
||
138 | return 0; |
||
139 | //while( *z2 ){ z2++; } |
||
140 | //return 0x3fffffff & (int)(z2 - z); |
||
141 | int iLen = z.IndexOf( '\0' ); |
||
142 | return 0x3fffffff & (iLen == -1 ? z.Length : iLen); |
||
143 | } |
||
144 | |||
145 | /* |
||
146 | ** Set the most recent error code and error string for the sqlite |
||
147 | ** handle "db". The error code is set to "err_code". |
||
148 | ** |
||
149 | ** If it is not NULL, string zFormat specifies the format of the |
||
150 | ** error string in the style of the printf functions: The following |
||
151 | ** format characters are allowed: |
||
152 | ** |
||
153 | ** %s Insert a string |
||
154 | ** %z A string that should be freed after use |
||
155 | ** %d Insert an integer |
||
156 | ** %T Insert a token |
||
157 | ** %S Insert the first element of a SrcList |
||
158 | ** |
||
159 | ** zFormat and any string tokens that follow it are assumed to be |
||
160 | ** encoded in UTF-8. |
||
161 | ** |
||
162 | ** To clear the most recent error for sqlite handle "db", sqlite3Error |
||
163 | ** should be called with err_code set to SQLITE_OK and zFormat set |
||
164 | ** to NULL. |
||
165 | */ |
||
166 | //Overloads |
||
167 | static void sqlite3Error( sqlite3 db, int err_code, int noString ) |
||
168 | { |
||
169 | sqlite3Error( db, err_code, err_code == 0 ? null : string.Empty ); |
||
170 | } |
||
171 | |||
172 | static void sqlite3Error( sqlite3 db, int err_code, string zFormat, params object[] ap ) |
||
173 | { |
||
174 | if ( db != null && ( db.pErr != null || ( db.pErr = sqlite3ValueNew( db ) ) != null ) ) |
||
175 | { |
||
176 | db.errCode = err_code; |
||
177 | if ( zFormat != null ) |
||
178 | { |
||
179 | lock ( lock_va_list ) |
||
180 | { |
||
181 | string z; |
||
182 | va_start( ap, zFormat ); |
||
183 | z = sqlite3VMPrintf( db, zFormat, ap ); |
||
184 | va_end( ref ap ); |
||
185 | sqlite3ValueSetStr( db.pErr, -1, z, SQLITE_UTF8, (dxDel)SQLITE_DYNAMIC ); |
||
186 | } |
||
187 | } |
||
188 | else |
||
189 | { |
||
190 | sqlite3ValueSetStr( db.pErr, 0, null, SQLITE_UTF8, SQLITE_STATIC ); |
||
191 | } |
||
192 | } |
||
193 | } |
||
194 | |||
195 | /* |
||
196 | ** Add an error message to pParse.zErrMsg and increment pParse.nErr. |
||
197 | ** The following formatting characters are allowed: |
||
198 | ** |
||
199 | ** %s Insert a string |
||
200 | ** %z A string that should be freed after use |
||
201 | ** %d Insert an integer |
||
202 | ** %T Insert a token |
||
203 | ** %S Insert the first element of a SrcList |
||
204 | ** |
||
205 | ** This function should be used to report any error that occurs whilst |
||
206 | ** compiling an SQL statement (i.e. within sqlite3_prepare()). The |
||
207 | ** last thing the sqlite3_prepare() function does is copy the error |
||
208 | ** stored by this function into the database handle using sqlite3Error(). |
||
209 | ** Function sqlite3Error() should be used during statement execution |
||
210 | ** (sqlite3_step() etc.). |
||
211 | */ |
||
212 | static void sqlite3ErrorMsg( Parse pParse, string zFormat, params object[] ap ) |
||
213 | { |
||
214 | string zMsg; |
||
215 | sqlite3 db = pParse.db; |
||
216 | //va_list ap; |
||
217 | lock ( lock_va_list ) |
||
218 | { |
||
219 | va_start( ap, zFormat ); |
||
220 | zMsg = sqlite3VMPrintf( db, zFormat, ap ); |
||
221 | va_end( ref ap ); |
||
222 | } |
||
223 | if ( db.suppressErr != 0 ) |
||
224 | { |
||
225 | sqlite3DbFree( db, ref zMsg ); |
||
226 | } |
||
227 | else |
||
228 | { |
||
229 | pParse.nErr++; |
||
230 | sqlite3DbFree( db, ref pParse.zErrMsg ); |
||
231 | pParse.zErrMsg = zMsg; |
||
232 | pParse.rc = SQLITE_ERROR; |
||
233 | } |
||
234 | } |
||
235 | |||
236 | /* |
||
237 | ** Convert an SQL-style quoted string into a normal string by removing |
||
238 | ** the quote characters. The conversion is done in-place. If the |
||
239 | ** input does not begin with a quote character, then this routine |
||
240 | ** is a no-op. |
||
241 | ** |
||
242 | ** The input string must be zero-terminated. A new zero-terminator |
||
243 | ** is added to the dequoted string. |
||
244 | ** |
||
245 | ** The return value is -1 if no dequoting occurs or the length of the |
||
246 | ** dequoted string, exclusive of the zero terminator, if dequoting does |
||
247 | ** occur. |
||
248 | ** |
||
249 | ** 2002-Feb-14: This routine is extended to remove MS-Access style |
||
250 | ** brackets from around identifers. For example: "[a-b-c]" becomes |
||
251 | ** "a-b-c". |
||
252 | */ |
||
253 | static int sqlite3Dequote( ref string z ) |
||
254 | { |
||
255 | char quote; |
||
256 | int i; |
||
257 | if ( string.IsNullOrEmpty( z ) ) |
||
258 | return -1; |
||
259 | quote = z[0]; |
||
260 | switch ( quote ) |
||
261 | { |
||
262 | case '\'': |
||
263 | break; |
||
264 | case '"': |
||
265 | break; |
||
266 | case '`': |
||
267 | break; /* For MySQL compatibility */ |
||
268 | case '[': |
||
269 | quote = ']'; |
||
270 | break; /* For MS SqlServer compatibility */ |
||
271 | default: |
||
272 | return -1; |
||
273 | } |
||
274 | StringBuilder sbZ = new StringBuilder( z.Length ); |
||
275 | for ( i = 1; i < z.Length; i++ ) //z[i] != 0; i++) |
||
276 | { |
||
277 | if ( z[i] == quote ) |
||
278 | { |
||
279 | if ( i < z.Length - 1 && ( z[i + 1] == quote ) ) |
||
280 | { |
||
281 | sbZ.Append( quote ); |
||
282 | i++; |
||
283 | } |
||
284 | else |
||
285 | { |
||
286 | break; |
||
287 | } |
||
288 | } |
||
289 | else |
||
290 | { |
||
291 | sbZ.Append( z[i] ); |
||
292 | } |
||
293 | } |
||
294 | z = sbZ.ToString(); |
||
295 | return sbZ.Length; |
||
296 | } |
||
297 | |||
298 | /* Convenient short-hand */ |
||
299 | //#define UpperToLower sqlite3UpperToLower |
||
300 | |||
301 | /* |
||
302 | ** Some systems have stricmp(). Others have strcasecmp(). Because |
||
303 | ** there is no consistency, we will define our own. |
||
304 | ** |
||
305 | ** IMPLEMENTATION-OF: R-20522-24639 The sqlite3_strnicmp() API allows |
||
306 | ** applications and extensions to compare the contents of two buffers |
||
307 | ** containing UTF-8 strings in a case-independent fashion, using the same |
||
308 | ** definition of case independence that SQLite uses internally when |
||
309 | ** comparing identifiers. |
||
310 | */ |
||
311 | |||
312 | static int sqlite3StrNICmp( string zLeft, int offsetLeft, string zRight, int N ) |
||
313 | { |
||
314 | //register unsigned char *a, *b; |
||
315 | //a = (unsigned char )zLeft; |
||
316 | //b = (unsigned char )zRight; |
||
317 | int a = 0, b = 0; |
||
318 | while ( N-- > 0 && a < zLeft.Length - offsetLeft && b < zRight.Length && zLeft[a + offsetLeft] != 0 && UpperToLower[zLeft[a + offsetLeft]] == UpperToLower[zRight[b]] ) |
||
319 | { |
||
320 | a++; |
||
321 | b++; |
||
322 | } |
||
323 | return N < 0 ? 0 : ( ( a < zLeft.Length - offsetLeft ) ? UpperToLower[zLeft[a + offsetLeft]] : 0 ) - UpperToLower[zRight[b]]; |
||
324 | } |
||
325 | |||
326 | static int sqlite3StrNICmp( string zLeft, string zRight, int N ) |
||
327 | { |
||
328 | //register unsigned char *a, *b; |
||
329 | //a = (unsigned char )zLeft; |
||
330 | //b = (unsigned char )zRight; |
||
331 | int a = 0, b = 0; |
||
332 | while ( N-- > 0 && a < zLeft.Length && b < zRight.Length && ( zLeft[a] == zRight[b] || ( zLeft[a] != 0 && zLeft[a] < 256 && zRight[b] < 256 && UpperToLower[zLeft[a]] == UpperToLower[zRight[b]] ) ) ) |
||
333 | { |
||
334 | a++; |
||
335 | b++; |
||
336 | } |
||
337 | if ( N < 0 ) |
||
338 | return 0; |
||
339 | if ( a == zLeft.Length && b == zRight.Length ) |
||
340 | return 0; |
||
341 | if ( a == zLeft.Length ) |
||
342 | return -UpperToLower[zRight[b]]; |
||
343 | if ( b == zRight.Length ) |
||
344 | return UpperToLower[zLeft[a]]; |
||
345 | return ( zLeft[a] < 256 ? UpperToLower[zLeft[a]] : zLeft[a] ) - ( zRight[b] < 256 ? UpperToLower[zRight[b]] : zRight[b] ); |
||
346 | } |
||
347 | |||
348 | |||
349 | /* |
||
350 | ** The string z[] is an text representation of a real number. |
||
351 | ** Convert this string to a double and write it into *pResult. |
||
352 | ** |
||
353 | ** The string z[] is length bytes in length (bytes, not characters) and |
||
354 | ** uses the encoding enc. The string is not necessarily zero-terminated. |
||
355 | ** |
||
356 | ** Return TRUE if the result is a valid real number (or integer) and FALSE |
||
357 | ** if the string is empty or contains extraneous text. Valid numbers |
||
358 | ** are in one of these formats: |
||
359 | ** |
||
360 | ** [+-]digits[E[+-]digits] |
||
361 | ** [+-]digits.[digits][E[+-]digits] |
||
362 | ** [+-].digits[E[+-]digits] |
||
363 | ** |
||
364 | ** Leading and trailing whitespace is ignored for the purpose of determining |
||
365 | ** validity. |
||
366 | ** |
||
367 | ** If some prefix of the input string is a valid number, this routine |
||
368 | ** returns FALSE but it still converts the prefix and writes the result |
||
369 | ** into *pResult. |
||
370 | */ |
||
371 | static bool sqlite3AtoF( string z, ref double pResult, int length, u8 enc ) |
||
372 | { |
||
373 | #if !SQLITE_OMIT_FLOATING_POINT |
||
374 | if ( string.IsNullOrEmpty( z ) ) |
||
375 | { |
||
376 | pResult = 0; |
||
377 | return false; |
||
378 | } |
||
379 | int incr = ( enc == SQLITE_UTF8 ? 1 : 2 ); |
||
380 | //const char* zEnd = z + length; |
||
381 | |||
382 | /* sign * significand * (10 ^ (esign * exponent)) */ |
||
383 | int sign = 1; /* sign of significand */ |
||
384 | i64 s = 0; /* significand */ |
||
385 | int d = 0; /* adjust exponent for shifting decimal point */ |
||
386 | int esign = 1; /* sign of exponent */ |
||
387 | int e = 0; /* exponent */ |
||
388 | int eValid = 1; /* True exponent is either not used or is well-formed */ |
||
389 | double result = 0; |
||
390 | int nDigits = 0; |
||
391 | |||
392 | pResult = 0.0; /* Default return value, in case of an error */ |
||
393 | |||
394 | int zDx = 0; |
||
395 | if ( enc == SQLITE_UTF16BE ) |
||
396 | zDx++; |
||
397 | |||
398 | while ( zDx < length && sqlite3Isspace( z[zDx] ) ) |
||
399 | zDx++; |
||
400 | if ( zDx >= length ) |
||
401 | return false; |
||
402 | |||
403 | /* get sign of significand */ |
||
404 | if ( z[zDx] == '-' ) |
||
405 | { |
||
406 | sign = -1; |
||
407 | zDx += incr; |
||
408 | } |
||
409 | else if ( z[zDx] == '+' ) |
||
410 | { |
||
411 | zDx += incr; |
||
412 | } |
||
413 | /* skip leading zeroes */ |
||
414 | while ( zDx < z.Length && z[zDx] == '0' ) |
||
415 | { |
||
416 | zDx += incr; |
||
417 | nDigits++; |
||
418 | } |
||
419 | /* copy max significant digits to significand */ |
||
420 | while ( zDx < length && sqlite3Isdigit( z[zDx] ) && s < ( ( LARGEST_INT64 - 9 ) / 10 ) ) |
||
421 | { |
||
422 | s = s * 10 + ( z[zDx] - '0' ); |
||
423 | zDx += incr; |
||
424 | nDigits++; |
||
425 | } |
||
426 | /* skip non-significant significand digits |
||
427 | ** (increase exponent by d to shift decimal left) */ |
||
428 | while ( zDx < length && sqlite3Isdigit( z[zDx] ) ) |
||
429 | { |
||
430 | zDx += incr; |
||
431 | nDigits++; |
||
432 | d++; |
||
433 | } |
||
434 | if ( zDx >= length ) |
||
435 | goto do_atof_calc; |
||
436 | |||
437 | /* if decimal point is present */ |
||
438 | if ( z[zDx] == '.' ) |
||
439 | { |
||
440 | zDx += incr; |
||
441 | /* copy digits from after decimal to significand |
||
442 | ** (decrease exponent by d to shift decimal right) */ |
||
443 | while ( zDx < length && sqlite3Isdigit( z[zDx] ) && s < ( ( LARGEST_INT64 - 9 ) / 10 ) ) |
||
444 | { |
||
445 | s = s * 10 + ( z[zDx] - '0' ); |
||
446 | zDx += incr; |
||
447 | nDigits++; |
||
448 | d--; |
||
449 | } |
||
450 | |||
451 | /* skip non-significant digits */ |
||
452 | while ( zDx < length && sqlite3Isdigit( z[zDx] ) ) |
||
453 | { |
||
454 | zDx += incr; |
||
455 | nDigits++; |
||
456 | } |
||
457 | if ( zDx >= length ) |
||
458 | goto do_atof_calc; |
||
459 | } |
||
460 | |||
461 | /* if exponent is present */ |
||
462 | if ( z[zDx] == 'e' || z[zDx] == 'E' ) |
||
463 | { |
||
464 | zDx += incr; |
||
465 | eValid = 0; |
||
466 | if ( zDx >= length ) |
||
467 | goto do_atof_calc; |
||
468 | |||
469 | /* get sign of exponent */ |
||
470 | if ( z[zDx] == '-' ) |
||
471 | { |
||
472 | esign = -1; |
||
473 | zDx += incr; |
||
474 | } |
||
475 | else if ( z[zDx] == '+' ) |
||
476 | { |
||
477 | zDx += incr; |
||
478 | } |
||
479 | |||
480 | /* copy digits to exponent */ |
||
481 | while ( zDx < length && sqlite3Isdigit( z[zDx] ) ) |
||
482 | { |
||
483 | e = e * 10 + ( z[zDx] - '0' ); |
||
484 | zDx += incr; |
||
485 | eValid = 1; |
||
486 | } |
||
487 | } |
||
488 | |||
489 | /* skip trailing spaces */ |
||
490 | if ( nDigits > 0 && eValid > 0 ) |
||
491 | { |
||
492 | while ( zDx < length && sqlite3Isspace( z[zDx] ) ) |
||
493 | zDx += incr; |
||
494 | } |
||
495 | |||
496 | do_atof_calc: |
||
497 | |||
498 | /* adjust exponent by d, and update sign */ |
||
499 | e = ( e * esign ) + d; |
||
500 | if ( e < 0 ) |
||
501 | { |
||
502 | esign = -1; |
||
503 | e *= -1; |
||
504 | } |
||
505 | else |
||
506 | { |
||
507 | esign = 1; |
||
508 | } |
||
509 | |||
510 | /* if 0 significand */ |
||
511 | if ( 0 == s ) |
||
512 | { |
||
513 | /* In the IEEE 754 standard, zero is signed. |
||
514 | ** Add the sign if we've seen at least one digit */ |
||
515 | result = ( sign < 0 && nDigits != 0 ) ? -(double)0 : (double)0; |
||
516 | } |
||
517 | else |
||
518 | { |
||
519 | /* attempt to reduce exponent */ |
||
520 | if ( esign > 0 ) |
||
521 | { |
||
522 | while ( s < ( LARGEST_INT64 / 10 ) && e > 0 ) |
||
523 | { |
||
524 | e--; |
||
525 | s *= 10; |
||
526 | } |
||
527 | } |
||
528 | else |
||
529 | { |
||
530 | while ( 0 == ( s % 10 ) && e > 0 ) |
||
531 | { |
||
532 | e--; |
||
533 | s /= 10; |
||
534 | } |
||
535 | } |
||
536 | |||
537 | /* adjust the sign of significand */ |
||
538 | s = sign < 0 ? -s : s; |
||
539 | |||
540 | /* if exponent, scale significand as appropriate |
||
541 | ** and store in result. */ |
||
542 | if ( e != 0 ) |
||
543 | { |
||
544 | double scale = 1.0; |
||
545 | /* attempt to handle extremely small/large numbers better */ |
||
546 | if ( e > 307 && e < 342 ) |
||
547 | { |
||
548 | while ( ( e % 308 ) != 0 ) |
||
549 | { |
||
550 | scale *= 1.0e+1; |
||
551 | e -= 1; |
||
552 | } |
||
553 | if ( esign < 0 ) |
||
554 | { |
||
555 | result = s / scale; |
||
556 | result /= 1.0e+308; |
||
557 | } |
||
558 | else |
||
559 | { |
||
560 | result = s * scale; |
||
561 | result *= 1.0e+308; |
||
562 | } |
||
563 | } |
||
564 | else |
||
565 | { |
||
566 | /* 1.0e+22 is the largest power of 10 than can be |
||
567 | ** represented exactly. */ |
||
568 | while ( ( e % 22 ) != 0 ) |
||
569 | { |
||
570 | scale *= 1.0e+1; |
||
571 | e -= 1; |
||
572 | } |
||
573 | while ( e > 0 ) |
||
574 | { |
||
575 | scale *= 1.0e+22; |
||
576 | e -= 22; |
||
577 | } |
||
578 | if ( esign < 0 ) |
||
579 | { |
||
580 | result = s / scale; |
||
581 | } |
||
582 | else |
||
583 | { |
||
584 | result = s * scale; |
||
585 | } |
||
586 | } |
||
587 | } |
||
588 | else |
||
589 | { |
||
590 | result = (double)s; |
||
591 | } |
||
592 | } |
||
593 | /* store the result */ |
||
594 | pResult = result; |
||
595 | |||
596 | /* return true if number and no extra non-whitespace chracters after */ |
||
597 | return zDx >= length && nDigits > 0 && eValid != 0; |
||
598 | #else |
||
599 | return !sqlite3Atoi64(z, pResult, length, enc); |
||
600 | #endif //* SQLITE_OMIT_FLOATING_POINT */ |
||
601 | } |
||
602 | |||
603 | /* |
||
604 | ** Compare the 19-character string zNum against the text representation |
||
605 | ** value 2^63: 9223372036854775808. Return negative, zero, or positive |
||
606 | ** if zNum is less than, equal to, or greater than the string. |
||
607 | ** Note that zNum must contain exactly 19 characters. |
||
608 | ** |
||
609 | ** Unlike memcmp() this routine is guaranteed to return the difference |
||
610 | ** in the values of the last digit if the only difference is in the |
||
611 | ** last digit. So, for example, |
||
612 | ** |
||
613 | ** compare2pow63("9223372036854775800", 1) |
||
614 | ** |
||
615 | ** will return -8. |
||
616 | */ |
||
617 | static int compare2pow63( string zNum, int incr ) |
||
618 | { |
||
619 | int c = 0; |
||
620 | int i; |
||
621 | /* 012345678901234567 */ |
||
622 | string pow63 = "922337203685477580"; |
||
623 | for ( i = 0; c == 0 && i < 18; i++ ) |
||
624 | { |
||
625 | c = ( zNum[i * incr] - pow63[i] ) * 10; |
||
626 | } |
||
627 | |||
628 | if ( c == 0 ) |
||
629 | { |
||
630 | c = zNum[18 * incr] - '8'; |
||
631 | testcase( c == ( -1 ) ); |
||
632 | testcase( c == 0 ); |
||
633 | testcase( c == ( +1 ) ); |
||
634 | } |
||
635 | return c; |
||
636 | } |
||
637 | |||
638 | |||
639 | /* |
||
640 | ** Convert zNum to a 64-bit signed integer. |
||
641 | ** |
||
642 | ** If the zNum value is representable as a 64-bit twos-complement |
||
643 | ** integer, then write that value into *pNum and return 0. |
||
644 | ** |
||
645 | ** If zNum is exactly 9223372036854665808, return 2. This special |
||
646 | ** case is broken out because while 9223372036854665808 cannot be a |
||
647 | ** signed 64-bit integer, its negative -9223372036854665808 can be. |
||
648 | ** |
||
649 | ** If zNum is too big for a 64-bit integer and is not |
||
650 | ** 9223372036854665808 then return 1. |
||
651 | ** |
||
652 | ** length is the number of bytes in the string (bytes, not characters). |
||
653 | ** The string is not necessarily zero-terminated. The encoding is |
||
654 | ** given by enc. |
||
655 | */ |
||
656 | static int sqlite3Atoi64( string zNum, ref i64 pNum, int length, u8 enc ) |
||
657 | { |
||
658 | if ( zNum == null ) |
||
659 | { |
||
660 | pNum = 0; |
||
661 | return 1; |
||
662 | } |
||
663 | int incr = ( enc == SQLITE_UTF8 ? 1 : 2 ); |
||
664 | u64 u = 0; |
||
665 | int neg = 0; /* assume positive */ |
||
666 | int i; |
||
667 | int c = 0; |
||
668 | int zDx = 0;// string zStart; |
||
669 | //string zEnd = zNum + length; |
||
670 | |||
671 | if ( enc == SQLITE_UTF16BE ) |
||
672 | zDx++; |
||
673 | while ( zDx < length && sqlite3Isspace( zNum[zDx] ) ) |
||
674 | zDx += incr; |
||
675 | if ( zDx < length ) |
||
676 | { |
||
677 | if ( zNum[zDx] == '-' ) |
||
678 | { |
||
679 | neg = 1; |
||
680 | zDx += incr; |
||
681 | } |
||
682 | else if ( zNum[zDx] == '+' ) |
||
683 | { |
||
684 | zDx += incr; |
||
685 | } |
||
686 | } |
||
687 | //zStart = zNum; |
||
688 | if ( length > zNum.Length ) |
||
689 | length = zNum.Length; |
||
690 | while ( zDx < length - 1 && zNum[zDx] == '0' ) |
||
691 | { |
||
692 | zDx += incr; |
||
693 | } /* Skip leading zeros. */ |
||
694 | for ( i = zDx; i < length && ( c = zNum[i] ) >= '0' && c <= '9'; i += incr ) |
||
695 | { |
||
696 | u = u * 10 + (u64)(c - '0'); |
||
697 | } |
||
698 | if ( u > LARGEST_INT64 ) |
||
699 | { |
||
700 | pNum = SMALLEST_INT64; |
||
701 | } |
||
702 | else if ( neg != 0) |
||
703 | { |
||
704 | pNum = -(i64)u; |
||
705 | } |
||
706 | else |
||
707 | { |
||
708 | pNum = (i64)u; |
||
709 | } |
||
710 | testcase( i - zDx == 18 ); |
||
711 | testcase( i - zDx == 19 ); |
||
712 | testcase( i - zDx == 20 ); |
||
713 | if ( ( c != 0 && i < length ) || i == zDx || i - zDx > 19 * incr ) |
||
714 | { |
||
715 | /* zNum is empty or contains non-numeric text or is longer |
||
716 | ** than 19 digits (thus guaranteeing that it is too large) */ |
||
717 | return 1; |
||
718 | } |
||
719 | else if ( i - zDx < 19 * incr ) |
||
720 | { |
||
721 | /* Less than 19 digits, so we know that it fits in 64 bits */ |
||
722 | Debug.Assert( u <= LARGEST_INT64 ); |
||
723 | return 0; |
||
724 | } |
||
725 | else |
||
726 | { |
||
727 | /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */ |
||
728 | c = compare2pow63( zNum.Substring(zDx), incr ); |
||
729 | if ( c < 0 ) |
||
730 | { |
||
731 | /* zNum is less than 9223372036854775808 so it fits */ |
||
732 | Debug.Assert( u <= LARGEST_INT64 ); |
||
733 | return 0; |
||
734 | } |
||
735 | else if ( c > 0 ) |
||
736 | { |
||
737 | /* zNum is greater than 9223372036854775808 so it overflows */ |
||
738 | return 1; |
||
739 | } |
||
740 | else |
||
741 | { |
||
742 | /* zNum is exactly 9223372036854775808. Fits if negative. The |
||
743 | ** special case 2 overflow if positive */ |
||
744 | Debug.Assert( u - 1 == LARGEST_INT64 ); |
||
745 | Debug.Assert( ( pNum ) == SMALLEST_INT64 ); |
||
746 | return neg != 0 ? 0 : 2; |
||
747 | } |
||
748 | } |
||
749 | } |
||
750 | |||
751 | /* |
||
752 | ** If zNum represents an integer that will fit in 32-bits, then set |
||
753 | ** pValue to that integer and return true. Otherwise return false. |
||
754 | ** |
||
755 | ** Any non-numeric characters that following zNum are ignored. |
||
756 | ** This is different from sqlite3Atoi64() which requires the |
||
757 | ** input number to be zero-terminated. |
||
758 | */ |
||
759 | static bool sqlite3GetInt32( string zNum, ref int pValue ) |
||
760 | { |
||
761 | return sqlite3GetInt32( zNum, 0, ref pValue ); |
||
762 | } |
||
763 | static bool sqlite3GetInt32( string zNum, int iZnum, ref int pValue ) |
||
764 | { |
||
765 | sqlite_int64 v = 0; |
||
766 | int i, c; |
||
767 | int neg = 0; |
||
768 | if ( zNum[iZnum] == '-' ) |
||
769 | { |
||
770 | neg = 1; |
||
771 | iZnum++; |
||
772 | } |
||
773 | else if ( zNum[iZnum] == '+' ) |
||
774 | { |
||
775 | iZnum++; |
||
776 | } |
||
777 | while ( iZnum < zNum.Length && zNum[iZnum] == '0' ) |
||
778 | iZnum++; |
||
779 | for ( i = 0; i < 11 && i + iZnum < zNum.Length && ( c = zNum[iZnum + i] - '0' ) >= 0 && c <= 9; i++ ) |
||
780 | { |
||
781 | v = v * 10 + c; |
||
782 | } |
||
783 | |||
784 | /* The longest decimal representation of a 32 bit integer is 10 digits: |
||
785 | ** |
||
786 | ** 1234567890 |
||
787 | ** 2^31 . 2147483648 |
||
788 | */ |
||
789 | testcase( i == 10 ); |
||
790 | if ( i > 10 ) |
||
791 | { |
||
792 | return false; |
||
793 | } |
||
794 | testcase( v - neg == 2147483647 ); |
||
795 | if ( v - neg > 2147483647 ) |
||
796 | { |
||
797 | return false; |
||
798 | } |
||
799 | if ( neg != 0 ) |
||
800 | { |
||
801 | v = -v; |
||
802 | } |
||
803 | pValue = (int)v; |
||
804 | return true; |
||
805 | } |
||
806 | |||
807 | /* |
||
808 | ** Return a 32-bit integer value extracted from a string. If the |
||
809 | ** string is not an integer, just return 0. |
||
810 | */ |
||
811 | static int sqlite3Atoi( string z ) |
||
812 | { |
||
813 | int x = 0; |
||
814 | if ( !string.IsNullOrEmpty( z ) ) |
||
815 | sqlite3GetInt32( z, ref x ); |
||
816 | return x; |
||
817 | } |
||
818 | |||
819 | /* |
||
820 | ** The variable-length integer encoding is as follows: |
||
821 | ** |
||
822 | ** KEY: |
||
823 | ** A = 0xxxxxxx 7 bits of data and one flag bit |
||
824 | ** B = 1xxxxxxx 7 bits of data and one flag bit |
||
825 | ** C = xxxxxxxx 8 bits of data |
||
826 | ** |
||
827 | ** 7 bits - A |
||
828 | ** 14 bits - BA |
||
829 | ** 21 bits - BBA |
||
830 | ** 28 bits - BBBA |
||
831 | ** 35 bits - BBBBA |
||
832 | ** 42 bits - BBBBBA |
||
833 | ** 49 bits - BBBBBBA |
||
834 | ** 56 bits - BBBBBBBA |
||
835 | ** 64 bits - BBBBBBBBC |
||
836 | */ |
||
837 | |||
838 | /* |
||
839 | ** Write a 64-bit variable-length integer to memory starting at p[0]. |
||
840 | ** The length of data write will be between 1 and 9 bytes. The number |
||
841 | ** of bytes written is returned. |
||
842 | ** |
||
843 | ** A variable-length integer consists of the lower 7 bits of each byte |
||
844 | ** for all bytes that have the 8th bit set and one byte with the 8th |
||
845 | ** bit clear. Except, if we get to the 9th byte, it stores the full |
||
846 | ** 8 bits and is the last byte. |
||
847 | */ |
||
848 | static int getVarint( byte[] p, out u32 v ) |
||
849 | { |
||
850 | v = p[0]; |
||
851 | if ( v <= 0x7F ) |
||
852 | return 1; |
||
853 | u64 u64_v = 0; |
||
854 | int result = sqlite3GetVarint( p, 0, out u64_v ); |
||
855 | v = (u32)u64_v; |
||
856 | return result; |
||
857 | } |
||
858 | static int getVarint( byte[] p, int offset, out u32 v ) |
||
859 | { |
||
860 | v = p[offset + 0]; |
||
861 | if ( v <= 0x7F ) |
||
862 | return 1; |
||
863 | u64 u64_v = 0; |
||
864 | int result = sqlite3GetVarint( p, offset, out u64_v ); |
||
865 | v = (u32)u64_v; |
||
866 | return result; |
||
867 | } |
||
868 | static int getVarint( byte[] p, int offset, out int v ) |
||
869 | { |
||
870 | v = p[offset + 0]; |
||
871 | if ( v <= 0x7F ) |
||
872 | return 1; |
||
873 | u64 u64_v = 0; |
||
874 | int result = sqlite3GetVarint( p, offset, out u64_v ); |
||
875 | v = (int)u64_v; |
||
876 | return result; |
||
877 | } |
||
878 | static int getVarint( byte[] p, int offset, out i64 v ) |
||
879 | { |
||
880 | v = offset >= p.Length ? 0 : (int)p[offset + 0]; |
||
881 | if ( v <= 0x7F ) |
||
882 | return 1; |
||
883 | if ( offset + 1 >= p.Length ) |
||
884 | { |
||
885 | v = 65535; |
||
886 | return 2; |
||
887 | } |
||
888 | else |
||
889 | { |
||
890 | u64 u64_v = 0; |
||
891 | int result = sqlite3GetVarint( p, offset, out u64_v ); |
||
892 | v = (i64)u64_v; |
||
893 | return result; |
||
894 | } |
||
895 | } |
||
896 | static int getVarint( byte[] p, int offset, out u64 v ) |
||
897 | { |
||
898 | v = p[offset + 0]; |
||
899 | if ( v <= 0x7F ) |
||
900 | return 1; |
||
901 | int result = sqlite3GetVarint( p, offset, out v ); |
||
902 | return result; |
||
903 | } |
||
904 | static int getVarint32( byte[] p, out u32 v ) |
||
905 | { //(*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) |
||
906 | v = p[0]; |
||
907 | if ( v <= 0x7F ) |
||
908 | return 1; |
||
909 | return sqlite3GetVarint32( p, 0, out v ); |
||
910 | } |
||
911 | static byte[] pByte4 = new byte[4]; |
||
912 | static int getVarint32( string s, u32 offset, out int v ) |
||
913 | { //(*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) |
||
914 | v = s[(int)offset]; |
||
915 | if ( v <= 0x7F ) |
||
916 | return 1; |
||
917 | pByte4[0] = (u8)s[(int)offset + 0]; |
||
918 | pByte4[1] = (u8)s[(int)offset + 1]; |
||
919 | pByte4[2] = (u8)s[(int)offset + 2]; |
||
920 | pByte4[3] = (u8)s[(int)offset + 3]; |
||
921 | u32 u32_v = 0; |
||
922 | int result = sqlite3GetVarint32( pByte4, 0, out u32_v ); |
||
923 | v = (int)u32_v; |
||
924 | return sqlite3GetVarint32( pByte4, 0, out v ); |
||
925 | } |
||
926 | static int getVarint32( string s, u32 offset, out u32 v ) |
||
927 | { //(*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) |
||
928 | v = s[(int)offset]; |
||
929 | if ( v <= 0x7F ) |
||
930 | return 1; |
||
931 | pByte4[0] = (u8)s[(int)offset + 0]; |
||
932 | pByte4[1] = (u8)s[(int)offset + 1]; |
||
933 | pByte4[2] = (u8)s[(int)offset + 2]; |
||
934 | pByte4[3] = (u8)s[(int)offset + 3]; |
||
935 | return sqlite3GetVarint32( pByte4, 0, out v ); |
||
936 | } |
||
937 | static int getVarint32( byte[] p, u32 offset, out u32 v ) |
||
938 | { //(*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) |
||
939 | v = p[offset]; |
||
940 | if ( v <= 0x7F ) |
||
941 | return 1; |
||
942 | return sqlite3GetVarint32( p, (int)offset, out v ); |
||
943 | } |
||
944 | static int getVarint32( byte[] p, int offset, out u32 v ) |
||
945 | { //(*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) |
||
946 | v = offset >= p.Length ? 0 : (u32)p[offset]; |
||
947 | if ( v <= 0x7F ) |
||
948 | return 1; |
||
949 | return sqlite3GetVarint32( p, offset, out v ); |
||
950 | } |
||
951 | static int getVarint32( byte[] p, int offset, out int v ) |
||
952 | { //(*B=*(A))<=0x7f?1:sqlite3GetVarint32(A,B)) |
||
953 | v = p[offset + 0]; |
||
954 | if ( v <= 0x7F ) |
||
955 | return 1; |
||
956 | u32 u32_v = 0; |
||
957 | int result = sqlite3GetVarint32( p, offset, out u32_v ); |
||
958 | v = (int)u32_v; |
||
959 | return result; |
||
960 | } |
||
961 | static int putVarint( byte[] p, int offset, int v ) |
||
962 | { |
||
963 | return putVarint( p, offset, (u64)v ); |
||
964 | } |
||
965 | static int putVarint( byte[] p, int offset, u64 v ) |
||
966 | { |
||
967 | return sqlite3PutVarint( p, offset, v ); |
||
968 | } |
||
969 | static int sqlite3PutVarint( byte[] p, int offset, int v ) |
||
970 | { |
||
971 | return sqlite3PutVarint( p, offset, (u64)v ); |
||
972 | } |
||
973 | static u8[] bufByte10 = new u8[10]; |
||
974 | static int sqlite3PutVarint( byte[] p, int offset, u64 v ) |
||
975 | { |
||
976 | int i, j, n; |
||
977 | if ( ( v & ( ( (u64)0xff000000 ) << 32 ) ) != 0 ) |
||
978 | { |
||
979 | p[offset + 8] = (byte)v; |
||
980 | v >>= 8; |
||
981 | for ( i = 7; i >= 0; i-- ) |
||
982 | { |
||
983 | p[offset + i] = (byte)( ( v & 0x7f ) | 0x80 ); |
||
984 | v >>= 7; |
||
985 | } |
||
986 | return 9; |
||
987 | } |
||
988 | n = 0; |
||
989 | do |
||
990 | { |
||
991 | bufByte10[n++] = (byte)( ( v & 0x7f ) | 0x80 ); |
||
992 | v >>= 7; |
||
993 | } while ( v != 0 ); |
||
994 | bufByte10[0] &= 0x7f; |
||
995 | Debug.Assert( n <= 9 ); |
||
996 | for ( i = 0, j = n - 1; j >= 0; j--, i++ ) |
||
997 | { |
||
998 | p[offset + i] = bufByte10[j]; |
||
999 | } |
||
1000 | return n; |
||
1001 | } |
||
1002 | |||
1003 | /* |
||
1004 | ** This routine is a faster version of sqlite3PutVarint() that only |
||
1005 | ** works for 32-bit positive integers and which is optimized for |
||
1006 | ** the common case of small integers. |
||
1007 | */ |
||
1008 | static int putVarint32( byte[] p, int offset, int v ) |
||
1009 | { |
||
1010 | #if !putVarint32 |
||
1011 | if ( ( v & ~0x7f ) == 0 ) |
||
1012 | { |
||
1013 | p[offset] = (byte)v; |
||
1014 | return 1; |
||
1015 | } |
||
1016 | #endif |
||
1017 | if ( ( v & ~0x3fff ) == 0 ) |
||
1018 | { |
||
1019 | p[offset] = (byte)( ( v >> 7 ) | 0x80 ); |
||
1020 | p[offset + 1] = (byte)( v & 0x7f ); |
||
1021 | return 2; |
||
1022 | } |
||
1023 | return sqlite3PutVarint( p, offset, v ); |
||
1024 | } |
||
1025 | |||
1026 | static int putVarint32( byte[] p, int v ) |
||
1027 | { |
||
1028 | if ( ( v & ~0x7f ) == 0 ) |
||
1029 | { |
||
1030 | p[0] = (byte)v; |
||
1031 | return 1; |
||
1032 | } |
||
1033 | else if ( ( v & ~0x3fff ) == 0 ) |
||
1034 | { |
||
1035 | p[0] = (byte)( ( v >> 7 ) | 0x80 ); |
||
1036 | p[1] = (byte)( v & 0x7f ); |
||
1037 | return 2; |
||
1038 | } |
||
1039 | else |
||
1040 | { |
||
1041 | return sqlite3PutVarint( p, 0, v ); |
||
1042 | } |
||
1043 | } |
||
1044 | |||
1045 | /* |
||
1046 | ** Bitmasks used by sqlite3GetVarint(). These precomputed constants |
||
1047 | ** are defined here rather than simply putting the constant expressions |
||
1048 | ** inline in order to work around bugs in the RVT compiler. |
||
1049 | ** |
||
1050 | ** SLOT_2_0 A mask for (0x7f<<14) | 0x7f |
||
1051 | ** |
||
1052 | ** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 |
||
1053 | */ |
||
1054 | const int SLOT_2_0 = 0x001fc07f; //#define SLOT_2_0 0x001fc07f |
||
1055 | const u32 SLOT_4_2_0 = (u32)0xf01fc07f; //#define SLOT_4_2_0 0xf01fc07f |
||
1056 | |||
1057 | /* |
||
1058 | ** Read a 64-bit variable-length integer from memory starting at p[0]. |
||
1059 | ** Return the number of bytes read. The value is stored in *v. |
||
1060 | */ |
||
1061 | static u8 sqlite3GetVarint( byte[] p, int offset, out u64 v ) |
||
1062 | { |
||
1063 | u32 a, b, s; |
||
1064 | |||
1065 | a = p[offset + 0]; |
||
1066 | /* a: p0 (unmasked) */ |
||
1067 | if ( 0 == ( a & 0x80 ) ) |
||
1068 | { |
||
1069 | v = a; |
||
1070 | return 1; |
||
1071 | } |
||
1072 | |||
1073 | //p++; |
||
1074 | b = p[offset + 1]; |
||
1075 | /* b: p1 (unmasked) */ |
||
1076 | if ( 0 == ( b & 0x80 ) ) |
||
1077 | { |
||
1078 | a &= 0x7f; |
||
1079 | a = a << 7; |
||
1080 | a |= b; |
||
1081 | v = a; |
||
1082 | return 2; |
||
1083 | } |
||
1084 | |||
1085 | /* Verify that constants are precomputed correctly */ |
||
1086 | Debug.Assert( SLOT_2_0 == ( ( 0x7f << 14 ) | ( 0x7f ) ) ); |
||
1087 | Debug.Assert( SLOT_4_2_0 == ( ( 0xfU << 28 ) | ( 0x7f << 14 ) | ( 0x7f ) ) ); |
||
1088 | //p++; |
||
1089 | a = a << 14; |
||
1090 | a |= p[offset + 2]; |
||
1091 | /* a: p0<<14 | p2 (unmasked) */ |
||
1092 | if ( 0 == ( a & 0x80 ) ) |
||
1093 | { |
||
1094 | a &= SLOT_2_0; |
||
1095 | b &= 0x7f; |
||
1096 | b = b << 7; |
||
1097 | a |= b; |
||
1098 | v = a; |
||
1099 | return 3; |
||
1100 | } |
||
1101 | |||
1102 | /* CSE1 from below */ |
||
1103 | a &= SLOT_2_0; |
||
1104 | //p++; |
||
1105 | b = b << 14; |
||
1106 | b |= p[offset + 3]; |
||
1107 | /* b: p1<<14 | p3 (unmasked) */ |
||
1108 | if ( 0 == ( b & 0x80 ) ) |
||
1109 | { |
||
1110 | b &= SLOT_2_0; |
||
1111 | /* moved CSE1 up */ |
||
1112 | /* a &= (0x7f<<14)|(0x7f); */ |
||
1113 | a = a << 7; |
||
1114 | a |= b; |
||
1115 | v = a; |
||
1116 | return 4; |
||
1117 | } |
||
1118 | |||
1119 | /* a: p0<<14 | p2 (masked) */ |
||
1120 | /* b: p1<<14 | p3 (unmasked) */ |
||
1121 | /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
||
1122 | /* moved CSE1 up */ |
||
1123 | /* a &= (0x7f<<14)|(0x7f); */ |
||
1124 | b &= SLOT_2_0; |
||
1125 | s = a; |
||
1126 | /* s: p0<<14 | p2 (masked) */ |
||
1127 | |||
1128 | //p++; |
||
1129 | a = a << 14; |
||
1130 | a |= p[offset + 4]; |
||
1131 | /* a: p0<<28 | p2<<14 | p4 (unmasked) */ |
||
1132 | if ( 0 == ( a & 0x80 ) ) |
||
1133 | { |
||
1134 | /* we can skip these cause they were (effectively) done above in calc'ing s */ |
||
1135 | /* a &= (0x1f<<28)|(0x7f<<14)|(0x7f); */ |
||
1136 | /* b &= (0x7f<<14)|(0x7f); */ |
||
1137 | b = b << 7; |
||
1138 | a |= b; |
||
1139 | s = s >> 18; |
||
1140 | v = ( (u64)s ) << 32 | a; |
||
1141 | return 5; |
||
1142 | } |
||
1143 | |||
1144 | /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
||
1145 | s = s << 7; |
||
1146 | s |= b; |
||
1147 | /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ |
||
1148 | |||
1149 | //p++; |
||
1150 | b = b << 14; |
||
1151 | b |= p[offset + 5]; |
||
1152 | /* b: p1<<28 | p3<<14 | p5 (unmasked) */ |
||
1153 | if ( 0 == ( b & 0x80 ) ) |
||
1154 | { |
||
1155 | /* we can skip this cause it was (effectively) done above in calc'ing s */ |
||
1156 | /* b &= (0x1f<<28)|(0x7f<<14)|(0x7f); */ |
||
1157 | a &= SLOT_2_0; |
||
1158 | a = a << 7; |
||
1159 | a |= b; |
||
1160 | s = s >> 18; |
||
1161 | v = ( (u64)s ) << 32 | a; |
||
1162 | return 6; |
||
1163 | } |
||
1164 | |||
1165 | //p++; |
||
1166 | a = a << 14; |
||
1167 | a |= p[offset + 6]; |
||
1168 | /* a: p2<<28 | p4<<14 | p6 (unmasked) */ |
||
1169 | if ( 0 == ( a & 0x80 ) ) |
||
1170 | { |
||
1171 | a &= SLOT_4_2_0; |
||
1172 | b &= SLOT_2_0; |
||
1173 | b = b << 7; |
||
1174 | a |= b; |
||
1175 | s = s >> 11; |
||
1176 | v = ( (u64)s ) << 32 | a; |
||
1177 | return 7; |
||
1178 | } |
||
1179 | |||
1180 | /* CSE2 from below */ |
||
1181 | a &= SLOT_2_0; |
||
1182 | //p++; |
||
1183 | b = b << 14; |
||
1184 | b |= p[offset + 7]; |
||
1185 | /* b: p3<<28 | p5<<14 | p7 (unmasked) */ |
||
1186 | if ( 0 == ( b & 0x80 ) ) |
||
1187 | { |
||
1188 | b &= SLOT_4_2_0; |
||
1189 | /* moved CSE2 up */ |
||
1190 | /* a &= (0x7f<<14)|(0x7f); */ |
||
1191 | a = a << 7; |
||
1192 | a |= b; |
||
1193 | s = s >> 4; |
||
1194 | v = ( (u64)s ) << 32 | a; |
||
1195 | return 8; |
||
1196 | } |
||
1197 | |||
1198 | //p++; |
||
1199 | a = a << 15; |
||
1200 | a |= p[offset + 8]; |
||
1201 | /* a: p4<<29 | p6<<15 | p8 (unmasked) */ |
||
1202 | |||
1203 | /* moved CSE2 up */ |
||
1204 | /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ |
||
1205 | b &= SLOT_2_0; |
||
1206 | b = b << 8; |
||
1207 | a |= b; |
||
1208 | |||
1209 | s = s << 4; |
||
1210 | b = p[offset + 4]; |
||
1211 | b &= 0x7f; |
||
1212 | b = b >> 3; |
||
1213 | s |= b; |
||
1214 | |||
1215 | v = ( (u64)s ) << 32 | a; |
||
1216 | |||
1217 | return 9; |
||
1218 | } |
||
1219 | |||
1220 | |||
1221 | /* |
||
1222 | ** Read a 32-bit variable-length integer from memory starting at p[0]. |
||
1223 | ** Return the number of bytes read. The value is stored in *v. |
||
1224 | ** |
||
1225 | ** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned |
||
1226 | ** integer, then set *v to 0xffffffff. |
||
1227 | ** |
||
1228 | ** A MACRO version, getVarint32, is provided which inlines the |
||
1229 | ** single-byte case. All code should use the MACRO version as |
||
1230 | ** this function assumes the single-byte case has already been handled. |
||
1231 | */ |
||
1232 | static u8 sqlite3GetVarint32( byte[] p, out int v ) |
||
1233 | { |
||
1234 | u32 u32_v = 0; |
||
1235 | u8 result = sqlite3GetVarint32( p, 0, out u32_v ); |
||
1236 | v = (int)u32_v; |
||
1237 | return result; |
||
1238 | } |
||
1239 | static u8 sqlite3GetVarint32( byte[] p, int offset, out int v ) |
||
1240 | { |
||
1241 | u32 u32_v = 0; |
||
1242 | u8 result = sqlite3GetVarint32( p, offset, out u32_v ); |
||
1243 | v = (int)u32_v; |
||
1244 | return result; |
||
1245 | } |
||
1246 | static u8 sqlite3GetVarint32( byte[] p, out u32 v ) |
||
1247 | { |
||
1248 | return sqlite3GetVarint32( p, 0, out v ); |
||
1249 | } |
||
1250 | static u8 sqlite3GetVarint32( byte[] p, int offset, out u32 v ) |
||
1251 | { |
||
1252 | u32 a, b; |
||
1253 | |||
1254 | /* The 1-byte case. Overwhelmingly the most common. Handled inline |
||
1255 | ** by the getVarin32() macro */ |
||
1256 | a = p[offset + 0]; |
||
1257 | /* a: p0 (unmasked) */ |
||
1258 | //#if getVarint32 |
||
1259 | // if ( 0==( a&0x80)) |
||
1260 | // { |
||
1261 | /* Values between 0 and 127 */ |
||
1262 | // v = a; |
||
1263 | // return 1; |
||
1264 | // } |
||
1265 | //#endif |
||
1266 | |||
1267 | /* The 2-byte case */ |
||
1268 | //p++; |
||
1269 | b = ( offset + 1 ) < p.Length ? p[offset + 1] : (u32)0; |
||
1270 | /* b: p1 (unmasked) */ |
||
1271 | if ( 0 == ( b & 0x80 ) ) |
||
1272 | { |
||
1273 | /* Values between 128 and 16383 */ |
||
1274 | a &= 0x7f; |
||
1275 | a = a << 7; |
||
1276 | v = a | b; |
||
1277 | return 2; |
||
1278 | } |
||
1279 | |||
1280 | /* The 3-byte case */ |
||
1281 | //p++; |
||
1282 | a = a << 14; |
||
1283 | a |= ( offset + 2 ) < p.Length ? p[offset + 2] : (u32)0; |
||
1284 | /* a: p0<<14 | p2 (unmasked) */ |
||
1285 | if ( 0 == ( a & 0x80 ) ) |
||
1286 | { |
||
1287 | /* Values between 16384 and 2097151 */ |
||
1288 | a &= ( 0x7f << 14 ) | ( 0x7f ); |
||
1289 | b &= 0x7f; |
||
1290 | b = b << 7; |
||
1291 | v = a | b; |
||
1292 | return 3; |
||
1293 | } |
||
1294 | |||
1295 | /* A 32-bit varint is used to store size information in btrees. |
||
1296 | ** Objects are rarely larger than 2MiB limit of a 3-byte varint. |
||
1297 | ** A 3-byte varint is sufficient, for example, to record the size |
||
1298 | ** of a 1048569-byte BLOB or string. |
||
1299 | ** |
||
1300 | ** We only unroll the first 1-, 2-, and 3- byte cases. The very |
||
1301 | ** rare larger cases can be handled by the slower 64-bit varint |
||
1302 | ** routine. |
||
1303 | */ |
||
1304 | #if TRUE |
||
1305 | { |
||
1306 | u64 v64 = 0; |
||
1307 | u8 n; |
||
1308 | |||
1309 | //p -= 2; |
||
1310 | n = sqlite3GetVarint( p, offset, out v64 ); |
||
1311 | Debug.Assert( n > 3 && n <= 9 ); |
||
1312 | if ( ( v64 & SQLITE_MAX_U32 ) != v64 ) |
||
1313 | { |
||
1314 | v = 0xffffffff; |
||
1315 | } |
||
1316 | else |
||
1317 | { |
||
1318 | v = (u32)v64; |
||
1319 | } |
||
1320 | return n; |
||
1321 | } |
||
1322 | #else |
||
1323 | /* For following code (kept for historical record only) shows an |
||
1324 | ** unrolling for the 3- and 4-byte varint cases. This code is |
||
1325 | ** slightly faster, but it is also larger and much harder to test. |
||
1326 | */ |
||
1327 | //p++; |
||
1328 | b = b << 14; |
||
1329 | b |= p[offset + 3]; |
||
1330 | /* b: p1<<14 | p3 (unmasked) */ |
||
1331 | if ( 0 == ( b & 0x80 ) ) |
||
1332 | { |
||
1333 | /* Values between 2097152 and 268435455 */ |
||
1334 | b &= ( 0x7f << 14 ) | ( 0x7f ); |
||
1335 | a &= ( 0x7f << 14 ) | ( 0x7f ); |
||
1336 | a = a << 7; |
||
1337 | v = a | b; |
||
1338 | return 4; |
||
1339 | } |
||
1340 | |||
1341 | //p++; |
||
1342 | a = a << 14; |
||
1343 | a |= p[offset + 4]; |
||
1344 | /* a: p0<<28 | p2<<14 | p4 (unmasked) */ |
||
1345 | if ( 0 == ( a & 0x80 ) ) |
||
1346 | { |
||
1347 | /* Values between 268435456 and 34359738367 */ |
||
1348 | a &= SLOT_2_0; |
||
1349 | b &= SLOT_4_2_0; |
||
1350 | b = b << 7; |
||
1351 | v = a | b; |
||
1352 | return 5; |
||
1353 | } |
||
1354 | |||
1355 | /* We can only reach this point when reading a corrupt database |
||
1356 | ** file. In that case we are not in any hurry. Use the (relatively |
||
1357 | ** slow) general-purpose sqlite3GetVarint() routine to extract the |
||
1358 | ** value. */ |
||
1359 | { |
||
1360 | u64 v64 = 0; |
||
1361 | int n; |
||
1362 | |||
1363 | //p -= 4; |
||
1364 | n = sqlite3GetVarint( p, offset, out v64 ); |
||
1365 | Debug.Assert( n > 5 && n <= 9 ); |
||
1366 | v = (u32)v64; |
||
1367 | return n; |
||
1368 | } |
||
1369 | #endif |
||
1370 | } |
||
1371 | |||
1372 | |||
1373 | /* |
||
1374 | ** Return the number of bytes that will be needed to store the given |
||
1375 | ** 64-bit integer. |
||
1376 | */ |
||
1377 | static int sqlite3VarintLen( u64 v ) |
||
1378 | { |
||
1379 | int i = 0; |
||
1380 | do |
||
1381 | { |
||
1382 | i++; |
||
1383 | v >>= 7; |
||
1384 | } while ( v != 0 && ALWAYS( i < 9 ) ); |
||
1385 | return i; |
||
1386 | } |
||
1387 | |||
1388 | |||
1389 | /* |
||
1390 | ** Read or write a four-byte big-endian integer value. |
||
1391 | */ |
||
1392 | static u32 sqlite3Get4byte( u8[] p, int p_offset, int offset ) |
||
1393 | { |
||
1394 | offset += p_offset; |
||
1395 | return ( offset + 3 > p.Length ) ? 0 : (u32)( ( p[0 + offset] << 24 ) | ( p[1 + offset] << 16 ) | ( p[2 + offset] << 8 ) | p[3 + offset] ); |
||
1396 | } |
||
1397 | static u32 sqlite3Get4byte( u8[] p, int offset ) |
||
1398 | { |
||
1399 | return ( offset + 3 > p.Length ) ? 0 : (u32)( ( p[0 + offset] << 24 ) | ( p[1 + offset] << 16 ) | ( p[2 + offset] << 8 ) | p[3 + offset] ); |
||
1400 | } |
||
1401 | static u32 sqlite3Get4byte( u8[] p, u32 offset ) |
||
1402 | { |
||
1403 | return ( offset + 3 > p.Length ) ? 0 : (u32)( ( p[0 + offset] << 24 ) | ( p[1 + offset] << 16 ) | ( p[2 + offset] << 8 ) | p[3 + offset] ); |
||
1404 | } |
||
1405 | static u32 sqlite3Get4byte( u8[] p ) |
||
1406 | { |
||
1407 | return (u32)( ( p[0] << 24 ) | ( p[1] << 16 ) | ( p[2] << 8 ) | p[3] ); |
||
1408 | } |
||
1409 | static void sqlite3Put4byte( byte[] p, int v ) |
||
1410 | { |
||
1411 | p[0] = (byte)( v >> 24 & 0xFF ); |
||
1412 | p[1] = (byte)( v >> 16 & 0xFF ); |
||
1413 | p[2] = (byte)( v >> 8 & 0xFF ); |
||
1414 | p[3] = (byte)( v & 0xFF ); |
||
1415 | } |
||
1416 | static void sqlite3Put4byte( byte[] p, int offset, int v ) |
||
1417 | { |
||
1418 | p[0 + offset] = (byte)( v >> 24 & 0xFF ); |
||
1419 | p[1 + offset] = (byte)( v >> 16 & 0xFF ); |
||
1420 | p[2 + offset] = (byte)( v >> 8 & 0xFF ); |
||
1421 | p[3 + offset] = (byte)( v & 0xFF ); |
||
1422 | } |
||
1423 | static void sqlite3Put4byte( byte[] p, u32 offset, u32 v ) |
||
1424 | { |
||
1425 | p[0 + offset] = (byte)( v >> 24 & 0xFF ); |
||
1426 | p[1 + offset] = (byte)( v >> 16 & 0xFF ); |
||
1427 | p[2 + offset] = (byte)( v >> 8 & 0xFF ); |
||
1428 | p[3 + offset] = (byte)( v & 0xFF ); |
||
1429 | } |
||
1430 | static void sqlite3Put4byte( byte[] p, int offset, u64 v ) |
||
1431 | { |
||
1432 | p[0 + offset] = (byte)( v >> 24 & 0xFF ); |
||
1433 | p[1 + offset] = (byte)( v >> 16 & 0xFF ); |
||
1434 | p[2 + offset] = (byte)( v >> 8 & 0xFF ); |
||
1435 | p[3 + offset] = (byte)( v & 0xFF ); |
||
1436 | } |
||
1437 | static void sqlite3Put4byte( byte[] p, u64 v ) |
||
1438 | { |
||
1439 | p[0] = (byte)( v >> 24 & 0xFF ); |
||
1440 | p[1] = (byte)( v >> 16 & 0xFF ); |
||
1441 | p[2] = (byte)( v >> 8 & 0xFF ); |
||
1442 | p[3] = (byte)( v & 0xFF ); |
||
1443 | } |
||
1444 | |||
1445 | |||
1446 | |||
1447 | /* |
||
1448 | ** Translate a single byte of Hex into an integer. |
||
1449 | ** This routine only works if h really is a valid hexadecimal |
||
1450 | ** character: 0..9a..fA..F |
||
1451 | */ |
||
1452 | static int sqlite3HexToInt( int h ) |
||
1453 | { |
||
1454 | Debug.Assert( ( h >= '0' && h <= '9' ) || ( h >= 'a' && h <= 'f' ) || ( h >= 'A' && h <= 'F' ) ); |
||
1455 | #if SQLITE_ASCII |
||
1456 | h += 9 * ( 1 & ( h >> 6 ) ); |
||
1457 | #endif |
||
1458 | //#if SQLITE_EBCDIC |
||
1459 | //h += 9*(1&~(h>>4)); |
||
1460 | //#endif |
||
1461 | return h & 0xf; |
||
1462 | } |
||
1463 | |||
1464 | #if !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC |
||
1465 | /* |
||
1466 | ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary |
||
1467 | ** value. Return a pointer to its binary value. Space to hold the |
||
1468 | ** binary value has been obtained from malloc and must be freed by |
||
1469 | ** the calling routine. |
||
1470 | */ |
||
1471 | static byte[] sqlite3HexToBlob( sqlite3 db, string z, int n ) |
||
1472 | { |
||
1473 | StringBuilder zBlob; |
||
1474 | int i; |
||
1475 | |||
1476 | zBlob = new StringBuilder( n / 2 + 1 );// (char)sqlite3DbMallocRaw(db, n / 2 + 1); |
||
1477 | n--; |
||
1478 | if ( zBlob != null ) |
||
1479 | { |
||
1480 | for ( i = 0; i < n; i += 2 ) |
||
1481 | { |
||
1482 | zBlob.Append( Convert.ToChar( ( sqlite3HexToInt( z[i] ) << 4 ) | sqlite3HexToInt( z[i + 1] ) ) ); |
||
1483 | } |
||
1484 | //zBlob[i / 2] = '\0'; ; |
||
1485 | } |
||
1486 | return Encoding.UTF8.GetBytes( zBlob.ToString() ); |
||
1487 | } |
||
1488 | #endif // * !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ |
||
1489 | |||
1490 | |||
1491 | /* |
||
1492 | ** Log an error that is an API call on a connection pointer that should |
||
1493 | ** not have been used. The "type" of connection pointer is given as the |
||
1494 | ** argument. The zType is a word like "NULL" or "closed" or "invalid". |
||
1495 | */ |
||
1496 | static void logBadConnection( string zType ) |
||
1497 | { |
||
1498 | sqlite3_log( SQLITE_MISUSE, |
||
1499 | "API call with %s database connection pointer", |
||
1500 | zType |
||
1501 | ); |
||
1502 | } |
||
1503 | |||
1504 | /* |
||
1505 | ** Check to make sure we have a valid db pointer. This test is not |
||
1506 | ** foolproof but it does provide some measure of protection against |
||
1507 | ** misuse of the interface such as passing in db pointers that are |
||
1508 | ** NULL or which have been previously closed. If this routine returns |
||
1509 | ** 1 it means that the db pointer is valid and 0 if it should not be |
||
1510 | ** dereferenced for any reason. The calling function should invoke |
||
1511 | ** SQLITE_MISUSE immediately. |
||
1512 | ** |
||
1513 | ** sqlite3SafetyCheckOk() requires that the db pointer be valid for |
||
1514 | ** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to |
||
1515 | ** open properly and is not fit for general use but which can be |
||
1516 | ** used as an argument to sqlite3_errmsg() or sqlite3_close(). |
||
1517 | */ |
||
1518 | static bool sqlite3SafetyCheckOk( sqlite3 db ) |
||
1519 | { |
||
1520 | u32 magic; |
||
1521 | if ( db == null ) |
||
1522 | { |
||
1523 | logBadConnection( "NULL" ); |
||
1524 | return false; |
||
1525 | } |
||
1526 | magic = db.magic; |
||
1527 | if ( magic != SQLITE_MAGIC_OPEN ) |
||
1528 | { |
||
1529 | if ( sqlite3SafetyCheckSickOrOk( db ) ) |
||
1530 | { |
||
1531 | testcase( sqlite3GlobalConfig.xLog != null ); |
||
1532 | logBadConnection( "unopened" ); |
||
1533 | } |
||
1534 | return false; |
||
1535 | } |
||
1536 | else |
||
1537 | { |
||
1538 | return true; |
||
1539 | } |
||
1540 | } |
||
1541 | static bool sqlite3SafetyCheckSickOrOk( sqlite3 db ) |
||
1542 | { |
||
1543 | u32 magic; |
||
1544 | magic = db.magic; |
||
1545 | if ( magic != SQLITE_MAGIC_SICK && |
||
1546 | magic != SQLITE_MAGIC_OPEN && |
||
1547 | magic != SQLITE_MAGIC_BUSY ) |
||
1548 | { |
||
1549 | testcase( sqlite3GlobalConfig.xLog != null ); |
||
1550 | logBadConnection( "invalid" ); |
||
1551 | return false; |
||
1552 | } |
||
1553 | else |
||
1554 | { |
||
1555 | return true; |
||
1556 | } |
||
1557 | } |
||
1558 | |||
1559 | /* |
||
1560 | ** Attempt to add, substract, or multiply the 64-bit signed value iB against |
||
1561 | ** the other 64-bit signed integer at *pA and store the result in *pA. |
||
1562 | ** Return 0 on success. Or if the operation would have resulted in an |
||
1563 | ** overflow, leave *pA unchanged and return 1. |
||
1564 | */ |
||
1565 | static int sqlite3AddInt64( ref i64 pA, i64 iB ) |
||
1566 | { |
||
1567 | i64 iA = pA; |
||
1568 | testcase( iA == 0 ); |
||
1569 | testcase( iA == 1 ); |
||
1570 | testcase( iB == -1 ); |
||
1571 | testcase( iB == 0 ); |
||
1572 | if ( iB >= 0 ) |
||
1573 | { |
||
1574 | testcase( iA > 0 && LARGEST_INT64 - iA == iB ); |
||
1575 | testcase( iA > 0 && LARGEST_INT64 - iA == iB - 1 ); |
||
1576 | if ( iA > 0 && LARGEST_INT64 - iA < iB ) |
||
1577 | return 1; |
||
1578 | pA += iB; |
||
1579 | } |
||
1580 | else |
||
1581 | { |
||
1582 | testcase( iA < 0 && -( iA + LARGEST_INT64 ) == iB + 1 ); |
||
1583 | testcase( iA < 0 && -( iA + LARGEST_INT64 ) == iB + 2 ); |
||
1584 | if ( iA < 0 && -( iA + LARGEST_INT64 ) > iB + 1 ) |
||
1585 | return 1; |
||
1586 | pA += iB; |
||
1587 | } |
||
1588 | return 0; |
||
1589 | } |
||
1590 | static int sqlite3SubInt64( ref i64 pA, i64 iB ) |
||
1591 | { |
||
1592 | testcase( iB == SMALLEST_INT64 + 1 ); |
||
1593 | if ( iB == SMALLEST_INT64 ) |
||
1594 | { |
||
1595 | testcase( ( pA ) == ( -1 ) ); |
||
1596 | testcase( ( pA ) == 0 ); |
||
1597 | if ( ( pA ) >= 0 ) |
||
1598 | return 1; |
||
1599 | pA -= iB; |
||
1600 | return 0; |
||
1601 | } |
||
1602 | else |
||
1603 | { |
||
1604 | return sqlite3AddInt64( ref pA, -iB ); |
||
1605 | } |
||
1606 | } |
||
1607 | //#define TWOPOWER32 (((i64)1)<<32) |
||
1608 | const i64 TWOPOWER32 = ( ( (i64)1 ) << 32 ); |
||
1609 | //#define TWOPOWER31 (((i64)1)<<31) |
||
1610 | const i64 TWOPOWER31 = ( ( (i64)1 ) << 31 ); |
||
1611 | |||
1612 | static int sqlite3MulInt64( ref i64 pA, i64 iB ) |
||
1613 | { |
||
1614 | i64 iA = pA; |
||
1615 | i64 iA1, iA0, iB1, iB0, r; |
||
1616 | |||
1617 | iA1 = iA / TWOPOWER32; |
||
1618 | iA0 = iA % TWOPOWER32; |
||
1619 | iB1 = iB / TWOPOWER32; |
||
1620 | iB0 = iB % TWOPOWER32; |
||
1621 | if ( iA1 * iB1 != 0 ) |
||
1622 | return 1; |
||
1623 | Debug.Assert( iA1 * iB0 == 0 || iA0 * iB1 == 0 ); |
||
1624 | r = iA1 * iB0 + iA0 * iB1; |
||
1625 | testcase( r == ( -TWOPOWER31 ) - 1 ); |
||
1626 | testcase( r == ( -TWOPOWER31 ) ); |
||
1627 | testcase( r == TWOPOWER31 ); |
||
1628 | testcase( r == TWOPOWER31 - 1 ); |
||
1629 | if ( r < ( -TWOPOWER31 ) || r >= TWOPOWER31 ) |
||
1630 | return 1; |
||
1631 | r *= TWOPOWER32; |
||
1632 | if ( sqlite3AddInt64( ref r, iA0 * iB0 ) != 0) |
||
1633 | return 1; |
||
1634 | pA = r; |
||
1635 | return 0; |
||
1636 | } |
||
1637 | |||
1638 | /* |
||
1639 | ** Compute the absolute value of a 32-bit signed integer, if possible. Or |
||
1640 | ** if the integer has a value of -2147483648, return +2147483647 |
||
1641 | */ |
||
1642 | static int sqlite3AbsInt32( int x ) |
||
1643 | { |
||
1644 | if ( x >= 0 ) |
||
1645 | return x; |
||
1646 | if ( x == -2147483648) // 0x80000000 |
||
1647 | return 0x7fffffff; |
||
1648 | return -x; |
||
1649 | } |
||
1650 | |||
1651 | #if SQLITE_ENABLE_8_3_NAMES |
||
1652 | /* |
||
1653 | ** If SQLITE_ENABLE_8_3_NAME is set at compile-time and if the database |
||
1654 | ** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and |
||
1655 | ** if filename in z[] has a suffix (a.k.a. "extension") that is longer than |
||
1656 | ** three characters, then shorten the suffix on z[] to be the last three |
||
1657 | ** characters of the original suffix. |
||
1658 | ** |
||
1659 | ** Examples: |
||
1660 | ** |
||
1661 | ** test.db-journal => test.nal |
||
1662 | ** test.db-wal => test.wal |
||
1663 | ** test.db-shm => test.shm |
||
1664 | */ |
||
1665 | static void sqlite3FileSuffix3(string zBaseFilename, string z){ |
||
1666 | string zOk; |
||
1667 | zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names"); |
||
1668 | if( zOk != null && sqlite3GetBoolean(zOk) ){ |
||
1669 | int i, sz; |
||
1670 | sz = sqlite3Strlen30(z); |
||
1671 | for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} |
||
1672 | if( z[i]=='.' && ALWAYS(sz>i+4) ) memcpy(&z[i+1], &z[sz-3], 4); |
||
1673 | } |
||
1674 | } |
||
1675 | #endif |
||
1676 | |||
1677 | } |
||
1678 | } |