wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 *************************************************************************
3 ** Custom classes used by C#
4 *************************************************************************
5 */
6 using System;
7 using System.Diagnostics;
8 using System.IO;
9 #if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE)
10 using System.Management;
11 #endif
12 using System.Text;
13 using System.Text.RegularExpressions;
14 using System.Threading;
15  
16 using i64 = System.Int64;
17  
18 using u32 = System.UInt32;
19 using time_t = System.Int64;
20  
21 namespace Community.CsharpSqlite
22 {
23 using sqlite3_value = Sqlite3.Mem;
24  
25 public partial class Sqlite3
26 {
27  
28 static int atoi( byte[] inStr )
29 {
30 return atoi( Encoding.UTF8.GetString( inStr, 0, inStr.Length ) );
31 }
32  
33 static int atoi( string inStr )
34 {
35 int i;
36 for ( i = 0; i < inStr.Length; i++ )
37 {
38 if ( !sqlite3Isdigit( inStr[i] ) && inStr[i] != '-' )
39 break;
40 }
41 int result = 0;
42 #if WINDOWS_MOBILE
43 try { result = Int32.Parse(inStr.Substring(0, i)); }
44 catch { }
45 return result;
46 #else
47 return ( Int32.TryParse( inStr.Substring( 0, i ), out result ) ? result : 0 );
48 #endif
49 }
50  
51 static void fprintf( TextWriter tw, string zFormat, params object[] ap )
52 {
53 tw.Write( sqlite3_mprintf( zFormat, ap ) );
54 }
55 static void printf( string zFormat, params object[] ap )
56 {
57 Console.Out.Write( sqlite3_mprintf( zFormat, ap ) );
58 }
59  
60  
61 //Byte Buffer Testing
62 static int memcmp( byte[] bA, byte[] bB, int Limit )
63 {
64 if ( bA.Length < Limit )
65 return ( bA.Length < bB.Length ) ? -1 : +1;
66 if ( bB.Length < Limit )
67 return +1;
68 for ( int i = 0; i < Limit; i++ )
69 {
70 if ( bA[i] != bB[i] )
71 return ( bA[i] < bB[i] ) ? -1 : 1;
72 }
73 return 0;
74 }
75  
76 //Byte Buffer & String Testing
77 static int memcmp( string A, byte[] bB, int Limit )
78 {
79 if ( A.Length < Limit )
80 return ( A.Length < bB.Length ) ? -1 : +1;
81 if ( bB.Length < Limit )
82 return +1;
83 char[] cA = A.ToCharArray();
84 for ( int i = 0; i < Limit; i++ )
85 {
86 if ( cA[i] != bB[i] )
87 return ( cA[i] < bB[i] ) ? -1 : 1;
88 }
89 return 0;
90 }
91  
92 //byte with Offset & String Testing
93 static int memcmp( byte[] a, int Offset, byte[] b, int Limit )
94 {
95 if ( a.Length < Offset + Limit )
96 return ( a.Length - Offset < b.Length ) ? -1 : +1;
97 if ( b.Length < Limit )
98 return +1;
99 for ( int i = 0; i < Limit; i++ )
100 {
101 if ( a[i + Offset] != b[i] )
102 return ( a[i + Offset] < b[i] ) ? -1 : 1;
103 }
104 return 0;
105 }
106  
107 //byte with Offset & String Testing
108 static int memcmp( byte[] a, int Aoffset, byte[] b, int Boffset, int Limit )
109 {
110 if ( a.Length < Aoffset + Limit )
111 return ( a.Length - Aoffset < b.Length - Boffset ) ? -1 : +1;
112 if ( b.Length < Boffset + Limit )
113 return +1;
114 for ( int i = 0; i < Limit; i++ )
115 {
116 if ( a[i + Aoffset] != b[i + Boffset] )
117 return ( a[i + Aoffset] < b[i + Boffset] ) ? -1 : 1;
118 }
119 return 0;
120 }
121  
122 static int memcmp( byte[] a, int Offset, string b, int Limit )
123 {
124 if ( a.Length < Offset + Limit )
125 return ( a.Length - Offset < b.Length ) ? -1 : +1;
126 if ( b.Length < Limit )
127 return +1;
128 for ( int i = 0; i < Limit; i++ )
129 {
130 if ( a[i + Offset] != b[i] )
131 return ( a[i + Offset] < b[i] ) ? -1 : 1;
132 }
133 return 0;
134 }
135 //String Testing
136 static int memcmp( string A, string B, int Limit )
137 {
138 if ( A.Length < Limit )
139 return ( A.Length < B.Length ) ? -1 : +1;
140 if ( B.Length < Limit )
141 return +1;
142 int rc;
143 if ( ( rc = String.Compare( A, 0, B, 0, Limit, StringComparison.Ordinal ) ) == 0 )
144 return 0;
145 return rc < 0 ? -1 : +1;
146 }
147  
148  
149 // ----------------------------
150 // ** Builtin Functions
151 // ----------------------------
152  
153  
154 static Regex oRegex = null;
155 /*
156 ** The regexp() function. two arguments are both strings
157 ** Collating sequences are not used.
158 */
159 static void regexpFunc(
160 sqlite3_context context,
161 int argc,
162 sqlite3_value[] argv
163 )
164 {
165 string zTest; /* The input string A */
166 string zRegex; /* The regex string B */
167  
168 Debug.Assert( argc == 2 );
169 UNUSED_PARAMETER( argc );
170 zRegex = sqlite3_value_text( argv[0] );
171 zTest = sqlite3_value_text( argv[1] );
172  
173 if ( zTest == null || string.IsNullOrEmpty( zRegex ) )
174 {
175 sqlite3_result_int( context, 0 );
176 return;
177 }
178  
179 if ( oRegex == null || oRegex.ToString() == zRegex )
180 {
181 oRegex = new Regex( zRegex, RegexOptions.IgnoreCase );
182 }
183 sqlite3_result_int( context, oRegex.IsMatch( zTest ) ? 1 : 0 );
184 }
185  
186  
187 // ----------------------------
188 // ** Convertion routines
189 // ----------------------------
190 static Object lock_va_list = new Object();
191  
192 static string vaFORMAT;
193 static int vaNEXT;
194  
195 static void va_start( object[] ap, string zFormat )
196 {
197 vaFORMAT = zFormat;
198 vaNEXT = 0;
199 }
200  
201 static Boolean va_arg( object[] ap, Boolean sysType )
202 {
203 return Convert.ToBoolean( ap[vaNEXT++] );
204 }
205  
206 static Byte[] va_arg( object[] ap, Byte[] sysType )
207 {
208 return (Byte[])ap[vaNEXT++];
209 }
210  
211 static Byte[][] va_arg( object[] ap, Byte[][] sysType )
212 {
213 if ( ap[vaNEXT] == null )
214 {
215 {
216 vaNEXT++;
217 return null;
218 }
219 }
220 else
221 {
222 return (Byte[][])ap[vaNEXT++];
223 }
224 }
225  
226 static Char va_arg( object[] ap, Char sysType )
227 {
228 if ( ap[vaNEXT] is Int32 && (int)ap[vaNEXT] == 0 )
229 {
230 vaNEXT++;
231 return (char)'0';
232 }
233 else
234 {
235 if ( ap[vaNEXT] is Int64 )
236 if ( (i64)ap[vaNEXT] == 0 )
237 {
238 vaNEXT++;
239 return (char)'0';
240 }
241 else
242 return (char)( (i64)ap[vaNEXT++] );
243 else
244 return (char)ap[vaNEXT++];
245 }
246  
247 }
248  
249 static Double va_arg( object[] ap, Double sysType )
250 {
251 return Convert.ToDouble( ap[vaNEXT++] );
252 }
253  
254 static dxLog va_arg( object[] ap, dxLog sysType )
255 {
256 return (dxLog)ap[vaNEXT++];
257 }
258  
259 static Int64 va_arg( object[] ap, Int64 sysType )
260 {
261 if ( ap[vaNEXT] is System.Int64)
262 return Convert.ToInt64( ap[vaNEXT++] );
263 else
264 return (Int64)( ap[vaNEXT++].GetHashCode() );
265 }
266  
267 static Int32 va_arg( object[] ap, Int32 sysType )
268 {
269 if ( Convert.ToInt64( ap[vaNEXT] ) > 0 && ( Convert.ToUInt32( ap[vaNEXT] ) > Int32.MaxValue ) )
270 return (Int32)( Convert.ToUInt32( ap[vaNEXT++] ) - System.UInt32.MaxValue - 1 );
271 else
272 return (Int32)Convert.ToInt32( ap[vaNEXT++] );
273 }
274  
275 static Int32[] va_arg( object[] ap, Int32[] sysType )
276 {
277 if ( ap[vaNEXT] == null )
278 {
279 {
280 vaNEXT++;
281 return null;
282 }
283 }
284 else
285 {
286 return (Int32[])ap[vaNEXT++];
287 }
288 }
289  
290 static MemPage va_arg( object[] ap, MemPage sysType )
291 {
292 return (MemPage)ap[vaNEXT++];
293 }
294  
295 static Object va_arg( object[] ap, Object sysType )
296 {
297 return (Object)ap[vaNEXT++];
298 }
299  
300 static sqlite3 va_arg( object[] ap, sqlite3 sysType )
301 {
302 return (sqlite3)ap[vaNEXT++];
303 }
304  
305 static sqlite3_mem_methods va_arg( object[] ap, sqlite3_mem_methods sysType )
306 {
307 return (sqlite3_mem_methods)ap[vaNEXT++];
308 }
309  
310 static sqlite3_mutex_methods va_arg( object[] ap, sqlite3_mutex_methods sysType )
311 {
312 return (sqlite3_mutex_methods)ap[vaNEXT++];
313 }
314  
315 static SrcList va_arg( object[] ap, SrcList sysType )
316 {
317 return (SrcList)ap[vaNEXT++];
318 }
319  
320 static String va_arg( object[] ap, String sysType )
321 {
322 if ( ap.Length < vaNEXT - 1 || ap[vaNEXT] == null )
323 {
324 vaNEXT++;
325 return "NULL";
326 }
327 else
328 {
329 if ( ap[vaNEXT] is Byte[] )
330 if ( Encoding.UTF8.GetString( (byte[])ap[vaNEXT], 0, ( (byte[])ap[vaNEXT] ).Length ) == "\0" )
331 {
332 vaNEXT++;
333 return string.Empty;
334 }
335 else
336 return Encoding.UTF8.GetString( (byte[])ap[vaNEXT], 0, ( (byte[])ap[vaNEXT++] ).Length );
337 else if ( ap[vaNEXT] is Int32 )
338 {
339 vaNEXT++;
340 return null;
341 }
342 else if ( ap[vaNEXT] is StringBuilder )
343 return (String)ap[vaNEXT++].ToString();
344 else if ( ap[vaNEXT] is Char )
345 return ( (Char)ap[vaNEXT++] ).ToString();
346 else
347 return (String)ap[vaNEXT++];
348 }
349 }
350  
351 static Token va_arg( object[] ap, Token sysType )
352 {
353 return (Token)ap[vaNEXT++];
354 }
355  
356 static UInt32 va_arg( object[] ap, UInt32 sysType )
357 {
358 if ( ap[vaNEXT].GetType().IsClass )
359 {
360 return (UInt32)ap[vaNEXT++].GetHashCode();
361 }
362 else
363 {
364 return (UInt32)Convert.ToUInt32( ap[vaNEXT++] );
365 }
366 }
367  
368 static UInt64 va_arg( object[] ap, UInt64 sysType )
369 {
370 if ( ap[vaNEXT].GetType().IsClass )
371 {
372 return (UInt64)ap[vaNEXT++].GetHashCode();
373 }
374 else
375 {
376 return (UInt64)Convert.ToUInt64( ap[vaNEXT++] );
377 }
378 }
379  
380 static void_function va_arg( object[] ap, void_function sysType )
381 {
382 return (void_function)ap[vaNEXT++];
383 }
384  
385  
386 static void va_end( ref string[] ap )
387 {
388 ap = null;
389 vaNEXT = -1;
390 vaFORMAT = string.Empty;
391 }
392 static void va_end( ref object[] ap )
393 {
394 ap = null;
395 vaNEXT = -1;
396 vaFORMAT = string.Empty;
397 }
398  
399  
400 public static tm localtime( time_t baseTime )
401 {
402 System.DateTime RefTime = new System.DateTime( 1970, 1, 1, 0, 0, 0, 0 );
403 RefTime = RefTime.AddSeconds( Convert.ToDouble( baseTime ) ).ToLocalTime();
404 tm tm = new tm();
405 tm.tm_sec = RefTime.Second;
406 tm.tm_min = RefTime.Minute;
407 tm.tm_hour = RefTime.Hour;
408 tm.tm_mday = RefTime.Day;
409 tm.tm_mon = RefTime.Month;
410 tm.tm_year = RefTime.Year;
411 tm.tm_wday = (int)RefTime.DayOfWeek;
412 tm.tm_yday = RefTime.DayOfYear;
413 tm.tm_isdst = RefTime.IsDaylightSavingTime() ? 1 : 0;
414 return tm;
415 }
416  
417 public static long ToUnixtime( System.DateTime date )
418 {
419 System.DateTime unixStartTime = new System.DateTime( 1970, 1, 1, 0, 0, 0, 0 );
420 System.TimeSpan timeSpan = date - unixStartTime;
421 return Convert.ToInt64( timeSpan.TotalSeconds );
422 }
423  
424 public static System.DateTime ToCSharpTime( long unixTime )
425 {
426 System.DateTime unixStartTime = new System.DateTime( 1970, 1, 1, 0, 0, 0, 0 );
427 return unixStartTime.AddSeconds( Convert.ToDouble( unixTime ) );
428 }
429  
430 public class tm
431 {
432 public int tm_sec; /* seconds after the minute - [0,59] */
433 public int tm_min; /* minutes after the hour - [0,59] */
434 public int tm_hour; /* hours since midnight - [0,23] */
435 public int tm_mday; /* day of the month - [1,31] */
436 public int tm_mon; /* months since January - [0,11] */
437 public int tm_year; /* years since 1900 */
438 public int tm_wday; /* days since Sunday - [0,6] */
439 public int tm_yday; /* days since January 1 - [0,365] */
440 public int tm_isdst; /* daylight savings time flag */
441 };
442  
443 public struct FILETIME
444 {
445 public u32 dwLowDateTime;
446 public u32 dwHighDateTime;
447 }
448  
449 // Example (C#)
450 public static int GetbytesPerSector( StringBuilder diskPath )
451 {
452 #if !(SQLITE_SILVERLIGHT || WINDOWS_MOBILE)
453 ManagementObjectSearcher mosLogicalDisks = new ManagementObjectSearcher( "select * from Win32_LogicalDisk where DeviceID = '" + diskPath.ToString().Remove( diskPath.Length - 1, 1 ) + "'" );
454 try
455 {
456 foreach ( ManagementObject moLogDisk in mosLogicalDisks.Get() )
457 {
458 ManagementObjectSearcher mosDiskDrives = new ManagementObjectSearcher( "select * from Win32_DiskDrive where SystemName = '" + moLogDisk["SystemName"] + "'" );
459 foreach ( ManagementObject moPDisk in mosDiskDrives.Get() )
460 {
461 return int.Parse( moPDisk["BytesPerSector"].ToString() );
462 }
463 }
464 }
465 catch
466 {
467 }
468 return 4096;
469 #else
470 return 4096;
471 #endif
472 }
473  
474 static void SWAP<T>( ref T A, ref T B )
475 {
476 T t = A;
477 A = B;
478 B = t;
479 }
480  
481 static void x_CountStep(
482 sqlite3_context context,
483 int argc,
484 sqlite3_value[] argv
485 )
486 {
487 SumCtx p;
488  
489 int type;
490 Debug.Assert( argc <= 1 );
491 Mem pMem = sqlite3_aggregate_context( context, 1 );//sizeof(*p));
492 if ( pMem._SumCtx == null )
493 pMem._SumCtx = new SumCtx();
494 p = pMem._SumCtx;
495 if ( p.Context == null )
496 p.Context = pMem;
497 if ( argc == 0 || SQLITE_NULL == sqlite3_value_type( argv[0] ) )
498 {
499 p.cnt++;
500 p.iSum += 1;
501 }
502 else
503 {
504 type = sqlite3_value_numeric_type( argv[0] );
505 if ( p != null && type != SQLITE_NULL )
506 {
507 p.cnt++;
508 if ( type == SQLITE_INTEGER )
509 {
510 i64 v = sqlite3_value_int64( argv[0] );
511 if ( v == 40 || v == 41 )
512 {
513 sqlite3_result_error( context, "value of " + v + " handed to x_count", -1 );
514 return;
515 }
516 else
517 {
518 p.iSum += v;
519 if ( !( p.approx | p.overflow != 0 ) )
520 {
521 i64 iNewSum = p.iSum + v;
522 int s1 = (int)( p.iSum >> ( sizeof( i64 ) * 8 - 1 ) );
523 int s2 = (int)( v >> ( sizeof( i64 ) * 8 - 1 ) );
524 int s3 = (int)( iNewSum >> ( sizeof( i64 ) * 8 - 1 ) );
525 p.overflow = ( ( s1 & s2 & ~s3 ) | ( ~s1 & ~s2 & s3 ) ) != 0 ? 1 : 0;
526 p.iSum = iNewSum;
527 }
528 }
529 }
530 else
531 {
532 p.rSum += sqlite3_value_double( argv[0] );
533 p.approx = true;
534 }
535 }
536 }
537 }
538 static void x_CountFinalize( sqlite3_context context )
539 {
540 SumCtx p;
541 Mem pMem = sqlite3_aggregate_context( context, 0 );
542 p = pMem._SumCtx;
543 if ( p != null && p.cnt > 0 )
544 {
545 if ( p.overflow != 0 )
546 {
547 sqlite3_result_error( context, "integer overflow", -1 );
548 }
549 else if ( p.approx )
550 {
551 sqlite3_result_double( context, p.rSum );
552 }
553 else if ( p.iSum == 42 )
554 {
555 sqlite3_result_error( context, "x_count totals to 42", -1 );
556 }
557 else
558 {
559 sqlite3_result_int64( context, p.iSum );
560 }
561 }
562 }
563  
564 #if SQLITE_MUTEX_W32
565 //---------------------WIN32 Definitions
566 static int GetCurrentThreadId()
567 {
568 return Thread.CurrentThread.ManagedThreadId;
569 }
570 static long InterlockedIncrement( long location )
571 {
572 Interlocked.Increment( ref location );
573 return location;
574 }
575 static void EnterCriticalSection( Object mtx )
576 {
577 //long mid = mtx.GetHashCode();
578 //int tid = Thread.CurrentThread.ManagedThreadId;
579 //long ticks = cnt++;
580 //Debug.WriteLine(String.Format( "{2}: +EnterCriticalSection; Mutex {0} Thread {1}", mtx.GetHashCode(), Thread.CurrentThread.ManagedThreadId, ticks) );
581 Monitor.Enter( mtx );
582 }
583 static void InitializeCriticalSection( Object mtx )
584 {
585 //Debug.WriteLine(String.Format( "{2}: +InitializeCriticalSection; Mutex {0} Thread {1}", mtx.GetHashCode(), Thread.CurrentThread.ManagedThreadId, System.DateTime.Now.Ticks ));
586 }
587 static void DeleteCriticalSection( Object mtx )
588 {
589 //Debug.WriteLine(String.Format( "{2}: +DeleteCriticalSection; Mutex {0} Thread {1}", mtx.GetHashCode(), Thread.CurrentThread.ManagedThreadId, System.DateTime.Now.Ticks) );
590 }
591 static void LeaveCriticalSection( Object mtx )
592 {
593 //Debug.WriteLine(String.Format("{2}: +LeaveCriticalSection; Mutex {0} Thread {1}", mtx.GetHashCode(), Thread.CurrentThread.ManagedThreadId, System.DateTime.Now.Ticks ));
594 Monitor.Exit( mtx );
595 }
596 #endif
597  
598 // Miscellaneous Windows Constants
599 //#define ERROR_FILE_NOT_FOUND 2L
600 //#define ERROR_HANDLE_DISK_FULL 39L
601 //#define ERROR_NOT_SUPPORTED 50L
602 //#define ERROR_DISK_FULL 112L
603 const long ERROR_FILE_NOT_FOUND = 2L;
604 const long ERROR_HANDLE_DISK_FULL = 39L;
605 const long ERROR_NOT_SUPPORTED = 50L;
606 const long ERROR_DISK_FULL = 112L;
607  
608 private class SQLite3UpperToLower
609 {
610 static int[] sqlite3UpperToLower = new int[] {
611 #if SQLITE_ASCII
612 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
613 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
614 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
615 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
616 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
617 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
618 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
619 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
620 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
621 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
622 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
623 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
624 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
625 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
626 252,253,254,255
627 #endif
628 };
629 public int this[int index]
630 {
631 get
632 {
633 if ( index < sqlite3UpperToLower.Length )
634 return sqlite3UpperToLower[index];
635 else
636 return index;
637 }
638 }
639  
640 public int this[u32 index]
641 {
642 get
643 {
644 if ( index < sqlite3UpperToLower.Length )
645 return sqlite3UpperToLower[index];
646 else
647 return (int)index;
648 }
649 }
650 }
651  
652 static SQLite3UpperToLower sqlite3UpperToLower = new SQLite3UpperToLower();
653 static SQLite3UpperToLower UpperToLower = sqlite3UpperToLower;
654  
655 }
656 }