xref: /sqlite-3.40.0/ext/misc/fileio.c (revision 38d69855)
1 /*
2 ** 2014-06-13
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 ******************************************************************************
12 **
13 ** This SQLite extension implements SQL functions readfile() and
14 ** writefile().
15 */
16 #include "sqlite3ext.h"
17 SQLITE_EXTENSION_INIT1
18 #include <stdio.h>
19 
20 /*
21 ** Implementation of the "readfile(X)" SQL function.  The entire content
22 ** of the file named X is read and returned as a BLOB.  NULL is returned
23 ** if the file does not exist or is unreadable.
24 */
25 static void readfileFunc(
26   sqlite3_context *context,
27   int argc,
28   sqlite3_value **argv
29 ){
30   const char *zName;
31   FILE *in;
32   long nIn;
33   void *pBuf;
34 
35   zName = (const char*)sqlite3_value_text(argv[0]);
36   if( zName==0 ) return;
37   in = fopen(zName, "rb");
38   if( in==0 ) return;
39   fseek(in, 0, SEEK_END);
40   nIn = ftell(in);
41   rewind(in);
42   pBuf = sqlite3_malloc( nIn );
43   if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
44     sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
45   }else{
46     sqlite3_free(pBuf);
47   }
48   fclose(in);
49 }
50 
51 /*
52 ** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
53 ** is written into file X.  The number of bytes written is returned.  Or
54 ** NULL is returned if something goes wrong, such as being unable to open
55 ** file X for writing.
56 */
57 static void writefileFunc(
58   sqlite3_context *context,
59   int argc,
60   sqlite3_value **argv
61 ){
62   FILE *out;
63   const char *z;
64   sqlite3_int64 rc;
65   const char *zFile;
66 
67   zFile = (const char*)sqlite3_value_text(argv[0]);
68   if( zFile==0 ) return;
69   out = fopen(zFile, "wb");
70   if( out==0 ) return;
71   z = (const char*)sqlite3_value_blob(argv[1]);
72   if( z==0 ){
73     rc = 0;
74   }else{
75     rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
76   }
77   fclose(out);
78   sqlite3_result_int64(context, rc);
79 }
80 
81 
82 #ifdef _WIN32
83 __declspec(dllexport)
84 #endif
85 int sqlite3_fileio_init(
86   sqlite3 *db,
87   char **pzErrMsg,
88   const sqlite3_api_routines *pApi
89 ){
90   int rc = SQLITE_OK;
91   SQLITE_EXTENSION_INIT2(pApi);
92   (void)pzErrMsg;  /* Unused parameter */
93   rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
94                                readfileFunc, 0, 0);
95   if( rc==SQLITE_OK ){
96     rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
97                                  writefileFunc, 0, 0);
98   }
99   return rc;
100 }
101