diff -r 4a65cc85c4f3 -r fbd95db6a4e1 engine/sqlite/src/os_symbian.cpp --- a/engine/sqlite/src/os_symbian.cpp Wed Apr 28 13:20:05 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,616 +0,0 @@ -/* -** 2008 February 09 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code that is specific to windows. -*/ -#include "sqliteInt.h" -#if OS_SYMBIAN /* This file is used for symbian only */ - -#define MAX_PATH 260 -/* -** A Note About Memory Allocation: -** -** This driver uses malloc()/free() directly rather than going through -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers -** are designed for use on embedded systems where memory is scarce and -** malloc failures happen frequently. Win32 does not typically run on -** embedded systems, and when it does the developers normally have bigger -** problems to worry about than running out of memory. So there is not -** a compelling need to use the wrappers. -** -** But there is a good reason to not use the wrappers. If we use the -** wrappers then we will get simulated malloc() failures within this -** driver. And that causes all kinds of problems for our tests. We -** could enhance SQLite to deal with simulated malloc failures within -** the OS driver, but the code to deal with those failure would not -** be exercised on Linux (which does not need to malloc() in the driver) -** and so we would have difficulty writing coverage tests for that -** code. Better to leave the code out, we think. -** -** The point of this discussion is as follows: When creating a new -** OS layer for an embedded system, if you use this file as an example, -** avoid the use of malloc()/free(). Those routines work ok on windows -** desktops but not so well in embedded systems. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* -** Macros used to determine whether or not to use threads. -*/ -#if defined(THREADSAFE) && THREADSAFE -# define SQLITE_W32_THREADS 1 -#endif - -/* -** Include code that is common to all os_*.c files -*/ -#include "os_common.h" - -/* -** The symbianFile structure is a subclass of sqlite3_file* specific to the win32 -** portability layer. -*/ - -typedef struct symbianFile symbianFile; -struct symbianFile { - int isOpen; - unsigned char locktype; /* Type of lock currently held on this file */ - short sharedLockByte; /* Randomly chosen byte used as a shared lock */ - char fileName[512]; - RFs session; - RFile file; -}; - -/***************************************************************************** -** The next group of routines implement the I/O methods specified -** by the sqlite3_io_methods object. -******************************************************************************/ - -/* -** Close a file. -** -** It is reported that an attempt to close a handle might sometimes -** fail. This is a very unreasonable result, but windows is notorious -** for being unreasonable so I do not doubt that it might happen. If -** the close fails, we pause for 100 milliseconds and try again. As -** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before -** giving up and returning an error. -*/ -#define MX_CLOSE_ATTEMPT 3 -int winClose(sqlite3_file *id){ - int rc, cnt = 0; - symbianFile *pFile = (symbianFile*)id; - pFile->file.Close(); - pFile->session.Close(); - return SQLITE_OK; -} - -/* -** Some microsoft compilers lack this definition. -*/ -#ifndef INVALID_SET_FILE_POINTER -# define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - -/* -** Read data from a file into a buffer. Return SQLITE_OK if all -** bytes were read successfully and SQLITE_IOERR if anything goes -** wrong. -*/ -int winRead( - sqlite3_file *id, /* File to read from */ - void *pBuf, /* Write content into this buffer */ - int amt, /* Number of bytes to read */ - sqlite3_int64 offset /* Begin reading at this offset */ -){ - int rc; - size_t got; - symbianFile *pFile = (symbianFile*)id; - assert( id!=0 ); - SimulateIOError(return SQLITE_IOERR_READ); - TInt tOffset = (TInt)offset; - rc = pFile->file.Seek(ESeekStart, tOffset); - if( rc!= KErrNone){ - return SQLITE_FULL; - } - - HBufC8* buf = HBufC8::NewL(amt) ; - TPtr8 ptr = buf->Des(); - - if (pFile->file.Read(ptr, amt) != KErrNone) - { - delete buf; - return SQLITE_IOERR_READ; - } - - got = buf->Length(); - - if( got == 0 ){ - delete buf; - TInt size = 0; - if (pFile->file.Size(size) != KErrNone) - { - return SQLITE_IOERR_READ; - } - if (size == 0) - { - return SQLITE_IOERR_SHORT_READ; - } - return SQLITE_IOERR_READ; - } - memcpy(pBuf, ptr.Ptr(), got); - delete buf; - if( got == amt ){ - return SQLITE_OK; - }else{ - memset(&((char*)pBuf)[got], 0, amt-got); - return SQLITE_IOERR_SHORT_READ; - } -} - -/* -** Write data from a buffer into a file. Return SQLITE_OK on success -** or some other error code on failure. -*/ -int winWrite( - sqlite3_file *id, /* File to write into */ - const void *pBuf, /* The bytes to be written */ - int amt, /* Number of bytes to write */ - sqlite3_int64 offset /* Offset into the file to begin writing at */ -){ - int rc; - symbianFile *pFile = (symbianFile*)id; - assert( id!=0 ); - SimulateIOError(return SQLITE_IOERR_WRITE); - SimulateDiskfullError(return SQLITE_FULL); - TInt tOffset = (TInt)offset; - rc = pFile->file.Seek(ESeekStart, tOffset); - if( rc!= KErrNone){ - return SQLITE_FULL; - } - - assert( amt>0 ); - - rc = SQLITE_OK; - TPtrC8 ptr((TUint8 *)pBuf,amt); - - if (pFile->file.Write(ptr, amt) != KErrNone) rc = SQLITE_FULL; - - return rc; -} - -/* -** Truncate an open file to a specified size -*/ -int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ - symbianFile *pFile = (symbianFile*)id; - - if (pFile->file.SetSize(nByte) != KErrNone) - { - return SQLITE_IOERR; - } - - return SQLITE_OK; -} - -#ifdef SQLITE_TEST -/* -** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occuring at the right times. -*/ -int sqlite3_sync_count = 0; -int sqlite3_fullsync_count = 0; -#endif - -/* -** Make sure all writes to a particular file are committed to disk. -*/ -int winSync(sqlite3_file *id, int flags){ - symbianFile *pFile = (symbianFile*)id; - OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype); -#ifdef SQLITE_TEST - if( flags & SQLITE_SYNC_FULL ){ - sqlite3_fullsync_count++; - } - sqlite3_sync_count++; -#endif - TInt error = pFile->file.Flush(); - if (error != KErrNone) - { - return SQLITE_IOERR; - }else{ - return SQLITE_OK; - } -} - -/* -** Determine the current size of a file in bytes -*/ -int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ - symbianFile *pFile = (symbianFile*)id; - - TInt size = 0; - if (pFile->file.Size(size) != KErrNone) - { - return SQLITE_IOERR; - } - - *pSize = size; - - return SQLITE_OK; -} - - -/* -** Lock the file with the lock specified by parameter locktype - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. The winUnlock() routine -** erases all locks at once and returns us immediately to locking level 0. -** It is not possible to lower the locking level one step at a time. You -** must go straight to locking level 0. -*/ -int winLock(sqlite3_file *id, int locktype){ - int rc = SQLITE_OK; /* Return code from subroutines */ - int res = 1; /* Result of a windows lock call */ - int newLocktype; /* Set pFile->locktype to this value before exiting */ - int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ - symbianFile *pFile = (symbianFile*)id; - - assert( pFile!=0 ); - OSTRACE5("LOCK %d %d was %d(%d)\n", - pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); - - // one smartphone only one application can control the database - - TInt size = 0; - if (pFile->file.Size(size) == KErrNone) return SQLITE_OK; - - return SQLITE_BUSY; -} - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, return -** non-zero, otherwise zero. -*/ -int winCheckReservedLock(sqlite3_file *id){ - int rc; - symbianFile *pFile = (symbianFile*)id; - assert( pFile!=0 ); - if( pFile->locktype>=RESERVED_LOCK ){ - rc = 1; - OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); - }else{ - TInt size = 0; - if (pFile->file.Size(size) == KErrNone) rc = 1; - OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc); - } - return rc; -} - -/* -** Lower the locking level on file descriptor id to locktype. locktype -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -** -** It is not possible for this routine to fail if the second argument -** is NO_LOCK. If the second argument is SHARED_LOCK then this routine -** might return SQLITE_IOERR; -*/ -int winUnlock(sqlite3_file *id, int locktype){ - int type; - symbianFile *pFile = (symbianFile*)id; - int rc = SQLITE_OK; - assert( pFile!=0 ); - return rc; -} - -/* -** Control and query of the open file handle. -*/ -int winFileControl(sqlite3_file *id, int op, void *pArg){ - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = ((symbianFile*)id)->locktype; - return SQLITE_OK; - } - } - return SQLITE_ERROR; -} - -/* -** Return the sector size in bytes of the underlying block device for -** the specified file. This is almost always 512 bytes, but may be -** larger for some devices. -** -** SQLite code assumes this function cannot fail. It also assumes that -** if two files are created in the same file-system directory (i.e. -** a database and its journal file) that the sector size will be the -** same for both. -*/ -int winSectorSize(sqlite3_file *id){ - return SQLITE_DEFAULT_SECTOR_SIZE; -} - -/* -** Return a vector of device characteristics. -*/ -int winDeviceCharacteristics(sqlite3_file *id){ - return 0; -} - - -/*************************************************************************** -** Here ends the I/O methods that form the sqlite3_io_methods object. -** -** The next block of code implements the VFS methods. -****************************************************************************/ - -void ConvertToUnicode(RFs session, TDes16& aUnicode, const char *str) -{ - CCnvCharacterSetConverter *converter = CCnvCharacterSetConverter::NewL(); - converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierUtf8, session); - - TPtrC8 ptr((const unsigned char*)str); - - int state = CCnvCharacterSetConverter::KStateDefault; - converter->ConvertToUnicode(aUnicode, ptr, state); - delete converter; -} - -/* -** Open a file. -*/ -int winOpen( - sqlite3_vfs *pVfs, /* Not used */ - const char *zName, /* Name of the file (UTF-8) */ - sqlite3_file *id, /* Write the SQLite file handle here */ - int flags, /* Open mode flags */ - int *pOutFlags /* Status return flags */ -){ - symbianFile *pFile = (symbianFile*)id; - TBuf16 filename; - - pFile->isOpen = 0; - memset(pFile, 0, sizeof(*pFile)); - strcpy(pFile->fileName, zName); - pFile->session.Connect(); - - ConvertToUnicode(pFile->session, filename, zName); - - int ret = 0; - if( flags & SQLITE_OPEN_CREATE ){ - if (BaflUtils::FileExists(pFile->session, filename) == 1) - { - ret = pFile->file.Open(pFile->session, filename, EFileStream | EFileWrite); - } - else - { - ret = pFile->file.Create(pFile->session, filename, EFileStream | EFileWrite); - } - } - else - if( flags & SQLITE_OPEN_READWRITE ){ - ret = pFile->file.Open(pFile->session, filename, EFileStream | EFileWrite); - }else{ - ret = pFile->file.Open(pFile->session, filename, EFileStream | EFileRead); - } - - OpenCounter(+1); - - if (ret != KErrNone) - { - return SQLITE_IOERR; - } - - pFile->isOpen = 1; - return SQLITE_OK; -} - -/* -** Delete the named file. -** -** Note that windows does not allow a file to be deleted if some other -** process has it open. Sometimes a virus scanner or indexing program -** will open a journal file shortly after it is created in order to do -** whatever does. While this other process is holding the -** file open, we will be unable to delete it. To work around this -** problem, we delay 100 milliseconds and try to delete again. Up -** to MX_DELETION_ATTEMPTs deletion attempts are run before giving -** up and returning an error. -*/ -#define MX_DELETION_ATTEMPTS 5 -int winDelete( - sqlite3_vfs *pVfs, /* Not used on win32 */ - const char *zFilename, /* Name of file to delete */ - int syncDir /* Not used on win32 */ -){ - SimulateIOError(return SQLITE_IOERR_DELETE); - TBuf16 filename; - - RFs session; - session.Connect(); - ConvertToUnicode(session, filename, zFilename); - BaflUtils::DeleteFile(session, filename); - OSTRACE2("DELETE \"%s\"\n", zFilename); - session.Close(); - return SQLITE_OK; -} - -/* -** Check the existance and status of a file. -*/ -int winAccess( - sqlite3_vfs *pVfs, /* Not used on win32 */ - const char *zFilename, /* Name of file to check */ - int flags /* Type of test to make on this file */ -){ - TBuf16 filename; - - RFs session; - session.Connect(); - ConvertToUnicode(session, filename, zFilename); - int ret = BaflUtils::FileExists(session, filename); - session.Close(); - - return ret; -} - - -/* -** Create a temporary file name in zBuf. zBuf must be big enough to -** hold at pVfs->mxPathname characters. -*/ -int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - static char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; - int i, j; - char zTempPath[MAX_PATH+1]; - if( sqlite3_temp_directory ){ - sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); - } - else - { - } - - for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} - zTempPath[i] = 0; - sqlite3_snprintf(nBuf-30, zBuf, - "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); - j = strlen(zBuf); - sqlite3Randomness(20, &zBuf[j]); - for(i=0; i<20; i++, j++){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - OSTRACE2("TEMP FILENAME: %s\n", zBuf); - return SQLITE_OK; -} - -/* -** Turn a relative pathname into a full pathname. Write the full -** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname -** bytes in size. -*/ -int winFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zRelative, /* Possibly relative input path */ - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ -){ - - /* WinCE has no concept of a relative pathname, or so I am told. */ - sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); - return SQLITE_OK; -} - - #define winDlOpen 0 - #define winDlError 0 - #define winDlSym 0 - #define winDlClose 0 - - -/* -** Write up to nBuf bytes of randomness into zBuf. -*/ -int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - - int i; - for (i=0; i