Add a partially completed SQLite VFS (requires SQLite 3.5+) implementation for PhysicsFS

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@3951 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2008-03-08 14:23:07 +00:00
parent 3858daf4a1
commit 9b71eb9821
5 changed files with 406 additions and 3 deletions

View File

@ -1,4 +1,4 @@
noinst_LIBRARIES = libsqlite3.a
noinst_HEADERS = sqlite3ext.h sqlite3.h
noinst_HEADERS = physfs_vfs.h sqlite3ext.h sqlite3.h
libsqlite3_a_SOURCES = sqlite3.c
libsqlite3_a_SOURCES = physfs_vfs.c sqlite3.c

View File

@ -1,7 +1,7 @@
MAKERULES=../../makerules
include $(MAKERULES)/configure.mk
SRC=sqlite3.c
SRC=physfs_vfs.c sqlite3.c
LIB=sqlite3

358
lib/sqlite3/physfs_vfs.c Normal file
View File

@ -0,0 +1,358 @@
/*
Copyright (c) 2008, Giel van Schijndel
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the Warzone Resurrection Project nor the names
of its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lib/framework/frame.h"
#include "lib/framework/strlfuncs.h"
#include "physfs_vfs.h"
#include "sqlite3.h"
#include <physfs.h>
#include <assert.h>
typedef struct physfs_sqlite3_file physfs_sqlite3_file;
/** "Subclassed" sqlite3_file for this PhysicsFS VFS.
*/
struct physfs_sqlite3_file
{
sqlite3_file SQLite3_file;
PHYSFS_file* file;
bool NOOP; /**< Flag which indicates whether all write operations should be no-ops (and reads should fail) */
};
/** Closes the given file and deallocates any associated resources.
* \param f the physfs_sqlite3_file to close
* \return SQLITE_OK on success.
*/
static int xClose(sqlite3_file* f)
{
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
if (file->NOOP)
return SQLITE_OK;
PHYSFS_close(file->file);
return SQLITE_OK;
}
/** Reads bytes from the file into the given output buffer.
* \param f the physfs_sqlite3_file to read from.
* \param[out] dst the memory buffer to write to.
* \param iAmt the amount of bytes to read from the file.
* \param iOfst the (absolute) offset into the file to start reading from.
* \return SQLITE_OK on success, SQLITE_IOERR_SHORT_READ if we couldn't read
* the full amount of \c iAmt bytes because EOF was reached, or
* SQLITE_IOERR_READ for any other error.
*/
static int xRead(sqlite3_file* f, void* dst, int iAmt, sqlite3_int64 iOfst)
{
PHYSFS_sint64 nRead;
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
if (file->NOOP)
return SQLITE_IOERR;
/* Seek to the given offset */
if (!PHYSFS_seek(file->file, iOfst))
return SQLITE_IOERR_READ;
nRead = PHYSFS_read(file->file, dst, 1, iAmt);
if (nRead < 0)
return SQLITE_IOERR_READ;
else if (nRead < iAmt)
return SQLITE_IOERR_SHORT_READ;
else
return SQLITE_OK;
}
/** Dummy write implementation (doesn't do anything at all).
* \return SQLITE_IOERR_WRITE
*/
static int xWrite(sqlite3_file* f, const void* src, int iAmt, sqlite3_int64 iOfst)
{
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
if (file->NOOP)
return SQLITE_OK;
return SQLITE_IOERR_WRITE;
}
/** Dummy truncate implementation (doesn't do anything at all).
* \return SQLITE_IOERR_TRUNCATE
*/
static int xTruncate(sqlite3_file* f, sqlite3_int64 size)
{
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
if (file->NOOP)
return SQLITE_OK;
return SQLITE_IOERR_TRUNCATE;
}
/** Dummy sync implementation (doesn't do anything at all).
* \return SQLITE_IOERR_FSYNC
*/
static int xSync(sqlite3_file* f, int flags)
{
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
if (file->NOOP)
return SQLITE_OK;
return SQLITE_IOERR_FSYNC;
}
/** Determines the size of the given file.
* \param f the physfs_sqlite3_file to determine the size of.
* \param[out] pSize to write the size of this file to.
* \return
*/
static int xFileSize(sqlite3_file* f, sqlite3_int64* pSize)
{
PHYSFS_sint64 size;
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
if (file->NOOP)
return SQLITE_IOERR;
size = PHYSFS_fileLength(file->file);
if (size < 0)
return SQLITE_IOERR_FSTAT;
*pSize = size;
return SQLITE_OK;
}
static int xLock(sqlite3_file* f, int level)
{
switch (level)
{
case SQLITE_LOCK_NONE:
case SQLITE_LOCK_SHARED:
return SQLITE_OK;
case SQLITE_LOCK_RESERVED:
case SQLITE_LOCK_PENDING:
case SQLITE_LOCK_EXCLUSIVE:
default:
return SQLITE_IOERR_RDLOCK;
}
}
static int xUnlock(sqlite3_file* f, int level)
{
return SQLITE_OK;
}
static int xCheckReservedLock(sqlite3_file* f)
{
return 0;
}
static int xFileControl(sqlite3_file* f, int op, void *pArg)
{
return 0;
}
static int xSectorSize(sqlite3_file* f)
{
return 512;
}
static int xDeviceCharacteristics(sqlite3_file* f)
{
return 0;
}
static const sqlite3_io_methods physfs_sqlite3_io_methods =
{
1, /**< iVersion */
xClose, /**< Closes the physfs_sqlite3_file */
xRead, /**< Reads from the physfs_sqlite3_file */
xWrite, /**< Intended to write from the physfs_sqlite3_file */
xTruncate, /**< Intended to truncate the physfs_sqlite3_file */
xSync, /**< Intended to flush data out of OS cache into non-volatile memory */
xFileSize, /**< Deterimines the physfs_sqlite3_file's size */
xLock, /**< Acquires a lock on the physfs_sqlite3_file */
xUnlock, /**< Releases a lock on the physfs_sqlite3_file */
xCheckReservedLock, /**< Checks whether a "reserved" (or higher) level lock is acquired on this physfs_sqlite3_file */
xFileControl, /**< Intended to execute the given opcode */
xSectorSize, /**< Determines the size of sectors for the underlying filesystem */
xDeviceCharacteristics, /**< Returns a bitmask describing the underlying filesystem's characteristics */
};
static int xOpen(sqlite3_vfs* pVfs, const char* zName, sqlite3_file* f, int flags, int* pOutFlags)
{
physfs_sqlite3_file * const file = (physfs_sqlite3_file * const)file;
assert(&file->SQLite3_file == f);
/* Assign the "overloaded" I/O functions to this file object */
file->SQLite3_file.pMethods = &physfs_sqlite3_io_methods;
/* We don't support journals in this implementation */
if (flags & SQLITE_OPEN_MAIN_JOURNAL
|| flags & SQLITE_OPEN_TEMP_JOURNAL
|| flags & SQLITE_OPEN_MASTER_JOURNAL
|| flags & SQLITE_OPEN_SUBJOURNAL)
{
file->file = 0;
file->NOOP = true;
}
else /* if (flags & SQLITE_OPEN_MAIN_DB
|| flags & SQLITE_OPEN_TEMP_DB
|| flags & SQLITE_OPEN_TRANSIENT_DB) */
{
file->file = PHYSFS_openRead(zName);
file->NOOP = false;
if (!file->file)
return SQLITE_IOERR;
}
*pOutFlags = SQLITE_OPEN_READONLY;
return SQLITE_OK;
}
static int xDelete(sqlite3_vfs* pVfs, const char* zName, int syncDir)
{
if (PHYSFS_delete(zName))
return SQLITE_OK;
else
return SQLITE_IOERR_DELETE;
}
static int xAccess(sqlite3_vfs* pVfs, const char* zName, int flags)
{
switch (flags)
{
case SQLITE_ACCESS_EXISTS:
return PHYSFS_exists(zName);
case SQLITE_ACCESS_READ:
{
PHYSFS_file* f = PHYSFS_openRead(zName);
if (!f)
return false;
PHYSFS_close(f);
return true;
}
case SQLITE_ACCESS_READWRITE:
return false;
default:
return false;
}
}
static int xGetTempname(sqlite3_vfs* pVfs, int nOut, char* zOut)
{
return SQLITE_IOERR;
}
/** \return non-zero when no truncation occurred, zero otherwise.
*/
static int xFullPathname(sqlite3_vfs* pVfs, const char* zName, int nOut, char* zOut)
{
return (strlcpy(zOut, zName, nOut) < nOut);
}
static void* xDlOpen(sqlite3_vfs* pVfs, const char* zFilename)
{
return 0;
}
static void xDlError(sqlite3_vfs* pVfs, int nByte, char* zErrMsg)
{
strlcpy(zErrMsg, "DlOpen and DlSym API isn't supported for this (PhysicsFS \"physfs\") VFS.", nByte);
}
static void *xDlSym(sqlite3_vfs* pVfs, void* dl, const char* zSymbol)
{
return 0;
}
static void xDlClose(sqlite3_vfs* pVfs, void* dl)
{
}
static int xRandomness(sqlite3_vfs* pVfs, int nByte, char* zOut)
{
return SQLITE_IOERR;
}
static int xSleep(sqlite3_vfs* pVfs, int microseconds)
{
return SQLITE_IOERR;
}
static int xCurrentTime(sqlite3_vfs* pVfs, double* curTime)
{
return SQLITE_IOERR;
}
static sqlite3_vfs physfs_sqlite3_vfs =
{
1, /**< Structure version number */
sizeof(physfs_sqlite3_vfs), /**< Size of subclassed sqlite3_file */
256, /**< Maximum file pathname length */
0, /**< Next registered VFS (managed by SQLite) */
"physfs", /**< Name of this virtual file system */
0, /**< Pointer to application-specific data */
xOpen,
xDelete,
xAccess,
xGetTempname,
xFullPathname,
xDlOpen,
xDlError,
xDlSym,
xDlClose,
xRandomness,
xSleep,
xCurrentTime,
};

37
lib/sqlite3/physfs_vfs.h Normal file
View File

@ -0,0 +1,37 @@
/*
Copyright (c) 2008, Giel van Schijndel
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the Warzone Resurrection Project nor the names
of its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __INCLUDED_PHYSICSFS_SQLITE3_VFS_H__
#define __INCLUDED_PHYSICSFS_SQLITE3_VFS_H__
#endif // __INCLUDED_PHYSICSFS_SQLITE3_VFS_H__

View File

@ -147,6 +147,10 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\physfs_vfs.c"
>
</File>
<File
RelativePath=".\sqlite3.c"
>
@ -157,6 +161,10 @@
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\physfs_vfs.h"
>
</File>
<File
RelativePath=".\sqlite3.h"
>