Fix semdiff syntactic output
[hiphop-php.git] / hphp / util / embedded-vfs.cpp
blob60e234a8042a0c9846bd4df7cbef497587465f6c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #include "hphp/util/embedded-vfs.h"
19 * based on test_demovfs.c and test_multiplex.c in sqlite3
21 #include <sqlite3.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <stdlib.h>
25 #include <stdio.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
32 #ifndef SQLITE_CORE
33 #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
34 #endif
35 #include <sqlite3ext.h>
37 #include <folly/portability/Fcntl.h>
38 #include <folly/portability/Unistd.h>
40 namespace HPHP {
43 ** For a build without mutexes, no-op the mutex calls.
45 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
46 #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
47 #define sqlite3_mutex_free(X)
48 #define sqlite3_mutex_enter(X)
49 #define sqlite3_mutex_try(X) SQLITE_OK
50 #define sqlite3_mutex_leave(X)
51 #define sqlite3_mutex_held(X) ((void)(X),1)
52 #define sqlite3_mutex_notheld(X) ((void)(X),1)
53 #endif /* SQLITE_THREADSAFE==0 */
55 struct embeddedConn {
56 sqlite3_file base;
57 int fd;
58 size_t offset;
59 size_t len;
62 static struct {
63 sqlite3_vfs* pOrigVfs;
64 sqlite3_vfs sThisVfs;
65 sqlite3_io_methods sIoMethodsV1;
66 sqlite3_mutex* pMutex;
67 int isInitialized;
68 } gEmbedded;
70 static void embeddedEnter() { sqlite3_mutex_enter(gEmbedded.pMutex); }
71 static void embeddedLeave() { sqlite3_mutex_leave(gEmbedded.pMutex); }
73 static int embeddedOpen(sqlite3_vfs *pVfs, const char *zName,
74 sqlite3_file *pConn, int flags,
75 int *pOutFlags) {
76 memset(pConn, 0, pVfs->szOsFile);
77 assert(zName || (flags & SQLITE_OPEN_DELETEONCLOSE));
79 if (zName) {
80 const char *p = strchr(zName, ':');
81 unsigned long off, len;
82 char c;
83 if (p && sscanf(p + 1, "%lu:%lu%c", &off, &len, &c) == 2) {
84 embeddedConn *eConn = (embeddedConn*)pConn;
85 eConn->base.pMethods = &gEmbedded.sIoMethodsV1;
86 char *tmp = strdup(zName);
87 tmp[p - zName] = 0;
88 eConn->fd = open(tmp, O_RDONLY, 0);
89 free(tmp);
90 if (eConn->fd < 0) return SQLITE_CANTOPEN;
91 eConn->offset = off;
92 eConn->len = len;
93 *pOutFlags = SQLITE_OPEN_READONLY;
94 return SQLITE_OK;
98 sqlite3_vfs *pOrigVfs = gEmbedded.pOrigVfs; /* Real VFS */
99 return pOrigVfs->xOpen(pOrigVfs, zName, pConn, flags, pOutFlags);
102 static int
103 embeddedDelete(sqlite3_vfs* /*pVfs*/, const char* zName, int syncDir) {
104 return gEmbedded.pOrigVfs->xDelete(gEmbedded.pOrigVfs, zName, syncDir);
107 static int embeddedAccess(sqlite3_vfs* /*a*/, const char* b, int c, int* d) {
108 return gEmbedded.pOrigVfs->xAccess(gEmbedded.pOrigVfs, b, c, d);
111 static int
112 embeddedFullPathname(sqlite3_vfs* /*a*/, const char* b, int c, char* d) {
113 return gEmbedded.pOrigVfs->xFullPathname(gEmbedded.pOrigVfs, b, c, d);
116 static void* embeddedDlOpen(sqlite3_vfs* /*a*/, const char* b) {
117 return gEmbedded.pOrigVfs->xDlOpen(gEmbedded.pOrigVfs, b);
120 static void embeddedDlError(sqlite3_vfs* /*a*/, int b, char* c) {
121 gEmbedded.pOrigVfs->xDlError(gEmbedded.pOrigVfs, b, c);
124 static void (*embeddedDlSym(sqlite3_vfs* /*a*/, void* b, const char* c))() {
125 return gEmbedded.pOrigVfs->xDlSym(gEmbedded.pOrigVfs, b, c);
128 static void embeddedDlClose(sqlite3_vfs* /*a*/, void* b) {
129 gEmbedded.pOrigVfs->xDlClose(gEmbedded.pOrigVfs, b);
132 static int embeddedRandomness(sqlite3_vfs* /*a*/, int b, char* c) {
133 return gEmbedded.pOrigVfs->xRandomness(gEmbedded.pOrigVfs, b, c);
136 static int embeddedSleep(sqlite3_vfs* /*a*/, int b) {
137 return gEmbedded.pOrigVfs->xSleep(gEmbedded.pOrigVfs, b);
140 static int embeddedCurrentTime(sqlite3_vfs* /*a*/, double* b) {
141 return gEmbedded.pOrigVfs->xCurrentTime(gEmbedded.pOrigVfs, b);
144 static int embeddedGetLastError(sqlite3_vfs* /*a*/, int b, char* c) {
145 return gEmbedded.pOrigVfs->xGetLastError(gEmbedded.pOrigVfs, b, c);
148 static int embeddedCurrentTimeInt64(sqlite3_vfs* /*a*/, sqlite3_int64* b) {
149 return gEmbedded.pOrigVfs->xCurrentTimeInt64(gEmbedded.pOrigVfs, b);
152 static int embeddedClose(sqlite3_file* pConn) {
153 embeddedConn* p = (embeddedConn*)pConn;
154 return close(p->fd) ? SQLITE_OK : SQLITE_ERROR;
157 static int embeddedRead(sqlite3_file* pConn, void* pBuf,
158 int iAmt, sqlite3_int64 iOfst) {
159 embeddedConn* p = (embeddedConn*)pConn;
160 if (iOfst > p->len) return SQLITE_IOERR_READ;
161 int rc = SQLITE_OK;
162 if (iAmt + iOfst > p->len) {
163 rc = SQLITE_IOERR_SHORT_READ;
164 iAmt = p->len - iOfst;
166 iOfst += p->offset;
167 embeddedEnter();
168 if (lseek(p->fd, iOfst, SEEK_SET) != iOfst) {
169 rc = SQLITE_IOERR_READ;
170 } else if (read(p->fd, pBuf, iAmt) != iAmt) {
171 rc = SQLITE_IOERR_READ;
173 embeddedLeave();
174 return rc;
177 static int embeddedWrite(sqlite3_file* /*pConn*/, const void* /*pBuf*/,
178 int /*iAmt*/, sqlite3_int64 /*iOfst*/) {
179 return SQLITE_IOERR_WRITE;
182 static int embeddedTruncate(sqlite3_file* /*pConn*/, sqlite3_int64 /*size*/) {
183 return SQLITE_IOERR_TRUNCATE;
186 static int embeddedSync(sqlite3_file* /*pConn*/, int /*flags*/) {
187 return SQLITE_OK;
190 static int embeddedFileSize(sqlite3_file* pConn, sqlite3_int64* pSize) {
191 embeddedConn* p = (embeddedConn*)pConn;
192 *pSize = p->len;
193 return SQLITE_OK;
196 static int embeddedLock(sqlite3_file* /*pConn*/, int /*lock*/) {
197 return SQLITE_OK;
200 static int embeddedUnlock(sqlite3_file* /*pConn*/, int /*lock*/) {
201 return SQLITE_OK;
204 static int
205 embeddedCheckReservedLock(sqlite3_file* /*pConn*/, int* /*pResOut*/) {
206 return SQLITE_IOERR_CHECKRESERVEDLOCK;
209 static int
210 embeddedFileControl(sqlite3_file* /*pConn*/, int /*op*/, void* /*pArg*/) {
211 return SQLITE_OK;
214 static int embeddedSectorSize(sqlite3_file* /*pConn*/) {
215 return 0;
218 static int embeddedDeviceCharacteristics(sqlite3_file* /*pConn*/) {
219 return 0;
222 int sqlite3_embedded_initialize(const char* zOrigVfsName, int makeDefault) {
223 sqlite3_vfs* pOrigVfs;
224 if (gEmbedded.isInitialized) return SQLITE_MISUSE;
225 pOrigVfs = sqlite3_vfs_find(zOrigVfsName);
226 if (pOrigVfs==0) return SQLITE_ERROR;
227 assert(pOrigVfs!=&gEmbedded.sThisVfs);
228 gEmbedded.pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
229 if (!gEmbedded.pMutex) {
230 return SQLITE_NOMEM;
233 gEmbedded.isInitialized = 1;
234 gEmbedded.pOrigVfs = pOrigVfs;
235 gEmbedded.sThisVfs = *pOrigVfs;
236 gEmbedded.sThisVfs.szOsFile += sizeof(embeddedConn);
237 gEmbedded.sThisVfs.zName = "embedded";
238 gEmbedded.sThisVfs.xOpen = embeddedOpen;
239 gEmbedded.sThisVfs.xDelete = embeddedDelete;
240 gEmbedded.sThisVfs.xAccess = embeddedAccess;
241 gEmbedded.sThisVfs.xFullPathname = embeddedFullPathname;
242 gEmbedded.sThisVfs.xDlOpen = embeddedDlOpen;
243 gEmbedded.sThisVfs.xDlError = embeddedDlError;
244 gEmbedded.sThisVfs.xDlSym = embeddedDlSym;
245 gEmbedded.sThisVfs.xDlClose = embeddedDlClose;
246 gEmbedded.sThisVfs.xRandomness = embeddedRandomness;
247 gEmbedded.sThisVfs.xSleep = embeddedSleep;
248 gEmbedded.sThisVfs.xCurrentTime = embeddedCurrentTime;
249 gEmbedded.sThisVfs.xGetLastError = embeddedGetLastError;
250 gEmbedded.sThisVfs.xCurrentTimeInt64 = embeddedCurrentTimeInt64;
252 gEmbedded.sIoMethodsV1.iVersion = 1;
253 gEmbedded.sIoMethodsV1.xClose = embeddedClose;
254 gEmbedded.sIoMethodsV1.xRead = embeddedRead;
255 gEmbedded.sIoMethodsV1.xWrite = embeddedWrite;
256 gEmbedded.sIoMethodsV1.xTruncate = embeddedTruncate;
257 gEmbedded.sIoMethodsV1.xSync = embeddedSync;
258 gEmbedded.sIoMethodsV1.xFileSize = embeddedFileSize;
259 gEmbedded.sIoMethodsV1.xLock = embeddedLock;
260 gEmbedded.sIoMethodsV1.xUnlock = embeddedUnlock;
261 gEmbedded.sIoMethodsV1.xCheckReservedLock = embeddedCheckReservedLock;
262 gEmbedded.sIoMethodsV1.xFileControl = embeddedFileControl;
263 gEmbedded.sIoMethodsV1.xSectorSize = embeddedSectorSize;
264 gEmbedded.sIoMethodsV1.xDeviceCharacteristics =
265 embeddedDeviceCharacteristics;
267 sqlite3_vfs_register(&gEmbedded.sThisVfs, makeDefault);
269 return SQLITE_OK;
272 int sqlite3_embedded_shutdown() {
273 if ( gEmbedded.isInitialized==0 ) return SQLITE_MISUSE;
274 gEmbedded.isInitialized = 0;
275 sqlite3_mutex_free(gEmbedded.pMutex);
276 sqlite3_vfs_unregister(&gEmbedded.sThisVfs);
277 memset(&gEmbedded, 0, sizeof(gEmbedded));
278 return SQLITE_OK;