wasCSharpSQLite – Blame information for rev 4

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System.Diagnostics;
2 using System.Text;
3  
4 using HANDLE = System.IntPtr;
5 using i64 = System.Int64;
6 using u32 = System.UInt32;
7 using sqlite3_int64 = System.Int64;
8  
9 namespace Community.CsharpSqlite
10 {
11 public partial class Sqlite3
12 {
13  
14 /*
15 ** 2005 November 29
16 **
17 ** The author disclaims copyright to this source code. In place of
18 ** a legal notice, here is a blessing:
19 **
20 ** May you do good and not evil.
21 ** May you find forgiveness for yourself and forgive others.
22 ** May you share freely, never taking more than you give.
23 **
24 ******************************************************************************
25 **
26 ** This file contains OS interface code that is common to all
27 ** architectures.
28 *************************************************************************
29 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
30 ** C#-SQLite is an independent reimplementation of the SQLite software library
31 **
32 ** SQLITE_SOURCE_ID: 2010-12-07 20:14:09 a586a4deeb25330037a49df295b36aaf624d0f45
33 **
34 *************************************************************************
35 */
36 //#define _SQLITE_OS_C_ 1
37 //#include "sqliteInt.h"
38 //#undef _SQLITE_OS_C_
39  
40 /*
41 ** The default SQLite sqlite3_vfs implementations do not allocate
42 ** memory (actually, os_unix.c allocates a small amount of memory
43 ** from within OsOpen()), but some third-party implementations may.
44 ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
45 ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
46 **
47 ** The following functions are instrumented for malloc() failure
48 ** testing:
49 **
50 ** sqlite3OsOpen()
51 ** sqlite3OsRead()
52 ** sqlite3OsWrite()
53 ** sqlite3OsSync()
54 ** sqlite3OsLock()
55 **
56 */
57 #if (SQLITE_TEST)
58 static int sqlite3_memdebug_vfs_oom_test = 1;
59  
60 //#define DO_OS_MALLOC_TEST(x) \
61 //if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \
62 // void *pTstAlloc = sqlite3Malloc(10); \
63 // if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
64 // sqlite3_free(pTstAlloc); \
65 //}
66 static void DO_OS_MALLOC_TEST( sqlite3_file x )
67 {
68 }
69 #else
70 //#define DO_OS_MALLOC_TEST(x)
71 static void DO_OS_MALLOC_TEST( sqlite3_file x ) { }
72 #endif
73  
74  
75 /*
76 ** The following routines are convenience wrappers around methods
77 ** of the sqlite3_file object. This is mostly just syntactic sugar. All
78 ** of this would be completely automatic if SQLite were coded using
79 ** C++ instead of plain old C.
80 */
81 static int sqlite3OsClose( sqlite3_file pId )
82 {
83 int rc = SQLITE_OK;
84 if ( pId.pMethods != null )
85 {
86 rc = pId.pMethods.xClose( pId );
87 pId.pMethods = null;
88 }
89 return rc;
90 }
91 static int sqlite3OsRead( sqlite3_file id, byte[] pBuf, int amt, i64 offset )
92 {
93 DO_OS_MALLOC_TEST( id );
94 if ( pBuf == null )
95 pBuf = sqlite3Malloc( amt );
96 return id.pMethods.xRead( id, pBuf, amt, offset );
97 }
98 static int sqlite3OsWrite( sqlite3_file id, byte[] pBuf, int amt, i64 offset )
99 {
100 DO_OS_MALLOC_TEST( id );
101 return id.pMethods.xWrite( id, pBuf, amt, offset );
102 }
103 static int sqlite3OsTruncate( sqlite3_file id, i64 size )
104 {
105 return id.pMethods.xTruncate( id, size );
106 }
107 static int sqlite3OsSync( sqlite3_file id, int flags )
108 {
109 DO_OS_MALLOC_TEST( id );
110 return id.pMethods.xSync( id, flags );
111 }
112 static int sqlite3OsFileSize( sqlite3_file id, ref long pSize )
113 {
114 return id.pMethods.xFileSize( id, ref pSize );
115 }
116 static int sqlite3OsLock( sqlite3_file id, int lockType )
117 {
118 DO_OS_MALLOC_TEST( id );
119 return id.pMethods.xLock( id, lockType );
120 }
121 static int sqlite3OsUnlock( sqlite3_file id, int lockType )
122 {
123 return id.pMethods.xUnlock( id, lockType );
124 }
125 static int sqlite3OsCheckReservedLock( sqlite3_file id, ref int pResOut )
126 {
127 DO_OS_MALLOC_TEST( id );
128 return id.pMethods.xCheckReservedLock( id, ref pResOut );
129 }
130 static int sqlite3OsFileControl( sqlite3_file id, u32 op, ref sqlite3_int64 pArg )
131 {
132 return id.pMethods.xFileControl( id, (int)op, ref pArg );
133 }
134  
135 static int sqlite3OsSectorSize( sqlite3_file id )
136 {
137 dxSectorSize xSectorSize = id.pMethods.xSectorSize;
138 return ( xSectorSize != null ? xSectorSize( id ) : SQLITE_DEFAULT_SECTOR_SIZE );
139 }
140 static int sqlite3OsDeviceCharacteristics( sqlite3_file id )
141 {
142 return id.pMethods.xDeviceCharacteristics( id );
143 }
144  
145 static int sqlite3OsShmLock( sqlite3_file id, int offset, int n, int flags )
146 {
147 return id.pMethods.xShmLock( id, offset, n, flags );
148 }
149 static void sqlite3OsShmBarrier( sqlite3_file id )
150 {
151 id.pMethods.xShmBarrier( id );
152 }
153  
154 static int sqlite3OsShmUnmap( sqlite3_file id, int deleteFlag )
155 {
156 return id.pMethods.xShmUnmap( id, deleteFlag );
157 }
158 static int sqlite3OsShmMap(
159 sqlite3_file id, /* Database file handle */
160 int iPage,
161 int pgsz,
162 int bExtend, /* True to extend file if necessary */
163 out object pp /* OUT: Pointer to mapping */
164 )
165 {
166 return id.pMethods.xShmMap( id, iPage, pgsz, bExtend, out pp );
167 }
168  
169 /*
170 ** The next group of routines are convenience wrappers around the
171 ** VFS methods.
172 */
173 static int sqlite3OsOpen(
174 sqlite3_vfs pVfs,
175 string zPath,
176 sqlite3_file pFile,
177 int flags,
178 ref int pFlagsOut
179 )
180 {
181 int rc;
182 DO_OS_MALLOC_TEST( null );
183 /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed
184 ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
185 ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
186 ** reaching the VFS. */
187 rc = pVfs.xOpen( pVfs, zPath, pFile, flags & 0x87f3f, out pFlagsOut );
188 Debug.Assert( rc == SQLITE_OK || pFile.pMethods == null );
189 return rc;
190 }
191 static int sqlite3OsDelete( sqlite3_vfs pVfs, string zPath, int dirSync )
192 {
193 return pVfs.xDelete( pVfs, zPath, dirSync );
194 }
195 static int sqlite3OsAccess( sqlite3_vfs pVfs, string zPath, int flags, ref int pResOut )
196 {
197 DO_OS_MALLOC_TEST( null );
198 return pVfs.xAccess( pVfs, zPath, flags, out pResOut );
199 }
200 static int sqlite3OsFullPathname(
201 sqlite3_vfs pVfs,
202 string zPath,
203 int nPathOut,
204 StringBuilder zPathOut
205 )
206 {
207 zPathOut.Length = 0;//zPathOut[0] = 0;
208 return pVfs.xFullPathname( pVfs, zPath, nPathOut, zPathOut );
209 }
210 #if !SQLITE_OMIT_LOAD_EXTENSION
211 static HANDLE sqlite3OsDlOpen( sqlite3_vfs pVfs, string zPath )
212 {
213 return pVfs.xDlOpen( pVfs, zPath );
214 }
215  
216 static void sqlite3OsDlError( sqlite3_vfs pVfs, int nByte, string zBufOut )
217 {
218 pVfs.xDlError( pVfs, nByte, zBufOut );
219 }
220 static object sqlite3OsDlSym( sqlite3_vfs pVfs, HANDLE pHdle, ref string zSym )
221 {
222 return pVfs.xDlSym( pVfs, pHdle, zSym );
223 }
224 static void sqlite3OsDlClose( sqlite3_vfs pVfs, HANDLE pHandle )
225 {
226 pVfs.xDlClose( pVfs, pHandle );
227 }
228 #endif
229 static int sqlite3OsRandomness( sqlite3_vfs pVfs, int nByte, byte[] zBufOut )
230 {
231 return pVfs.xRandomness( pVfs, nByte, zBufOut );
232 }
233 static int sqlite3OsSleep( sqlite3_vfs pVfs, int nMicro )
234 {
235 return pVfs.xSleep( pVfs, nMicro );
236 }
237  
238 static int sqlite3OsCurrentTimeInt64( sqlite3_vfs pVfs, ref sqlite3_int64 pTimeOut )
239 {
240 int rc;
241 /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
242 ** method to get the current date and time if that method is available
243 ** (if iVersion is 2 or greater and the function pointer is not NULL) and
244 ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
245 ** unavailable.
246 */
247 if ( pVfs.iVersion >= 2 && pVfs.xCurrentTimeInt64 != null )
248 {
249 rc = pVfs.xCurrentTimeInt64( pVfs, ref pTimeOut );
250 }
251 else
252 {
253 double r = 0;
254 rc = pVfs.xCurrentTime( pVfs, ref r );
255 pTimeOut = (sqlite3_int64)( r * 86400000.0 );
256 }
257 return rc;
258 }
259  
260 static int sqlite3OsOpenMalloc(
261 ref sqlite3_vfs pVfs,
262 string zFile,
263 ref sqlite3_file ppFile,
264 int flags,
265 ref int pOutFlags
266 )
267 {
268 int rc = SQLITE_NOMEM;
269 sqlite3_file pFile;
270 pFile = new sqlite3_file(); //sqlite3Malloc(ref pVfs.szOsFile);
271 if ( pFile != null )
272 {
273 rc = sqlite3OsOpen( pVfs, zFile, pFile, flags, ref pOutFlags );
274 if ( rc != SQLITE_OK )
275 {
276 pFile = null; // was sqlite3DbFree(db,ref pFile);
277 }
278 else
279 {
280 ppFile = pFile;
281 }
282 }
283 return rc;
284 }
285 static int sqlite3OsCloseFree( sqlite3_file pFile )
286 {
287 int rc = SQLITE_OK;
288 Debug.Assert( pFile != null );
289 rc = sqlite3OsClose( pFile );
290 //sqlite3_free( ref pFile );
291 return rc;
292 }
293  
294 /*
295 ** This function is a wrapper around the OS specific implementation of
296 ** sqlite3_os_init(). The purpose of the wrapper is to provide the
297 ** ability to simulate a malloc failure, so that the handling of an
298 ** error in sqlite3_os_init() by the upper layers can be tested.
299 */
300 static int sqlite3OsInit()
301 {
302 //void *p = sqlite3_malloc(10);
303 //if( p==null ) return SQLITE_NOMEM;
304 //sqlite3_free(ref p);
305 return sqlite3_os_init();
306 }
307 /*
308 ** The list of all registered VFS implementations.
309 */
310 static sqlite3_vfs vfsList;
311 //#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
312  
313 /*
314 ** Locate a VFS by name. If no name is given, simply return the
315 ** first VFS on the list.
316 */
317 static bool isInit = false;
318  
319 static sqlite3_vfs sqlite3_vfs_find( string zVfs )
320 {
321 sqlite3_vfs pVfs = null;
322 #if SQLITE_THREADSAFE
323 sqlite3_mutex mutex;
324 #endif
325 #if !SQLITE_OMIT_AUTOINIT
326 int rc = sqlite3_initialize();
327 if ( rc != 0 )
328 return null;
329 #endif
330 #if SQLITE_THREADSAFE
331 mutex = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MASTER );
332 #endif
333 sqlite3_mutex_enter( mutex );
334 for ( pVfs = vfsList; pVfs != null; pVfs = pVfs.pNext )
335 {
336 if ( string.IsNullOrEmpty( zVfs ) )
337 break;
338 if ( zVfs == pVfs.zName )
339 break; //strcmp(zVfs, pVfs.zName) == null) break;
340 }
341 sqlite3_mutex_leave( mutex );
342 return pVfs;
343 }
344  
345 /*
346 ** Unlink a VFS from the linked list
347 */
348 static void vfsUnlink( sqlite3_vfs pVfs )
349 {
350 Debug.Assert( sqlite3_mutex_held( sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MASTER ) ) );
351 if ( pVfs == null )
352 {
353 /* No-op */
354 }
355 else if ( vfsList == pVfs )
356 {
357 vfsList = pVfs.pNext;
358 }
359 else if ( vfsList != null )
360 {
361 sqlite3_vfs p = vfsList;
362 while ( p.pNext != null && p.pNext != pVfs )
363 {
364 p = p.pNext;
365 }
366 if ( p.pNext == pVfs )
367 {
368 p.pNext = pVfs.pNext;
369 }
370 }
371 }
372  
373 /*
374 ** Register a VFS with the system. It is harmless to register the same
375 ** VFS multiple times. The new VFS becomes the default if makeDflt is
376 ** true.
377 */
378 static int sqlite3_vfs_register( sqlite3_vfs pVfs, int makeDflt )
379 {
380 sqlite3_mutex mutex;
381 #if !SQLITE_OMIT_AUTOINIT
382 int rc = sqlite3_initialize();
383 if ( rc != 0 )
384 return rc;
385 #endif
386 mutex = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MASTER );
387 sqlite3_mutex_enter( mutex );
388 vfsUnlink( pVfs );
389 if ( makeDflt != 0 || vfsList == null )
390 {
391 pVfs.pNext = vfsList;
392 vfsList = pVfs;
393 }
394 else
395 {
396 pVfs.pNext = vfsList.pNext;
397 vfsList.pNext = pVfs;
398 }
399 Debug.Assert( vfsList != null );
400 sqlite3_mutex_leave( mutex );
401 return SQLITE_OK;
402 }
403  
404 /*
405 ** Unregister a VFS so that it is no longer accessible.
406 */
407 static int sqlite3_vfs_unregister( sqlite3_vfs pVfs )
408 {
409 #if SQLITE_THREADSAFE
410 sqlite3_mutex mutex = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_MASTER );
411 #endif
412 sqlite3_mutex_enter( mutex );
413 vfsUnlink( pVfs );
414 sqlite3_mutex_leave( mutex );
415 return SQLITE_OK;
416 }
417 }
418 }
419