Arquivos
hhvm/hphp/util/embedded-vfs.cpp
Edwin Smith fd881ac637 Rename _ to - in hphp/util
One more step in the renaming arc.
Depends on D925182

Differential Revision: D927227
2013-08-27 11:58:28 -07:00

276 linhas
8.7 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/util/embedded-vfs.h"
/*
* based on test_demovfs.c and test_multiplex.c in sqlite3
*/
#include <sqlite3.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef SQLITE_CORE
#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
#endif
#include <sqlite3ext.h>
namespace HPHP {
/*
** For a build without mutexes, no-op the mutex calls.
*/
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
#define sqlite3_mutex_free(X)
#define sqlite3_mutex_enter(X)
#define sqlite3_mutex_try(X) SQLITE_OK
#define sqlite3_mutex_leave(X)
#define sqlite3_mutex_held(X) ((void)(X),1)
#define sqlite3_mutex_notheld(X) ((void)(X),1)
#endif /* SQLITE_THREADSAFE==0 */
struct embeddedConn {
sqlite3_file base;
int fd;
size_t offset;
size_t len;
};
static struct {
sqlite3_vfs* pOrigVfs;
sqlite3_vfs sThisVfs;
sqlite3_io_methods sIoMethodsV1;
sqlite3_mutex* pMutex;
int isInitialized;
} gEmbedded;
static void embeddedEnter() { sqlite3_mutex_enter(gEmbedded.pMutex); }
static void embeddedLeave() { sqlite3_mutex_leave(gEmbedded.pMutex); }
static int embeddedOpen(sqlite3_vfs *pVfs, const char *zName,
sqlite3_file *pConn, int flags,
int *pOutFlags) {
memset(pConn, 0, pVfs->szOsFile);
assert(zName || (flags & SQLITE_OPEN_DELETEONCLOSE));
if (zName) {
const char *p = strchr(zName, ':');
unsigned long off, len;
char c;
if (p && sscanf(p + 1, "%lu:%lu%c", &off, &len, &c) == 2) {
embeddedConn *eConn = (embeddedConn*)pConn;
eConn->base.pMethods = &gEmbedded.sIoMethodsV1;
char *tmp = strdup(zName);
tmp[p - zName] = 0;
eConn->fd = open(tmp, O_RDONLY, 0);
free(tmp);
if (eConn->fd < 0) return SQLITE_CANTOPEN;
eConn->offset = off;
eConn->len = len;
*pOutFlags = SQLITE_OPEN_READONLY;
return SQLITE_OK;
}
}
sqlite3_vfs *pOrigVfs = gEmbedded.pOrigVfs; /* Real VFS */
return pOrigVfs->xOpen(pOrigVfs, zName, pConn, flags, pOutFlags);
}
static int embeddedDelete(sqlite3_vfs* pVfs, const char* zName, int syncDir) {
return gEmbedded.pOrigVfs->xDelete(gEmbedded.pOrigVfs, zName, syncDir);
}
static int embeddedAccess(sqlite3_vfs* a, const char* b, int c, int* d) {
return gEmbedded.pOrigVfs->xAccess(gEmbedded.pOrigVfs, b, c, d);
}
static int embeddedFullPathname(sqlite3_vfs* a, const char* b, int c, char* d) {
return gEmbedded.pOrigVfs->xFullPathname(gEmbedded.pOrigVfs, b, c, d);
}
static void* embeddedDlOpen(sqlite3_vfs* a, const char* b) {
return gEmbedded.pOrigVfs->xDlOpen(gEmbedded.pOrigVfs, b);
}
static void embeddedDlError(sqlite3_vfs* a, int b, char* c) {
gEmbedded.pOrigVfs->xDlError(gEmbedded.pOrigVfs, b, c);
}
static void (*embeddedDlSym(sqlite3_vfs* a, void* b, const char* c))() {
return gEmbedded.pOrigVfs->xDlSym(gEmbedded.pOrigVfs, b, c);
}
static void embeddedDlClose(sqlite3_vfs* a, void* b) {
gEmbedded.pOrigVfs->xDlClose(gEmbedded.pOrigVfs, b);
}
static int embeddedRandomness(sqlite3_vfs* a, int b, char* c) {
return gEmbedded.pOrigVfs->xRandomness(gEmbedded.pOrigVfs, b, c);
}
static int embeddedSleep(sqlite3_vfs* a, int b) {
return gEmbedded.pOrigVfs->xSleep(gEmbedded.pOrigVfs, b);
}
static int embeddedCurrentTime(sqlite3_vfs* a, double* b) {
return gEmbedded.pOrigVfs->xCurrentTime(gEmbedded.pOrigVfs, b);
}
static int embeddedGetLastError(sqlite3_vfs* a, int b, char* c) {
return gEmbedded.pOrigVfs->xGetLastError(gEmbedded.pOrigVfs, b, c);
}
static int embeddedCurrentTimeInt64(sqlite3_vfs* a, sqlite3_int64* b) {
return gEmbedded.pOrigVfs->xCurrentTimeInt64(gEmbedded.pOrigVfs, b);
}
static int embeddedClose(sqlite3_file* pConn) {
embeddedConn* p = (embeddedConn*)pConn;
return close(p->fd) ? SQLITE_OK : SQLITE_ERROR;
}
static int embeddedRead(sqlite3_file* pConn, void* pBuf,
int iAmt, sqlite3_int64 iOfst) {
embeddedConn* p = (embeddedConn*)pConn;
if (iOfst > p->len) return SQLITE_IOERR_READ;
int rc = SQLITE_OK;
if (iAmt + iOfst > p->len) {
rc = SQLITE_IOERR_SHORT_READ;
iAmt = p->len - iOfst;
}
iOfst += p->offset;
embeddedEnter();
if (lseek(p->fd, iOfst, SEEK_SET) != iOfst) {
rc = SQLITE_IOERR_READ;
} else if (read(p->fd, pBuf, iAmt) != iAmt) {
rc = SQLITE_IOERR_READ;
}
embeddedLeave();
return rc;
}
static int embeddedWrite(sqlite3_file* pConn, const void* pBuf,
int iAmt, sqlite3_int64 iOfst) {
return SQLITE_IOERR_WRITE;
}
static int embeddedTruncate(sqlite3_file* pConn, sqlite3_int64 size) {
return SQLITE_IOERR_TRUNCATE;
}
static int embeddedSync(sqlite3_file* pConn, int flags) {
return SQLITE_OK;
}
static int embeddedFileSize(sqlite3_file* pConn, sqlite3_int64* pSize) {
embeddedConn* p = (embeddedConn*)pConn;
*pSize = p->len;
return SQLITE_OK;
}
static int embeddedLock(sqlite3_file* pConn, int lock) {
return SQLITE_OK;
}
static int embeddedUnlock(sqlite3_file* pConn, int lock) {
return SQLITE_OK;
}
static int embeddedCheckReservedLock(sqlite3_file* pConn, int* pResOut) {
return SQLITE_IOERR_CHECKRESERVEDLOCK;
}
static int embeddedFileControl(sqlite3_file* pConn, int op, void* pArg) {
return SQLITE_OK;
}
static int embeddedSectorSize(sqlite3_file* pConn) {
return 0;
}
static int embeddedDeviceCharacteristics(sqlite3_file* pConn) {
return 0;
}
int sqlite3_embedded_initialize(const char* zOrigVfsName, int makeDefault) {
sqlite3_vfs* pOrigVfs;
if (gEmbedded.isInitialized) return SQLITE_MISUSE;
pOrigVfs = sqlite3_vfs_find(zOrigVfsName);
if (pOrigVfs==0) return SQLITE_ERROR;
assert(pOrigVfs!=&gEmbedded.sThisVfs);
gEmbedded.pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if (!gEmbedded.pMutex) {
return SQLITE_NOMEM;
}
gEmbedded.isInitialized = 1;
gEmbedded.pOrigVfs = pOrigVfs;
gEmbedded.sThisVfs = *pOrigVfs;
gEmbedded.sThisVfs.szOsFile += sizeof(embeddedConn);
gEmbedded.sThisVfs.zName = "embedded";
gEmbedded.sThisVfs.xOpen = embeddedOpen;
gEmbedded.sThisVfs.xDelete = embeddedDelete;
gEmbedded.sThisVfs.xAccess = embeddedAccess;
gEmbedded.sThisVfs.xFullPathname = embeddedFullPathname;
gEmbedded.sThisVfs.xDlOpen = embeddedDlOpen;
gEmbedded.sThisVfs.xDlError = embeddedDlError;
gEmbedded.sThisVfs.xDlSym = embeddedDlSym;
gEmbedded.sThisVfs.xDlClose = embeddedDlClose;
gEmbedded.sThisVfs.xRandomness = embeddedRandomness;
gEmbedded.sThisVfs.xSleep = embeddedSleep;
gEmbedded.sThisVfs.xCurrentTime = embeddedCurrentTime;
gEmbedded.sThisVfs.xGetLastError = embeddedGetLastError;
gEmbedded.sThisVfs.xCurrentTimeInt64 = embeddedCurrentTimeInt64;
gEmbedded.sIoMethodsV1.iVersion = 1;
gEmbedded.sIoMethodsV1.xClose = embeddedClose;
gEmbedded.sIoMethodsV1.xRead = embeddedRead;
gEmbedded.sIoMethodsV1.xWrite = embeddedWrite;
gEmbedded.sIoMethodsV1.xTruncate = embeddedTruncate;
gEmbedded.sIoMethodsV1.xSync = embeddedSync;
gEmbedded.sIoMethodsV1.xFileSize = embeddedFileSize;
gEmbedded.sIoMethodsV1.xLock = embeddedLock;
gEmbedded.sIoMethodsV1.xUnlock = embeddedUnlock;
gEmbedded.sIoMethodsV1.xCheckReservedLock = embeddedCheckReservedLock;
gEmbedded.sIoMethodsV1.xFileControl = embeddedFileControl;
gEmbedded.sIoMethodsV1.xSectorSize = embeddedSectorSize;
gEmbedded.sIoMethodsV1.xDeviceCharacteristics =
embeddedDeviceCharacteristics;
sqlite3_vfs_register(&gEmbedded.sThisVfs, makeDefault);
return SQLITE_OK;
}
int sqlite3_embedded_shutdown() {
if( gEmbedded.isInitialized==0 ) return SQLITE_MISUSE;
gEmbedded.isInitialized = 0;
sqlite3_mutex_free(gEmbedded.pMutex);
sqlite3_vfs_unregister(&gEmbedded.sThisVfs);
memset(&gEmbedded, 0, sizeof(gEmbedded));
return SQLITE_OK;
}
}