25#include <sqlite3ext.h>
26static SQLITE_EXTENSION_INIT1
29#if defined(_WIN32) || defined(_WIN64)
49#define ZIP_LOCAL_HEADER_SIG 0x04034b50
50#define ZIP_LOCAL_HEADER_FLAGS 6
51#define ZIP_LOCAL_PATHLEN_OFFS 26
52#define ZIP_LOCAL_EXTRA_OFFS 28
53#define ZIP_LOCAL_HEADER_LEN 30
55#define ZIP_CENTRAL_HEADER_SIG 0x02014b50
56#define ZIP_CENTRAL_HEADER_FLAGS 8
57#define ZIP_CENTRAL_HEADER_LEN 46
58#define ZIP_CENTRAL_COMPMETH_OFFS 10
59#define ZIP_CENTRAL_MTIME_OFFS 12
60#define ZIP_CENTRAL_MDATE_OFFS 14
61#define ZIP_CENTRAL_CRC32_OFFS 16
62#define ZIP_CENTRAL_COMPLEN_OFFS 20
63#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24
64#define ZIP_CENTRAL_PATHLEN_OFFS 28
65#define ZIP_CENTRAL_EXTRALEN_OFFS 30
66#define ZIP_CENTRAL_COMMENTLEN_OFFS 32
67#define ZIP_CENTRAL_LOCALHDR_OFFS 42
69#define ZIP_CENTRAL_END_SIG 0x06054b50
70#define ZIP_CENTRAL_END_LEN 22
71#define ZIP_CENTRAL_ENTS_OFFS 8
72#define ZIP_CENTRAL_DIRSIZE_OFFS 12
73#define ZIP_CENTRAL_DIRSTART_OFFS 16
75#define ZIP_COMPMETH_STORED 0
76#define ZIP_COMPMETH_DEFLATED 8
78#define zip_read_int(p) \
79 ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
80#define zip_read_short(p) \
81 ((p)[0] | ((p)[1] << 8))
92#if defined(_WIN32) || defined(_WIN64)
129#ifdef SQLITE_OPEN_URI
137typedef struct mem_blk {
138#define MEM_MAGIC "MVFS"
141#if defined(_WIN32) || defined(_WIN64)
146 sqlite3_mutex *mutex;
151 unsigned long length;
161typedef struct mem_file {
173static char mem_vfs_name[64];
186#if defined(_WIN32) || defined(_WIN64)
187 HANDLE h, mh = INVALID_HANDLE_VALUE;
189 unsigned char *data = 0;
193 unsigned char *data = MAP_FAILED;
195 int nentries, baseoffs = 0, i;
197 unsigned char *p, *q;
202#if defined(_WIN32) || defined(_WIN64)
203 h = CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
204 if (h == INVALID_HANDLE_VALUE) {
207 length = GetFileSize(h, 0);
211 mh = CreateFileMapping(h, 0, PAGE_READONLY, 0, length, 0);
212 if (mh == INVALID_HANDLE_VALUE) {
215 data = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, length);
220 fd = open(filename, O_RDONLY);
224 length = lseek(fd, 0, SEEK_END);
228 data = (
unsigned char *) mmap(0, length, PROT_READ,
229 MAP_FILE | MAP_PRIVATE, fd, 0);
230 if (data == MAP_FAILED) {
256 if (p < data || p > data + length || q < data || q > data + length) {
261 for (i = 0; i < nentries; i++) {
262 int pathlen, comlen, extra;
275 zip = sqlite3_malloc(
sizeof (
zip_file) +
276 nentries *
sizeof (
unsigned char *));
280#if defined(_WIN32) || defined(_WIN64)
281 zip->h = zip->mh = INVALID_HANDLE_VALUE;
288 for (i = 0; i < nentries; i++) {
289 int pathlen, comlen, extra;
304#if defined(_WIN32) || defined(_WIN64)
313#if defined(_WIN32) || defined(_WIN64)
315 UnmapViewOfFile(data);
317 if (mh != INVALID_HANDLE_VALUE) {
320 if (h != INVALID_HANDLE_VALUE) {
324 if (data != MAP_FAILED) {
325 munmap(data, length);
343#if defined(_WIN32) || defined(_WIN64)
345 UnmapViewOfFile(zip->
data);
347 if (zip->mh != INVALID_HANDLE_VALUE) {
348 CloseHandle(zip->mh);
350 if (zip->h != INVALID_HANDLE_VALUE) {
377 ret = sqlite3_malloc(strlen(in) + 1);
380 if ((c ==
'"') || (c ==
'\'')) {
382 if ((i > 0) && (in[i] == c)) {
413 sqlite3_vtab **vtabp,
char **errp)
416 int rc = SQLITE_ERROR;
421 *errp = sqlite3_mprintf(
"input file name missing");
427 sqlite3_free(filename);
430 *errp = sqlite3_mprintf(
"unable to open input file");
433 vtab = sqlite3_malloc(
sizeof(
zip_vtab) + 6 +
434 strlen(argv[1]) + strlen(argv[2]));
437 *errp = sqlite3_mprintf(
"out of memory");
440 memset(vtab, 0,
sizeof (*vtab));
442 strcat(vtab->
tblname, argv[1]);
443 strcat(vtab->
tblname,
"\".\"");
444 strcat(vtab->
tblname, argv[2]);
448 rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(path, comp, mtime, "
449 "crc32, length, data, clength, cdata, isdir)");
450 if (rc != SQLITE_OK) {
453 *errp = sqlite3_mprintf(
"table definition failed (error %d)", rc);
456 *vtabp = &vtab->
vtab;
474 const char *
const *argv,
475 sqlite3_vtab **vtabp,
char **errp)
524 unsigned char **entries = 0;
525 sqlite3_stmt *
stmt = 0;
531 entries = sqlite3_malloc(tab->
zip->
nentries * sizeof (entries));
532 sql = sqlite3_mprintf(
"SELECT rowid FROM %s ORDER BY path",
534 if (sql && entries) {
535 rc = sqlite3_prepare_v2(tab->
db, sql, -1, &
stmt, 0);
536 if ((rc == SQLITE_OK) &&
stmt) {
539 rc = sqlite3_step(
stmt);
540 if (rc != SQLITE_ROW) {
543 tmp = sqlite3_column_int(
stmt, 0);
544 entries[count++] = (
unsigned char *) tmp;
546 if ((rc == SQLITE_DONE) && (count == tab->
zip->
nentries)) {
547 for (i = 0; i < count; i++) {
548 tmp = (size_t) entries[i];
550 entries[i] = (
unsigned char *) tmp;
552 memcpy(tab->
zip->
entries, entries, i * sizeof (entries));
558 sqlite3_finalize(
stmt);
564 sqlite3_free(entries);
572 for (i = 0; i < info->nConstraint; i++) {
573 if (info->aConstraint[i].usable &&
574 (info->aConstraint[i].iColumn == 0)) {
575 if (info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_EQ) {
577 info->aConstraintUsage[i].argvIndex = 1;
578 info->aConstraintUsage[i].omit = 1;
579 info->estimatedCost = 1.0;
581 }
else if (info->aConstraint[i].op ==
582 SQLITE_INDEX_CONSTRAINT_MATCH) {
584 info->aConstraintUsage[i].argvIndex = 1;
585 info->aConstraintUsage[i].omit = 1;
586 info->estimatedCost = 2.0;
592 if (info->nOrderBy > 0) {
593 if ((info->aOrderBy[0].iColumn == 0) && !info->aOrderBy[0].desc) {
594 info->orderByConsumed = 1;
610 zip_cursor *cur = sqlite3_malloc(
sizeof(*cur));
671 const char *idxStr,
int argc, sqlite3_value **argv)
683 if (idxNum && (argc > 0)) {
684 int i, k, d, found, leneq, len;
687 eq = (
unsigned char *) sqlite3_value_text(argv[0]);
693 unsigned char *p = (
unsigned char *) strrchr((
char *) eq,
'*');
695 if (!p || (p[1] !=
'\0')) {
700 leneq = sqlite3_value_bytes(argv[0]);
719 }
else if (len != leneq) {
780 unsigned char *data = 0;
781 unsigned char *dest = 0;
788 sqlite3_result_error(ctx,
"out of bounds", -1);
795 sqlite3_result_error(ctx,
"out of bounds", -1);
804 sqlite3_result_text(ctx, (
char *) data, length, SQLITE_TRANSIENT);
808 sqlite3_result_int(ctx, length);
816 sprintf(mtbuf,
"%04d-%02d-%02d %02d:%02d:%02d",
817 (date >> 9) + 1980, (date >> 5) & 0xf, date & 0x1f,
818 time >> 11, (time >> 5) & 0x3f, (time & 0x1f) << 1);
819 sqlite3_result_text(ctx, mtbuf, -1, SQLITE_TRANSIENT);
824 sqlite3_result_int(ctx, length);
828 sqlite3_result_int(ctx, length);
832 int clength, offs, extra, pathlen, cmeth;
847 if ((offs + clength) > tab->
zip->
length) {
852 sqlite3_result_blob(ctx, data, clength, SQLITE_TRANSIENT);
858 stream.zalloc = Z_NULL;
859 stream.zfree = Z_NULL;
860 stream.next_in = data;
861 stream.avail_in = clength;
862 stream.next_out = dest = sqlite3_malloc(length);
863 stream.avail_out = length;
868 if (inflateInit2(&stream, -15) != Z_OK) {
871 err = inflate(&stream, Z_SYNC_FLUSH);
873 if ((err == Z_STREAM_END) ||
874 ((err == Z_OK) && (stream.avail_in == 0))) {
875 sqlite3_result_blob(ctx, dest, length, sqlite3_free);
883 sqlite3_result_null(ctx);
888 sqlite3_result_int(ctx, length);
892 int clength, offs, extra, pathlen;
906 if ((offs + clength) > tab->
zip->
length) {
910 sqlite3_result_blob(ctx, data, clength, SQLITE_TRANSIENT);
916 sqlite3_result_int(ctx, (length > 0 && data[length - 1] ==
'/'));
919 sqlite3_result_error(ctx,
"invalid column number", -1);
962 unsigned char *q = (
unsigned char *) sqlite3_value_text(argv[0]);
963 unsigned char *p = (
unsigned char *) sqlite3_value_text(argv[1]);
966 unsigned char *eq = (
unsigned char *) strrchr((
char *) q,
'*');
969 if (eq && (eq[1] ==
'\0')) {
972 lenp = strlen((
char *) p);
973 if ((lenp >= lenq) && !memcmp(p, q, lenq)) {
980 sqlite3_result_int(ctx, ret);
995 void (**pfunc)(sqlite3_context *,
int, sqlite3_value **),
998 if ((narg == 2) && !strcmp(name,
"match")) {
1006#if (SQLITE_VERSION_NUMBER > 3004000)
1015zip_vtab_rename(sqlite3_vtab *vtab,
const char *newname)
1046#if (SQLITE_VERSION_NUMBER > 3004000)
1062 unsigned char *data;
1065 sqlite3_result_error(ctx,
"need one argument", -1);
1067 data = (
unsigned char *) sqlite3_value_blob(argv[0]);
1068 length = sqlite3_value_bytes(argv[0]);
1069 crc = crc32(0, 0, 0);
1070 if (data && (length > 0)) {
1071 crc = crc32(crc, data, length);
1073 sqlite3_result_int(ctx, crc);
1086 int err, length, dlength, avail;
1087 unsigned char *data, *dest, *newdest;
1091 sqlite3_result_error(ctx,
"need one argument", -1);
1094 data = (
unsigned char *) sqlite3_value_blob(argv[0]);
1095 length = sqlite3_value_bytes(argv[0]);
1096 stream.zalloc = Z_NULL;
1097 stream.zfree = Z_NULL;
1098 stream.next_in = data;
1099 stream.avail_in = length;
1101 stream.next_out = dest = sqlite3_malloc(avail);
1102 stream.avail_out = avail;
1107 if (inflateInit2(&stream, -15) != Z_OK) {
1112 err = inflate(&stream, Z_SYNC_FLUSH);
1113 if ((err == Z_STREAM_END) ||
1114 ((err == Z_OK) && (stream.avail_in == 0))) {
1115 dlength += length - stream.avail_out;
1116 newdest = sqlite3_realloc(dest, dlength);
1117 inflateEnd(&stream);
1124 sqlite3_result_error_nomem(ctx);
1127 sqlite3_result_blob(ctx, newdest, dlength, sqlite3_free);
1130 if ((err == Z_BUF_ERROR) || (err == Z_OK)) {
1131 newdest = sqlite3_realloc(dest, avail + length);
1132 dlength += length - stream.avail_out;
1134 inflateEnd(&stream);
1138 stream.next_out = newdest + (stream.next_out - dest);
1140 stream.avail_out += length;
1142 inflateEnd(&stream);
1144 sqlite3_result_error(ctx,
"inflate error", -1);
1161 unsigned long avail, length;
1162 unsigned char *data, *dest = 0;
1165 if ((argc < 1) || (argc > 2)) {
1166 sqlite3_result_error(ctx,
"need one or two arguments", -1);
1170 level = sqlite3_value_int(argv[1]);
1172 data = (
unsigned char *) sqlite3_value_blob(argv[0]);
1173 length = sqlite3_value_bytes(argv[0]);
1174 stream.zalloc = Z_NULL;
1175 stream.zfree = Z_NULL;
1176 stream.next_in = data;
1177 stream.avail_in = length;
1178 stream.next_out = 0;
1179 stream.avail_out = 0;
1181 if (deflateInit2(&stream, level, Z_DEFLATED, -15, 8,
1182 Z_DEFAULT_STRATEGY) != Z_OK) {
1185 avail = deflateBound(&stream, length);
1187 sqlite3_result_null(ctx);
1190 stream.next_out = dest = sqlite3_malloc(avail);
1191 stream.avail_out = avail;
1193 sqlite3_result_error_nomem(ctx);
1196 err = deflate(&stream, Z_FINISH);
1197 if (err != Z_STREAM_END) {
1198 deflateEnd(&stream);
1203 sqlite3_result_error(ctx,
"deflate error", -1);
1206 length = stream.total_out;
1207 err = deflateEnd(&stream);
1211 sqlite3_result_blob(ctx, dest, length, sqlite3_free);
1225 unsigned long length, dlength;
1226 unsigned char *data, *dest;
1228 if ((argc < 1) || (argc > 2)) {
1229 sqlite3_result_error(ctx,
"need one or two arguments", -1);
1233 level = sqlite3_value_int(argv[1]);
1235 data = (
unsigned char *) sqlite3_value_blob(argv[0]);
1236 length = sqlite3_value_bytes(argv[0]);
1237 dlength = compressBound(length);
1238 dest = sqlite3_malloc(dlength);
1240 sqlite3_result_error_nomem(ctx);
1243 err = compress2(dest, &dlength, data, length, level);
1245 sqlite3_result_blob(ctx, dest, dlength, sqlite3_free);
1248 if (err == Z_MEM_ERROR) {
1249 sqlite3_result_error(ctx,
"memory error", -1);
1250 }
else if (err == Z_BUF_ERROR) {
1251 sqlite3_result_error(ctx,
"buffer error", -1);
1253 sqlite3_result_error(ctx,
"compress error", -1);
1258#ifdef SQLITE_OPEN_URI
1268mem_createmb(
const unsigned char *data,
unsigned long length)
1271#if defined(_WIN32) || defined(_WIN64)
1278#if defined(_WIN32) || defined(_WIN64)
1279 size =
sizeof (mem_blk) + length;
1280 mh = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE,
1282 if (mh == INVALID_HANDLE_VALUE) {
1285 mb = (mem_blk *) MapViewOfFile(mh, FILE_MAP_ALL_ACCESS, 0, 0, length);
1290 psize = sysconf(_SC_PAGESIZE);
1292 mb = (mem_blk *) sqlite3_malloc(
sizeof (mem_blk));
1297 mb->data = (
unsigned char *) mmap(0, size, PROT_READ | PROT_WRITE,
1298 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1299 if (mb->data == MAP_FAILED) {
1304 size =
sizeof (mem_blk) + psize + length + 1;
1305 mb = (mem_blk *) mmap(0, size, PROT_READ | PROT_WRITE,
1306 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1307 if (mb == MAP_FAILED) {
1313 memcpy(mb->magic, MEM_MAGIC, 4);
1316 mb->length = length;
1317#if defined(_WIN32) || defined(_WIN64)
1319 mb->data = (
unsigned char *) (mb + 1);
1320 memcpy(mb->data, data, length);
1324 mb->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
1325 sqlite3_mutex_enter(mb->mutex);
1327 memcpy(mb->data, data, length);
1329 if (psize >=
sizeof (mem_blk)) {
1330 mb->data = (
unsigned char *) mb + psize;
1331 memcpy(mb->data, data, length);
1333 mprotect(mb->data, length, PROT_READ);
1336 mb->data = (
unsigned char *) (mb + 1);
1337 memcpy(mb->data, data, length);
1351mem_destroymb(mem_blk *mb)
1353#if defined(_WIN32) || defined(_WIN64)
1358 memset(mb->magic, 0, 4);
1359#if defined(_WIN32) || defined(_WIN64)
1361 UnmapViewOfFile(mb);
1365 munmap(mb->data, mb->size);
1366 sqlite3_mutex_leave(mb->mutex);
1367 sqlite3_mutex_free(mb->mutex);
1370 munmap(mb, mb->size);
1383mem_close(sqlite3_file *file)
1385 mem_file *mf = (mem_file *) file;
1386 mem_blk *mb = mf->mb;
1390 sqlite3_mutex_enter(mb->mutex);
1396 if (mb->opened <= 0) {
1401 sqlite3_mutex_leave(mb->mutex);
1419mem_read(sqlite3_file *file,
void *buf,
int len, sqlite_int64 offs)
1421 mem_file *mf = (mem_file *) file;
1422 mem_blk *mb = mf->mb;
1423 int rc = SQLITE_IOERR_READ;
1427 sqlite3_mutex_enter(mb->mutex);
1430 if (mb && (offs <= mb->length)) {
1432 if (offs + len > mb->length) {
1433 rc = SQLITE_IOERR_SHORT_READ;
1434 len = mb->length - offs;
1436 memcpy(buf, mb->data + offs, len);
1440 sqlite3_mutex_leave(mb->mutex);
1455mem_truncate_unlocked(sqlite3_file *file, sqlite_int64 offs)
1457mem_truncate(sqlite3_file *file, sqlite_int64 offs)
1461 mem_file *mf = (mem_file *) file;
1462 mem_blk *mb = mf->mb;
1464 long psize = mb->psize;
1465 unsigned long length = offs;
1469 if ((psize > 0) && (size / psize == mb->size / psize)) {
1472 p = mremap(mb->data, mb->size, size, MREMAP_MAYMOVE);
1474 if (p == MAP_FAILED) {
1475 return SQLITE_IOERR_TRUNCATE;
1478 mb->length = length;
1482 return SQLITE_IOERR_TRUNCATE;
1488mem_truncate(sqlite3_file *file, sqlite_int64 offs)
1490 mem_file *mf = (mem_file *) file;
1491 mem_blk *mb = mf->mb;
1492 int rc = SQLITE_IOERR_TRUNCATE;
1495 sqlite3_mutex_enter(mb->mutex);
1496 rc = mem_truncate_unlocked(file, offs);
1497 sqlite3_mutex_leave(mb->mutex);
1513mem_write(sqlite3_file *file,
const void *buf,
int len, sqlite_int64 offs)
1516 mem_file *mf = (mem_file *) file;
1517 mem_blk *mb = mf->mb;
1519 sqlite3_mutex_enter(mb->mutex);
1520 if (offs + len > mb->length) {
1521 if (mem_truncate_unlocked(file, offs + len) != SQLITE_OK) {
1522 sqlite3_mutex_leave(mb->mutex);
1523 return SQLITE_IOERR_WRITE;
1526 memcpy(mb->data + offs, buf, len);
1527 sqlite3_mutex_leave(mb->mutex);
1530 return SQLITE_IOERR_WRITE;
1542mem_sync(sqlite3_file *file,
int flags)
1547 return SQLITE_IOERR_FSYNC;
1559mem_filesize(sqlite3_file *file, sqlite_int64 *size)
1561 mem_file *mf = (mem_file *) file;
1562 mem_blk *mb = mf->mb;
1566 sqlite3_mutex_enter(mb->mutex);
1570 sqlite3_mutex_leave(mb->mutex);
1574 return SQLITE_IOERR_FSTAT;
1585mem_lock(sqlite3_file *file,
int lck)
1588 mem_file *mf = (mem_file *) file;
1589 mem_blk *mb = mf->mb;
1590 int rc = SQLITE_IOERR_LOCK;
1593 sqlite3_mutex_enter(mb->mutex);
1596 if ((mf->lock == 0) && (mb->lcnt == 0)) {
1600 }
else if ((mf->lock > 0) && (mb->lcnt == 1)) {
1605 sqlite3_mutex_leave(mb->mutex);
1621mem_unlock(sqlite3_file *file,
int lck)
1624 mem_file *mf = (mem_file *) file;
1625 mem_blk *mb = mf->mb;
1626 int rc = SQLITE_IOERR_UNLOCK;
1629 sqlite3_mutex_enter(mb->mutex);
1630 if (mf->lock == lck) {
1632 }
else if (lck == 0) {
1638 }
else if ((lck < mf->lock) && (mb->lcnt != 0)) {
1642 sqlite3_mutex_leave(mb->mutex);
1658mem_checkreservedlock(sqlite3_file *file,
int *out)
1661 mem_file *mf = (mem_file *) file;
1662 mem_blk *mb = mf->mb;
1663 int rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
1666 sqlite3_mutex_enter(mb->mutex);
1667 *out = mf->lock >= 2;
1668 sqlite3_mutex_leave(mb->mutex);
1689mem_filecontrol(sqlite3_file *file,
int op,
void *arg)
1691#ifdef SQLITE_FCNTL_PRAGMA
1692 if (op == SQLITE_FCNTL_PRAGMA) {
1693 return SQLITE_NOTFOUND;
1706mem_sectorsize(sqlite3_file *file)
1718mem_devicecharacteristics(sqlite3_file *file)
1727static sqlite3_io_methods mem_methods = {
1737 mem_checkreservedlock,
1740 mem_devicecharacteristics
1754mem_open(sqlite3_vfs *vfs,
const char *name, sqlite3_file *file,
1755 int flags,
int *outflags)
1757 mem_file *mf = (mem_file *) file;
1760 unsigned long long t = 0;
1762 unsigned long t = 0;
1764#if !defined(_WIN32) && !defined(_WIN64)
1771 return SQLITE_IOERR;
1773 if (flags & (SQLITE_OPEN_MAIN_JOURNAL |
1776 SQLITE_OPEN_READWRITE |
1778 SQLITE_OPEN_CREATE)) {
1779 return SQLITE_CANTOPEN;
1782 sscanf(name + 1,
"%I64x", &t);
1784 t = strtoul(name + 1, 0, 16);
1788 return SQLITE_CANTOPEN;
1790#if !defined(_WIN32) && !defined(_WIN64)
1791 if (pipe(pfd) < 0) {
1792 return SQLITE_CANTOPEN;
1794 n = (write(pfd[1], (
char *) mb,
sizeof (mem_blk)) < 0) ? errno : 0;
1799 return SQLITE_CANTOPEN;
1801 n = read(pfd[0], (
char *) &mb0,
sizeof (mem_blk));
1802 if (n !=
sizeof (mem_blk)) {
1805 if (memcmp(mb0.magic, MEM_MAGIC, 4) == 0) {
1807 n = (write(pfd[1], (
char *) mb0.data, 1) < 0) ? errno : 0;
1812 if (mb0.length > 0) {
1813 n = (write(pfd[1], (
char *) mb0.data + mb0.length - 1, 1) < 0)
1822 sqlite3_mutex_enter(mb->mutex);
1826 sqlite3_mutex_leave(mb->mutex);
1832 if (memcmp(mb->magic, MEM_MAGIC, 4) == 0) {
1835 return SQLITE_CANTOPEN;
1838 memset(mf, 0,
sizeof (mem_file));
1840 mf->base.pMethods = &mem_methods;
1856mem_delete(sqlite3_vfs *vfs,
const char *name,
int sync)
1858 return SQLITE_IOERR_DELETE;
1871mem_access(sqlite3_vfs *vfs,
const char *name,
int flags,
int *outflags)
1876 t = strtol(name + 1, &endp, 16);
1879 (flags == SQLITE_ACCESS_READWRITE) ||
1899mem_fullpathname(sqlite3_vfs *vfs,
const char *name,
int len,
char *out)
1901 strncpy(out, name, len);
1902 out[len - 1] =
'\0';
1914mem_dlopen(sqlite3_vfs *vfs,
const char *name)
1927mem_dlerror(sqlite3_vfs *vfs,
int len,
char *out)
1929 static const char *errtxt =
"Loadable extensions are not supported";
1931 strncpy(out, errtxt, strlen(errtxt));
1932 out[len - 1] =
'\0';
1944(*mem_dlsym(sqlite3_vfs *vfs,
void *handle,
const char *sym))(void)
1956mem_dlclose(sqlite3_vfs *vfs,
void *handle)
1969mem_randomness(sqlite3_vfs *vfs,
int len,
char *out)
1971 sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
1973 return ovfs->xRandomness(ovfs, len, out);
1984mem_sleep(sqlite3_vfs *vfs,
int micro)
1986 sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
1988 return ovfs->xSleep(ovfs, micro);
1999mem_currenttime(sqlite3_vfs *vfs,
double *out)
2001 sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
2003 return ovfs->xCurrentTime(ovfs, out);
2010static sqlite3_vfs mem_vfs = {
2055blob_attach_func(sqlite3_context *ctx,
int argc, sqlite3_value **argv)
2057 unsigned long length;
2058 const unsigned char *data;
2067 sqlite3_result_error(ctx,
"need two arguments", -1);
2070 data = (
const unsigned char *) sqlite3_value_blob(argv[0]);
2071 length = sqlite3_value_bytes(argv[0]);
2072 if (!data || !length) {
2073 sqlite3_result_error(ctx,
"empty blob", -1);
2076 mb = mem_createmb(data, length);
2078 sqlite3_result_error(ctx,
"cannot map blob", -1);
2081 sql = sqlite3_mprintf(
"ATTACH "
2093 "cache=private' AS %Q",
2095 (
unsigned long long) mb,
2100 (
char *) sqlite3_value_text(argv[1]));
2102 sqlite3_result_error(ctx,
"cannot map blob", -1);
2107 sqlite3_mutex_leave(mb->mutex);
2109 if (sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0)
2112 sqlite3_result_error(ctx,
"cannot attach blob", -1);
2114 sqlite3_mutex_enter(mb->mutex);
2119 sqllen = strlen(sql);
2120 sqlite3_snprintf(sqllen, sql,
"PRAGMA %Q.synchronous = OFF",
2121 (
char *) sqlite3_value_text(argv[1]));
2122 sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0);
2124 sqlite3_snprintf(sqllen, sql,
"PRAGMA %Q.journal_mode = OFF",
2125 (
char *) sqlite3_value_text(argv[1]));
2126 if (sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0)
2132 sqlite3_mutex_enter(mb->mutex);
2134 if (--mb->opened < 1) {
2135 sqlite3_snprintf(sqllen, sql,
"DETACH %Q",
2136 (
char *) sqlite3_value_text(argv[1]));
2137 sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0);
2139 sqlite3_result_error(ctx,
"cannot attach blob", -1);
2144 sqlite3_mutex_leave(mb->mutex);
2146 sqlite3_snprintf(sqllen, sql,
2147 "file:/%lX?vfs=%s&mode=rw&cache=private",
2148 (
unsigned long) mb, mem_vfs_name);
2149 sqlite3_result_text(ctx, sql, -1, sqlite3_free);
2154 sqlite3_result_null(ctx);
2175blob_dump_func(sqlite3_context *ctx,
int argc, sqlite3_value **argv)
2179 unsigned long long addr = 0;
2181 unsigned long addr = 0;
2189 sqlite3_result_error(ctx,
"need one argument", -1);
2192 uri = (
char *) sqlite3_value_text(argv[0]);
2194 if (!uri || (sscanf(uri,
2196 "file:/%I64X?vfs=%63[^&]",
2198 "file:/%lX?vfs=%63[^&]",
2200 &addr, vfs) != 2)) {
2202 sqlite3_result_error(ctx,
"invalid object", -1);
2206 if ((strcmp(mem_vfs_name, vfs) != 0) || (addr == 0)) {
2210 if (pipe(pfd) < 0) {
2213 n = (write(pfd[1], (
char *) addr, 1) < 0) ? errno : 0;
2219 mb = (mem_blk *) addr;
2220 if (memcmp(mb->magic, MEM_MAGIC, 4) != 0) {
2223 sqlite3_mutex_enter(mb->mutex);
2224 sqlite3_result_blob(ctx, mb->data, mb->length, SQLITE_STATIC);
2225 sqlite3_mutex_leave(mb->mutex);
2227 sqlite3_result_error(ctx,
"unsupported function", -1);
2245 sqlite3_create_function(db,
"crc32", 1, SQLITE_UTF8,
2247 sqlite3_create_function(db,
"inflate", 1, SQLITE_UTF8,
2249 sqlite3_create_function(db,
"deflate", 1, SQLITE_UTF8,
2251 sqlite3_create_function(db,
"uncompress", 1, SQLITE_UTF8,
2253 sqlite3_create_function(db,
"compress", -1, SQLITE_UTF8,
2255#ifdef SQLITE_OPEN_URI
2256 if (!mem_vfs.pAppData) {
2257 sqlite3_vfs *parent = sqlite3_vfs_find(0);
2260 sqlite3_snprintf(
sizeof (mem_vfs_name), mem_vfs_name,
2262 "mem_vfs_%llX", (
unsigned long long) &mem_vfs
2264 "mem_vfs_%lX", (
unsigned long) &mem_vfs
2267 if (sqlite3_vfs_register(&mem_vfs, 0) == SQLITE_OK) {
2268 mem_vfs.pAppData = (
void *) parent;
2272 if (mem_vfs.pAppData) {
2273 sqlite3_create_function(db,
"blob_attach", 2, SQLITE_UTF8,
2274 (
void *) db, blob_attach_func, 0, 0);
2275 sqlite3_create_function(db,
"blob_dump", 1, SQLITE_UTF8,
2276 (
void *) db, blob_dump_func, 0, 0);
2279 return sqlite3_create_module(db,
"zipfile", &
zip_vtab_mod, 0);
2294 const sqlite3_api_routines *api)
2296 SQLITE_EXTENSION_INIT2(api);
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Driver internal structure representing SQL statement (HSTMT).
Structure to describe ZIP virtual table cursor.
int nmatches
For filter EQ.
int usematches
For filter EQ.
int pos
ZIP file position.
int * matches
For filter EQ.
sqlite3_vtab_cursor cursor
SQLite virtual table cursor.
Structure to implement ZIP file handle.
unsigned char * entries[1]
Pointer to first entry.
off_t length
length of ZIP file
int baseoffs
Global offset for embedded ZIP files.
int nentries
Number of directory entries.
unsigned char * data
mmap()'ed ZIP file
Structure to describe a ZIP virtual table.
sqlite3 * db
Open database.
sqlite3_vtab vtab
SQLite virtual table.
int sorted
1 = sorted by path, -1 = sorting, 0 = unsorted
char tblname[1]
Name, format "database".
zip_file * zip
ZIP file handle.
static const sqlite3_module zip_vtab_mod
SQLite module descriptor.
static int zip_vtab_filter(sqlite3_vtab_cursor *cursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv)
Filter function for virtual table.
#define ZIP_CENTRAL_MTIME_OFFS
#define ZIP_COMPMETH_STORED
static int zip_vtab_close(sqlite3_vtab_cursor *cursor)
Close virtual table cursor.
static void zip_vtab_matchfunc(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Internal MATCH function for virtual table.
#define ZIP_LOCAL_PATHLEN_OFFS
static void zip_compress_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Compress data given blob and optional compression level.
#define ZIP_CENTRAL_DIRSIZE_OFFS
#define ZIP_LOCAL_EXTRA_OFFS
#define ZIP_CENTRAL_CRC32_OFFS
#define ZIP_CENTRAL_DIRSTART_OFFS
static int zip_vtab_rowid(sqlite3_vtab_cursor *cursor, sqlite_int64 *rowidp)
Return current rowid of virtual table cursor.
static int zip_vtab_next(sqlite3_vtab_cursor *cursor)
Retrieve next row from virtual table cursor.
static int zip_vtab_bestindex(sqlite3_vtab *vtab, sqlite3_index_info *info)
Determines information for filter function according to constraints.
static void zip_close(zip_file *zip)
Close ZIP file handle.
#define zip_read_short(p)
#define ZIP_CENTRAL_COMMENTLEN_OFFS
#define ZIP_CENTRAL_COMPLEN_OFFS
#define ZIP_CENTRAL_PATHLEN_OFFS
#define ZIP_LOCAL_HEADER_LEN
#define ZIP_CENTRAL_COMPMETH_OFFS
static int zip_vtab_init(sqlite3 *db)
Module initializer creating SQLite module and functions.
int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api)
Initializer for SQLite extension load mechanism.
static int zip_vtab_connect(sqlite3 *db, void *aux, int argc, const char *const *argv, sqlite3_vtab **vtabp, char **errp)
Connect to virtual table.
static zip_file * zip_open(const char *filename)
Memory map ZIP file for reading and return handle to it.
static void zip_crc32_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Compute CRC32 given blob.
#define ZIP_CENTRAL_END_LEN
static char * unquote(char const *in)
Strip off quotes given string.
static int zip_vtab_open(sqlite3_vtab *vtab, sqlite3_vtab_cursor **cursorp)
Open virtual table and return cursor.
#define ZIP_CENTRAL_HEADER_LEN
#define ZIP_CENTRAL_END_SIG
#define ZIP_CENTRAL_UNCOMPLEN_OFFS
static int zip_vtab_disconnect(sqlite3_vtab *vtab)
Disconnect virtual table.
static int zip_vtab_destroy(sqlite3_vtab *vtab)
Destroy virtual table.
static int zip_vtab_create(sqlite3 *db, void *aux, int argc, const char *const *argv, sqlite3_vtab **vtabp, char **errp)
Create virtual table.
#define ZIP_CENTRAL_ENTS_OFFS
#define ZIP_CENTRAL_MDATE_OFFS
static void zip_inflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Inflate data given blob.
static int zip_vtab_eof(sqlite3_vtab_cursor *cursor)
Return end of table state of virtual table cursor.
static void zip_deflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Deflate data given blob and optional compression level.
#define ZIP_CENTRAL_EXTRALEN_OFFS
static int zip_vtab_column(sqlite3_vtab_cursor *cursor, sqlite3_context *ctx, int n)
Return column data of virtual table.
#define ZIP_CENTRAL_LOCALHDR_OFFS
#define ZIP_CENTRAL_HEADER_SIG
static int zip_vtab_findfunc(sqlite3_vtab *vtab, int narg, const char *name, void(**pfunc)(sqlite3_context *, int, sqlite3_value **), void **parg)
Find overloaded function on virtual table.
#define ZIP_COMPMETH_DEFLATED