1 /* 2 ** 2016-09-07 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ****************************************************************************** 12 ** 13 ** This is an in-memory read-only VFS implementation. The application 14 ** supplies a block of memory which is the database file, and this VFS 15 ** uses that block of memory. 16 ** 17 ** Because there is no place to store journals and no good way to lock 18 ** the "file", this VFS is read-only. 19 ** 20 ** USAGE: 21 ** 22 ** sqlite3_open_v2("file:/whatever?ptr=0xf05538&sz=14336", &db, 23 ** SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, 24 ** "memvfs"); 25 ** 26 ** The ptr= and sz= query parameters are required or the open will fail. 27 ** The ptr= parameter gives the memory address of the buffer holding the 28 ** read-only database and sz= gives the size of the database. The parameter 29 ** values may be in hexadecimal or decimal. The filename is ignored. 30 */ 31 #include <sqlite3ext.h> 32 SQLITE_EXTENSION_INIT1 33 #include <string.h> 34 #include <assert.h> 35 36 37 /* 38 ** Forward declaration of objects used by this utility 39 */ 40 typedef struct sqlite3_vfs MemVfs; 41 typedef struct MemFile MemFile; 42 43 /* Access to a lower-level VFS that (might) implement dynamic loading, 44 ** access to randomness, etc. 45 */ 46 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) 47 48 /* An open file */ 49 struct MemFile { 50 sqlite3_file base; /* IO methods */ 51 sqlite3_int64 sz; /* Size of the file */ 52 unsigned char *aData; /* content of the file */ 53 }; 54 55 /* 56 ** Methods for MemFile 57 */ 58 static int memClose(sqlite3_file*); 59 static int memRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 60 static int memWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); 61 static int memTruncate(sqlite3_file*, sqlite3_int64 size); 62 static int memSync(sqlite3_file*, int flags); 63 static int memFileSize(sqlite3_file*, sqlite3_int64 *pSize); 64 static int memLock(sqlite3_file*, int); 65 static int memUnlock(sqlite3_file*, int); 66 static int memCheckReservedLock(sqlite3_file*, int *pResOut); 67 static int memFileControl(sqlite3_file*, int op, void *pArg); 68 static int memSectorSize(sqlite3_file*); 69 static int memDeviceCharacteristics(sqlite3_file*); 70 static int memShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); 71 static int memShmLock(sqlite3_file*, int offset, int n, int flags); 72 static void memShmBarrier(sqlite3_file*); 73 static int memShmUnmap(sqlite3_file*, int deleteFlag); 74 static int memFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); 75 static int memUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); 76 77 /* 78 ** Methods for MemVfs 79 */ 80 static int memOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); 81 static int memDelete(sqlite3_vfs*, const char *zName, int syncDir); 82 static int memAccess(sqlite3_vfs*, const char *zName, int flags, int *); 83 static int memFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); 84 static void *memDlOpen(sqlite3_vfs*, const char *zFilename); 85 static void memDlError(sqlite3_vfs*, int nByte, char *zErrMsg); 86 static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); 87 static void memDlClose(sqlite3_vfs*, void*); 88 static int memRandomness(sqlite3_vfs*, int nByte, char *zOut); 89 static int memSleep(sqlite3_vfs*, int microseconds); 90 static int memCurrentTime(sqlite3_vfs*, double*); 91 static int memGetLastError(sqlite3_vfs*, int, char *); 92 static int memCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); 93 94 static sqlite3_vfs mem_vfs = { 95 2, /* iVersion */ 96 0, /* szOsFile (set when registered) */ 97 1024, /* mxPathname */ 98 0, /* pNext */ 99 "memvfs", /* zName */ 100 0, /* pAppData (set when registered) */ 101 memOpen, /* xOpen */ 102 memDelete, /* xDelete */ 103 memAccess, /* xAccess */ 104 memFullPathname, /* xFullPathname */ 105 memDlOpen, /* xDlOpen */ 106 memDlError, /* xDlError */ 107 memDlSym, /* xDlSym */ 108 memDlClose, /* xDlClose */ 109 memRandomness, /* xRandomness */ 110 memSleep, /* xSleep */ 111 memCurrentTime, /* xCurrentTime */ 112 memGetLastError, /* xGetLastError */ 113 memCurrentTimeInt64 /* xCurrentTimeInt64 */ 114 }; 115 116 static const sqlite3_io_methods mem_io_methods = { 117 3, /* iVersion */ 118 memClose, /* xClose */ 119 memRead, /* xRead */ 120 memWrite, /* xWrite */ 121 memTruncate, /* xTruncate */ 122 memSync, /* xSync */ 123 memFileSize, /* xFileSize */ 124 memLock, /* xLock */ 125 memUnlock, /* xUnlock */ 126 memCheckReservedLock, /* xCheckReservedLock */ 127 memFileControl, /* xFileControl */ 128 memSectorSize, /* xSectorSize */ 129 memDeviceCharacteristics, /* xDeviceCharacteristics */ 130 memShmMap, /* xShmMap */ 131 memShmLock, /* xShmLock */ 132 memShmBarrier, /* xShmBarrier */ 133 memShmUnmap, /* xShmUnmap */ 134 memFetch, /* xFetch */ 135 memUnfetch /* xUnfetch */ 136 }; 137 138 139 140 /* 141 ** Close an mem-file. 142 ** 143 ** The pData pointer is owned by the application, so there is nothing 144 ** to free. 145 */ 146 static int memClose(sqlite3_file *pFile){ 147 return SQLITE_OK; 148 } 149 150 /* 151 ** Read data from an mem-file. 152 */ 153 static int memRead( 154 sqlite3_file *pFile, 155 void *zBuf, 156 int iAmt, 157 sqlite_int64 iOfst 158 ){ 159 MemFile *p = (MemFile *)pFile; 160 memcpy(zBuf, p->aData+iOfst, iAmt); 161 return SQLITE_OK; 162 } 163 164 /* 165 ** Write data to an mem-file. 166 */ 167 static int memWrite( 168 sqlite3_file *pFile, 169 const void *z, 170 int iAmt, 171 sqlite_int64 iOfst 172 ){ 173 return SQLITE_READONLY; 174 } 175 176 /* 177 ** Truncate an mem-file. 178 */ 179 static int memTruncate(sqlite3_file *pFile, sqlite_int64 size){ 180 return SQLITE_READONLY; 181 } 182 183 /* 184 ** Sync an mem-file. 185 */ 186 static int memSync(sqlite3_file *pFile, int flags){ 187 return SQLITE_READONLY; 188 } 189 190 /* 191 ** Return the current file-size of an mem-file. 192 */ 193 static int memFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 194 MemFile *p = (MemFile *)pFile; 195 *pSize = p->sz; 196 return SQLITE_OK; 197 } 198 199 /* 200 ** Lock an mem-file. 201 */ 202 static int memLock(sqlite3_file *pFile, int eLock){ 203 return SQLITE_READONLY; 204 } 205 206 /* 207 ** Unlock an mem-file. 208 */ 209 static int memUnlock(sqlite3_file *pFile, int eLock){ 210 return SQLITE_OK; 211 } 212 213 /* 214 ** Check if another file-handle holds a RESERVED lock on an mem-file. 215 */ 216 static int memCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 217 *pResOut = 0; 218 return SQLITE_OK; 219 } 220 221 /* 222 ** File control method. For custom operations on an mem-file. 223 */ 224 static int memFileControl(sqlite3_file *pFile, int op, void *pArg){ 225 MemFile *p = (MemFile *)pFile; 226 int rc = SQLITE_NOTFOUND; 227 if( op==SQLITE_FCNTL_VFSNAME ){ 228 *(char**)pArg = sqlite3_mprintf("mem(%p,%lld)", p->aData, p->sz); 229 rc = SQLITE_OK; 230 } 231 return rc; 232 } 233 234 /* 235 ** Return the sector-size in bytes for an mem-file. 236 */ 237 static int memSectorSize(sqlite3_file *pFile){ 238 return 1024; 239 } 240 241 /* 242 ** Return the device characteristic flags supported by an mem-file. 243 */ 244 static int memDeviceCharacteristics(sqlite3_file *pFile){ 245 return SQLITE_IOCAP_IMMUTABLE; 246 } 247 248 /* Create a shared memory file mapping */ 249 static int memShmMap( 250 sqlite3_file *pFile, 251 int iPg, 252 int pgsz, 253 int bExtend, 254 void volatile **pp 255 ){ 256 return SQLITE_READONLY; 257 } 258 259 /* Perform locking on a shared-memory segment */ 260 static int memShmLock(sqlite3_file *pFile, int offset, int n, int flags){ 261 return SQLITE_READONLY; 262 } 263 264 /* Memory barrier operation on shared memory */ 265 static void memShmBarrier(sqlite3_file *pFile){ 266 return; 267 } 268 269 /* Unmap a shared memory segment */ 270 static int memShmUnmap(sqlite3_file *pFile, int deleteFlag){ 271 return SQLITE_OK; 272 } 273 274 /* Fetch a page of a memory-mapped file */ 275 static int memFetch( 276 sqlite3_file *pFile, 277 sqlite3_int64 iOfst, 278 int iAmt, 279 void **pp 280 ){ 281 MemFile *p = (MemFile *)pFile; 282 *pp = (void*)(p->aData + iOfst); 283 return SQLITE_OK; 284 } 285 286 /* Release a memory-mapped page */ 287 static int memUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ 288 return SQLITE_OK; 289 } 290 291 /* 292 ** Open an mem file handle. 293 */ 294 static int memOpen( 295 sqlite3_vfs *pVfs, 296 const char *zName, 297 sqlite3_file *pFile, 298 int flags, 299 int *pOutFlags 300 ){ 301 MemFile *p = (MemFile*)pFile; 302 memset(p, 0, sizeof(*p)); 303 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ) return SQLITE_CANTOPEN; 304 p->aData = (unsigned char*)sqlite3_uri_int64(zName,"ptr",0); 305 if( p->aData==0 ) return SQLITE_CANTOPEN; 306 p->sz = sqlite3_uri_int64(zName,"sz",0); 307 if( p->sz<0 ) return SQLITE_CANTOPEN; 308 pFile->pMethods = &mem_io_methods; 309 return SQLITE_OK; 310 } 311 312 /* 313 ** Delete the file located at zPath. If the dirSync argument is true, 314 ** ensure the file-system modifications are synced to disk before 315 ** returning. 316 */ 317 static int memDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 318 return SQLITE_READONLY; 319 } 320 321 /* 322 ** Test for access permissions. Return true if the requested permission 323 ** is available, or false otherwise. 324 */ 325 static int memAccess( 326 sqlite3_vfs *pVfs, 327 const char *zPath, 328 int flags, 329 int *pResOut 330 ){ 331 /* The spec says there are three possible values for flags. But only 332 ** two of them are actually used */ 333 assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); 334 if( flags==SQLITE_ACCESS_READWRITE ){ 335 *pResOut = 0; 336 }else{ 337 *pResOut = 1; 338 } 339 return SQLITE_OK; 340 } 341 342 /* 343 ** Populate buffer zOut with the full canonical pathname corresponding 344 ** to the pathname in zPath. zOut is guaranteed to point to a buffer 345 ** of at least (INST_MAX_PATHNAME+1) bytes. 346 */ 347 static int memFullPathname( 348 sqlite3_vfs *pVfs, 349 const char *zPath, 350 int nOut, 351 char *zOut 352 ){ 353 sqlite3_snprintf(nOut, zOut, "%s", zPath); 354 return SQLITE_OK; 355 } 356 357 /* 358 ** Open the dynamic library located at zPath and return a handle. 359 */ 360 static void *memDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 361 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); 362 } 363 364 /* 365 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable 366 ** utf-8 string describing the most recent error encountered associated 367 ** with dynamic libraries. 368 */ 369 static void memDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 370 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); 371 } 372 373 /* 374 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. 375 */ 376 static void (*memDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ 377 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); 378 } 379 380 /* 381 ** Close the dynamic library handle pHandle. 382 */ 383 static void memDlClose(sqlite3_vfs *pVfs, void *pHandle){ 384 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); 385 } 386 387 /* 388 ** Populate the buffer pointed to by zBufOut with nByte bytes of 389 ** random data. 390 */ 391 static int memRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 392 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); 393 } 394 395 /* 396 ** Sleep for nMicro microseconds. Return the number of microseconds 397 ** actually slept. 398 */ 399 static int memSleep(sqlite3_vfs *pVfs, int nMicro){ 400 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); 401 } 402 403 /* 404 ** Return the current time as a Julian Day number in *pTimeOut. 405 */ 406 static int memCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 407 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); 408 } 409 410 static int memGetLastError(sqlite3_vfs *pVfs, int a, char *b){ 411 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); 412 } 413 static int memCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ 414 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); 415 } 416 417 #ifdef MEMVFS_TEST 418 /* 419 ** memload(FILENAME) 420 ** 421 ** This an SQL function used to help in testing the memvfs VFS. The 422 ** function reads the content of a file into memory and then returns 423 ** a string that gives the locate and size of the in-memory buffer. 424 */ 425 #include <stdio.h> 426 static void memvfsMemloadFunc( 427 sqlite3_context *context, 428 int argc, 429 sqlite3_value **argv 430 ){ 431 unsigned char *p; 432 sqlite3_int64 sz; 433 FILE *in; 434 const char *zFilename = (const char*)sqlite3_value_text(argv[0]); 435 char zReturn[100]; 436 437 if( zFilename==0 ) return; 438 in = fopen(zFilename, "rb"); 439 if( in==0 ) return; 440 fseek(in, 0, SEEK_END); 441 sz = ftell(in); 442 rewind(in); 443 p = sqlite3_malloc( sz ); 444 if( p==0 ){ 445 fclose(in); 446 sqlite3_result_error_nomem(context); 447 return; 448 } 449 fread(p, sz, 1, in); 450 fclose(in); 451 sqlite3_snprintf(sizeof(zReturn),zReturn,"ptr=%lld&sz=%lld", 452 (sqlite3_int64)p, sz); 453 sqlite3_result_text(context, zReturn, -1, SQLITE_TRANSIENT); 454 } 455 /* Called for each new database connection */ 456 static int memvfsRegister( 457 sqlite3 *db, 458 const char **pzErrMsg, 459 const struct sqlite3_api_routines *pThunk 460 ){ 461 return sqlite3_create_function(db, "memload", 1, SQLITE_UTF8, 0, 462 memvfsMemloadFunc, 0, 0); 463 } 464 #endif /* MEMVFS_TEST */ 465 466 467 #ifdef _WIN32 468 __declspec(dllexport) 469 #endif 470 /* 471 ** This routine is called when the extension is loaded. 472 ** Register the new VFS. 473 */ 474 int sqlite3_memvfs_init( 475 sqlite3 *db, 476 char **pzErrMsg, 477 const sqlite3_api_routines *pApi 478 ){ 479 int rc = SQLITE_OK; 480 SQLITE_EXTENSION_INIT2(pApi); 481 mem_vfs.pAppData = sqlite3_vfs_find(0); 482 mem_vfs.szOsFile = sizeof(MemFile); 483 rc = sqlite3_vfs_register(&mem_vfs, 1); 484 #ifdef MEMVFS_TEST 485 if( rc==SQLITE_OK ){ 486 rc = sqlite3_auto_extension((void(*)(void))memvfsRegister); 487 } 488 #endif 489 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; 490 return rc; 491 } 492