-C Remove\sunused\sfields\sfrom\sthe\sParse\sobject.\s\sDocumentation\sand\sformatting\nimprovements\son\sdata\sstructure\sdefinitions.
-D 2011-11-29T15:40:32.491
+C Add\sa\sprototype\simplementation\sof\sstdio-like\sroutines\sfor\saccessing\sthe\sVFS.\nThis\sis\sintended\sas\sdocumentation.\s\sThe\scode\sis\suntested.\sThere\sis\sno\nguarantee\sthat\sany\sof\sthis\swill\sever\smake\sit\sinto\strunk.\s\sSubstantial\nrevision\sis\spossible\sprior\sto\sreaching\strunk,\sif\sit\sever\sdoes.
+D 2011-12-01T02:32:12.196
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/mutex_unix.c b4f4e923bb8de93ec3f251fadb50855f23df9579
F src/mutex_w32.c 5e54f3ba275bcb5d00248b8c23107df2e2f73e33
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
-F src/os.c 28bbdab2170dfce84d86c45456a18eab1d0f99a9
+F src/os.c c2dcf314db63a0ea06af00fcf087750a1852bbbc
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 80f3ac44a8514b1d107b80f5df4a424ae059d2b6
F src/shell.c 29812a900a780eb0f835c4bc65e216272689def8
-F src/sqlite.h.in 57081d8e6b53ce29541d7437c93bce6087ac53b5
+F src/sqlite.h.in 6ab24133ed28e094dc67981cd9279d7bd8b31cf6
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 6f28b69d77356b1e45c024a6c103a1e0f0ec9f62
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P b10d091ec02e94643e865743129e2a21147b3136
-R 7d0a9d11e01c28eaf1d831b1553005fb
+P 431556cac0b2c86d7f6a60412ff1023feeaafedf
+R 0398714a93656ee1bfce81727b47b578
+T *branch * vfs-stdio
+T *sym-vfs-stdio *
+T -sym-trunk *
U drh
-Z fa710425b85d2a4b5e2c971fb970b087
+Z 536ed89e4d5b4e5e1bbeee8dbaae70fb
-431556cac0b2c86d7f6a60412ff1023feeaafedf
\ No newline at end of file
+8936542b225836f5f4a789e1ecc1451f6a1e120d
\ No newline at end of file
sqlite3_mutex_leave(mutex);
return SQLITE_OK;
}
+
+#ifndef SQLITE_OMIT_VFS_STDIO
+/*****************************************************************************
+** The remainder of this file contains a simplified stdio-like interface
+** to the VFS layer.
+*/
+
+/*
+** An instance of the following object records the state of an
+** open file. This object is opaque to all users - the internal
+** structure is only visible to the functions below.
+*/
+struct sqlite3_FILE {
+ char *zFilename; /* Full pathname of the open file */
+ sqlite3_int64 iOfst; /* Current offset into the file */
+ sqlite3_vfs *pVfs; /* The VFS used for this file */
+ u8 alwaysAppend; /* Always append if true */
+ sqlite3_file sFile; /* Open file. MUST BE LAST */
+};
+
+/*
+** This is a helper routine used to translate a URI into a full pathname
+** and a pointer to the appropriate VFS.
+*/
+static int getFilename(const char *zURI, sqlite3_vfs **ppVfs, char **pzName){
+ int rc;
+ char *zOpen = 0;
+ char *zFullname = 0;
+ unsigned int flags;
+ char *zErrmsg = 0;
+ sqlite3_vfs *pVfs = 0;
+
+ rc = sqlite3ParseUri(0, zURI, &flags, &pVfs, &zOpen, &zErrmsg);
+ sqlite3_free(zErrmsg);
+ if( rc ) goto getFilename_error;
+ zFullname = sqlite3_malloc( pVfs->mxPathname+1 );
+ if( zFullname==0 ){ rc = SQLITE_NOMEM; goto getFilename_error; }
+ rc = pVfs->xFullPathname(pVfs, zOpen, pVfs->mxPathname, zFullname);
+ if( rc ) goto getFilename_error;
+ sqlite3_free(zOpen);
+ zOpen = 0;
+ *pzName = sqlite3_realloc(zFullname, sqlite3Strlen30(zFullname)+1);
+ if( *pzName==0 ) goto getFilename_error;
+ zFullname = 0;
+ *ppVfs = pVfs;
+ return SQLITE_OK;
+
+getFilename_error:
+ sqlite3_free(zOpen);
+ sqlite3_free(zFullname);
+ *pzName = 0;
+ *ppVfs = 0;
+ return rc;
+}
+
+/*
+** Open a file for stdio-like reading and writing. The file is identified
+** by the URI in the first parameter. The access mode can be "r", "r+",
+** "w", "w+", "a", or "a+" with the usual meanings.
+**
+** On success, a pointer to a new sqlite3_FILE object is returned. On
+** failure, NULL is returned. Unfortunately, there is no way to recover
+** detailed error information after a failure.
+*/
+sqlite3_FILE *sqlite3_fopen(const char *zURI, const char *zMode){
+ char *zFile = 0;
+ sqlite3_vfs *pVfs = 0;
+ int rc;
+ int openFlags;
+ int doTruncate = 0;
+ int seekEnd = 0;
+ int alwaysAppend = 0;
+ int nToAlloc;
+ sqlite3_FILE *p;
+
+ if( zMode[0]==0 ) return 0;
+ if( zMode[0]=='r' ){
+ if( zMode[1]=='+' ){
+ openFlags = SQLITE_OPEN_READWRITE;
+ }else{
+ openFlags = SQLITE_OPEN_READONLY;
+ }
+ }else if( zMode[0]=='w' ){
+ openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ doTruncate = 1;
+ }else if( zMode[0]=='a' ){
+ openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ if( zMode[1]=='+' ){
+ alwaysAppend = 1;
+ }else{
+ seekEnd = 1;
+ }
+ }else{
+ return 0;
+ }
+ rc = getFilename(zURI, &pVfs, &zFile);
+ if( rc ) return 0;
+ nToAlloc = sizeof(*p) + ROUND8(pVfs->szOsFile);
+ p = sqlite3_malloc( nToAlloc );
+ if( p==0 ){
+ sqlite3_free(zFile);
+ return 0;
+ }
+ memset(p, 0, nToAlloc);
+ p->zFilename = zFile;
+ rc = pVfs->xOpen(pVfs, zFile, &p->sFile, openFlags, &openFlags);
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(zFile);
+ sqlite3_free(p);
+ return 0;
+ }
+ p->pVfs = pVfs;
+ p->alwaysAppend = alwaysAppend;
+ if( seekEnd ) sqlite3_fseek(p, 0, SQLITE_SEEK_END);
+ if( doTruncate ) sqlite3_ftruncate(p, 0);
+ return p;
+}
+
+/*
+** Close a file perviously opened by sqlite3_fopen().
+*/
+int sqlite3_fclose(sqlite3_FILE *p){
+ p->sFile.pMethods->xClose(&p->sFile);
+ sqlite3_free(p);
+ return SQLITE_OK;
+}
+
+/*
+** Read iAmt bytes from the file p into pBuf.
+**
+** Return 0 on success or an error code if the full amount could
+** not be read.
+*/
+int sqlite3_fread(
+ void *pBuf, /* Write content read into this buffer */
+ sqlite3_int64 iAmt, /* Number of bytes to read */
+ sqlite3_FILE *p /* Read from this file */
+){
+ int rc = p->sFile.pMethods->xRead(&p->sFile, pBuf, iAmt, p->iOfst);
+ if( rc==SQLITE_OK ){
+ p->iOfst += iAmt;
+ }
+ return rc;
+}
+
+/*
+** Write iAmt bytes from buffer pBuf into the file p.
+**
+** Return 0 on success or an error code if anything goes wrong.
+*/
+int sqlite3_fwrite(
+ const void *pBuf, /* Take content to be written from this buffer */
+ sqlite3_int64 iAmt, /* Number of bytes to write */
+ sqlite3_FILE *p /* Write into this file */
+){
+ int rc;
+
+ if( p->alwaysAppend ) sqlite3_fseek(p, 0, SQLITE_SEEK_END);
+ rc = p->sFile.pMethods->xWrite(&p->sFile, pBuf, iAmt, p->iOfst);
+ if( rc==SQLITE_OK ){
+ p->iOfst += iAmt;
+ }
+ return rc;
+}
+
+/*
+** Truncate an open file to newSize bytes.
+*/
+int sqlite3_ftruncate(sqlite3_FILE *p, sqlite3_int64 newSize){
+ int rc;
+ rc = p->sFile.pMethods->xTruncate(&p->sFile, newSize);
+ return rc;
+}
+
+/*
+** Return the current position of the file pointer.
+*/
+sqlite3_int64 sqlite3_ftell(sqlite3_FILE *p){
+ return p->iOfst;
+}
+
+/*
+** Move the file pointer to a new position in the file.
+*/
+int sqlite3_fseek(sqlite3_FILE *p, sqlite3_int64 ofst, int whence){
+ int rc = SQLITE_OK;
+ if( whence==SQLITE_SEEK_SET ){
+ p->iOfst = ofst;
+ }else if( whence==SQLITE_SEEK_CUR ){
+ p->iOfst += ofst;
+ }else{
+ sqlite3_int64 iCur = 0;
+ rc = p->sFile.pMethods->xFileSize(&p->sFile, &iCur);
+ if( rc==SQLITE_OK ){
+ p->iOfst = iCur + ofst;
+ }
+ }
+ return rc;
+}
+
+/*
+** Rewind the file pointer to the beginning of the file.
+*/
+int sqlite3_rewind(sqlite3_FILE *p){
+ p->iOfst = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Flush the content of OS cache buffers to disk. (fsync())
+*/
+int sqlite3_fflush(sqlite3_FILE *p){
+ return p->sFile.pMethods->xSync(&p->sFile, SQLITE_SYNC_NORMAL);
+}
+
+/*
+** Delete the file identified by the URI in the first parameter
+*/
+int sqlite3_remove(const char *zURI){
+ sqlite3_vfs *pVfs = 0;
+ char *zFilename = 0;
+ int rc;
+
+ rc = getFilename(zURI, &pVfs, &zFilename);
+ if( rc==SQLITE_OK ){
+ rc = pVfs->xDelete(pVfs, zFilename, 0);
+ }
+ sqlite3_free(zFilename);
+ return rc;
+}
+
+#endif /* SQLITE_OMIT_VFS_STDIO */
** for their own use. The pMethods entry is a pointer to an
** [sqlite3_io_methods] object that defines methods for performing
** I/O operations on the open file.
+**
+** Do not confuse the low-level sqlite3_file object described here
+** and used by the [VFS] with the high-level [sqlite3_FILE object]
+** that provides a stdio-like interface for use by application programs.
*/
typedef struct sqlite3_file sqlite3_file;
struct sqlite3_file {
/* #define SQLITE_ABORT 4 // Also an error code */
#define SQLITE_REPLACE 5
+/*
+** CAPI3REF: Simplified Interface To The VFS
+** KEYWORDS: *sqlite3_FILE {*sqlite3_FILE object}
+**
+** An instance of this object represents an open file in a [VFS].
+** This object is used by simplified I/O routines such as
+** [sqlite3_fopen()] and [sqlite3_fread()] and [sqlite3_fwrite()].
+**
+** The sqlite3_FILE object provides a simple means to access
+** the filesystem through an SQLite [VFS]. This allows, for example,
+** ordinary file I/O to occur through VFS shims such as the quota or
+** multiplexor or vfstrace, or for I/O to occur on specialized
+** application-specific VFSes. The sqlite3_FILE object also provides
+** a safe way for the application to read directly from an SQLite database
+** file, without the risk of cancelling posix advisory locks when the
+** connection is closed, as would happen using stdio or direct OS
+** I/O interfaces.
+**
+** The simplified I/O routines a similar to the "fopen()" family
+** of I/O routines in the standard C library, though there are some
+** minor differences. Note in particular that [sqlite3_fread()] and
+** [sqlite3_fwrite()] have 3 instead of 4 parameters and return a
+** success code rather than the number of elements read or written.
+** Also, standard C library numeric datatypes such as size_t and off_t are
+** replaced in this interface with the 64-bit signed integer type
+** [sqlite3_int64].
+**
+** The sqlite3_FILE object is not intended to be a general-purpose
+** replacement for stdio, but it can be very useful in some
+** circumstances.
+**
+** Do not confuse the high-level sqlite3_FILE object described here
+** with the low-level [sqlite3_file] object used by the [VFS].
+**
+** See also:
+** [sqlite3_fopen()],
+** [sqlite3_fread()],
+** [sqlite3_fwrite()],
+** [sqlite3_fseek()],
+** [sqlite3_ftell()],
+** [sqlite3_rewind()],
+** [sqlite3_fflush()],
+** [sqlite3_ftruncate()],
+** [sqlite3_close()],
+** [sqlite3_remove()].
+*/
+typedef struct sqlite3_FILE sqlite3_FILE;
+
+/*
+** CAPI3REF: Open A File Object
+**
+** The sqlite3_fopen(F,M) routine opens an [sqlite3_FILE object] on the
+** the file identified by [URI filename] F with mode M. Return a pointer
+** to the [sqlite3_FILE object] created, or a NULL pointer if the open failed.
+**
+** The mode M can be one of the following:
+**
+** <dl>
+** <dt><b>"r"</b>
+** <dd>Open the file read-only. Fail if the file does not already exist.
+** <dt><b>"r+"</b>
+** <dd>Open the file read and writing, but fail if the file does not
+** already exist.
+** <dt><b>"w"</b>
+** <dd>Open for reading and writing. Create the file if it does not
+** already exist. If the file does already exist, truncate it to zero
+** bytes in size immediately after opening.
+** <dt><b>"w+"</b>
+** <dd>This works the same as "w".
+** <dt><b>"a"</b>
+** <dd>Open for reading and writing. Create the file if it does not
+** already exist. Set the file cursor to the end of the file so that
+** any write operations that occur prior to an [sqlite3_fseek()] or
+** [sqlite3_rewind()] will append to the file.
+** <dt><b>"a+"</b>
+** <dd>Open for reading and writing. Create the file if it does not
+** already exist. The file cursor is positioned at the beginning of
+** the file for reading purposes. However, any writes on the file
+** cause the file cursor to move to the end of the file prior to the
+** write (and thus append to the file).
+** </dl>
+**
+** Any value for the mode M other than those listed above cause the
+** sqlite3_fopen() call to fail.
+**
+** See also:
+** [sqlite3_fread()],
+** [sqlite3_fwrite()],
+** [sqlite3_fseek()],
+** [sqlite3_ftell()],
+** [sqlite3_rewind()],
+** [sqlite3_fflush()],
+** [sqlite3_close()],
+** [sqlite3_remove()].
+*/
+sqlite3_FILE *sqlite3_fopen(const char *zURI, const char *zMode);
+
+/*
+** CAPI3REF: Read and Write A File Object
+**
+** The [sqlite3_fread(B,N,P)] routine reads N bytes of content from
+** [sqlite3_FILE object] P and into buffer B.
+** The [sqlite3_fwrite(B,N,P)] routine writes N bytes of content from
+** buffer B into [sqlite3_FILE object] P. Both routines return
+** SQLITE_OK on success or an [error code] on failure.
+**
+** Reading and writing always occur beginning at the file cursor. The file
+** cursor is advanced by N if the read or write is successful and unchanged
+** if the read is not successful. Not that the file cursor is
+** unchanged by a partial read ([SQLITE_IOERR_SHORT_READ]).
+** If the mode from [sqlite3_fopen()] was "a+" then the file cursor is
+** always moved to the end of the file prior to every write.
+**
+** Note that these routines differ from stdio fread() and fwrite()
+** functions in two significant ways: These routines use 3 parameters
+** instead of 4; these routines always assume an element size of one byte.
+** And these routines return a success code, not the number of elements
+** read or written. With the routines described here, and unlike
+** fread() and fwrite(), a partial read or write is considered an error.
+*/
+int sqlite3_fread(void*, sqlite3_int64, sqlite3_FILE*);
+int sqlite3_fwrite(const void*, sqlite3_int64, sqlite3_FILE*);
+/*
+** CAPI3REF: Whence Parameter For sqlite3_fseek()
+**
+** The 3rd parameter to [sqlite3_fseek(P,N,W)] can take on any of the
+** following values.
+*/
+#define SQLITE_SEEK_SET 0
+#define SQLITE_SEEK_CUR 1
+#define SQLITE_SEEK_END 2
+
+/*
+** CAPI3REF: Position The Cursor For An sqlite3_FILE object
+**
+** This routines move the current cursor position in an [sqlite3_FILE object].
+** The sqlite3_fseek(P,N,W) call move the [sqlite3_FILE object] P to a new
+** position N relative to W. W is [SQLITE_SEEK_SET] for the beginning of
+** the file, [SQLITE_SEEK_CUR] for the cursor position prior to the current
+** move, or [SQLITE_SEEK_END] for the end of the file.
+**
+** The sqlite3_rewind(P) call move the cursor position to the beginning
+** of the file. It is equivalent to sqlite3_fseek(P,0,SQLITE_SEEK_SET).
+**
+** The sqlite3_ftell(P) call returns the current cursor position.
+*/
+int sqlite3_fseek(sqlite3_FILE*, sqlite3_int64, int whence);
+int sqlite3_rewind(sqlite3_FILE*);
+sqlite3_int64 sqlite3_ftell(sqlite3_FILE*);
+
+/*
+** CAPI3REF: Flush OS File Cache Buffers
+**
+** A call to sqlite3_fflush(P) causes any writes previously made against
+** [sqlite3_FILE object] P to be flushed from the operating-system cache
+** to nonvolatile storage.
+*/
+int sqlite3_fflush(sqlite3_FILE*);
+
+/*
+** CAPI3REF: Truncate An sqlite3_FILE object
+**
+** The sqlite3_ftruncate(P,N) interface calls the [sqlite3_FILE object] P
+** to be truncated to N bytes in size.
+**
+** It is undefined what happens if N is larger than the current file size.
+** Some [VFS] implementations will extend the file. Others will fail.
+** Still others will leave the file in an inconsistent state.
+*/
+int sqlite3_ftruncate(sqlite3_FILE*, sqlite3_int64);
+
+/*
+** CAPI3REF: Close an sqlite3_FILE object
+**
+** Every successful call to [sqlite3_fopen()] should be eventually followed
+** by a call to this routine to destroy the [sqlite3_FILE object] that
+** [sqlite3_fopen()] created. After calling this routine, the
+** [sqlite3_FILE object] must not be used again.
+*/
+int sqlite3_fclose(sqlite3_FILE*);
+
+/*
+** CAPI3REF: Remove A File
+**
+** The sqlite3_remove(U) interface attempts to delete the file identified
+** by the [URI filename] U. Query parameters on U can specify a particular
+** [VFS] to use to do the deletion.
+*/
+int sqlite3_remove(const char *zURI);
/*
** Undo the hack that converts floating point types to integer for