Fixes default log output to console for macOS
[sqlcipher.git] / ext / misc / blobio.c
blob3a1ee8465c9323e590585b46775514af7c4ee7cf
1 /*
2 ** 2019-03-30
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.
11 ******************************************************************************
13 ** An SQL function that uses the incremental BLOB I/O mechanism of SQLite
14 ** to read or write part of a blob. This is intended for debugging use
15 ** in the CLI.
17 ** readblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,N)
19 ** Returns N bytes of the blob starting at OFFSET.
21 ** writeblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,NEWDATA)
23 ** NEWDATA must be a blob. The content of NEWDATA overwrites the
24 ** existing BLOB data at SCHEMA.TABLE.COLUMN for row ROWID beginning
25 ** at OFFSET bytes into the blob.
27 #include "sqlite3ext.h"
28 SQLITE_EXTENSION_INIT1
29 #include <assert.h>
30 #include <string.h>
32 static void readblobFunc(
33 sqlite3_context *context,
34 int argc,
35 sqlite3_value **argv
37 sqlite3_blob *pBlob = 0;
38 const char *zSchema;
39 const char *zTable;
40 const char *zColumn;
41 sqlite3_int64 iRowid;
42 int iOfst;
43 unsigned char *aData;
44 int nData;
45 sqlite3 *db;
46 int rc;
48 zSchema = (const char*)sqlite3_value_text(argv[0]);
49 zTable = (const char*)sqlite3_value_text(argv[1]);
50 if( zTable==0 ){
51 sqlite3_result_error(context, "bad table name", -1);
52 return;
54 zColumn = (const char*)sqlite3_value_text(argv[2]);
55 if( zTable==0 ){
56 sqlite3_result_error(context, "bad column name", -1);
57 return;
59 iRowid = sqlite3_value_int64(argv[3]);
60 iOfst = sqlite3_value_int(argv[4]);
61 nData = sqlite3_value_int(argv[5]);
62 if( nData<=0 ) return;
63 aData = sqlite3_malloc64( nData+1 );
64 if( aData==0 ){
65 sqlite3_result_error_nomem(context);
66 return;
68 db = sqlite3_context_db_handle(context);
69 rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 0, &pBlob);
70 if( rc ){
71 sqlite3_free(aData);
72 sqlite3_result_error(context, "cannot open BLOB pointer", -1);
73 return;
75 rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
76 sqlite3_blob_close(pBlob);
77 if( rc ){
78 sqlite3_free(aData);
79 sqlite3_result_error(context, "BLOB read failed", -1);
80 }else{
81 sqlite3_result_blob(context, aData, nData, sqlite3_free);
85 static void writeblobFunc(
86 sqlite3_context *context,
87 int argc,
88 sqlite3_value **argv
90 sqlite3_blob *pBlob = 0;
91 const char *zSchema;
92 const char *zTable;
93 const char *zColumn;
94 sqlite3_int64 iRowid;
95 int iOfst;
96 unsigned char *aData;
97 int nData;
98 sqlite3 *db;
99 int rc;
101 zSchema = (const char*)sqlite3_value_text(argv[0]);
102 zTable = (const char*)sqlite3_value_text(argv[1]);
103 if( zTable==0 ){
104 sqlite3_result_error(context, "bad table name", -1);
105 return;
107 zColumn = (const char*)sqlite3_value_text(argv[2]);
108 if( zTable==0 ){
109 sqlite3_result_error(context, "bad column name", -1);
110 return;
112 iRowid = sqlite3_value_int64(argv[3]);
113 iOfst = sqlite3_value_int(argv[4]);
114 if( sqlite3_value_type(argv[5])!=SQLITE_BLOB ){
115 sqlite3_result_error(context, "6th argument must be a BLOB", -1);
116 return;
118 nData = sqlite3_value_bytes(argv[5]);
119 aData = (unsigned char *)sqlite3_value_blob(argv[5]);
120 db = sqlite3_context_db_handle(context);
121 rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 1, &pBlob);
122 if( rc ){
123 sqlite3_result_error(context, "cannot open BLOB pointer", -1);
124 return;
126 rc = sqlite3_blob_write(pBlob, aData, nData, iOfst);
127 sqlite3_blob_close(pBlob);
128 if( rc ){
129 sqlite3_result_error(context, "BLOB write failed", -1);
134 #ifdef _WIN32
135 __declspec(dllexport)
136 #endif
137 int sqlite3_blobio_init(
138 sqlite3 *db,
139 char **pzErrMsg,
140 const sqlite3_api_routines *pApi
142 int rc = SQLITE_OK;
143 SQLITE_EXTENSION_INIT2(pApi);
144 (void)pzErrMsg; /* Unused parameter */
145 rc = sqlite3_create_function(db, "readblob", 6, SQLITE_UTF8, 0,
146 readblobFunc, 0, 0);
147 if( rc==SQLITE_OK ){
148 rc = sqlite3_create_function(db, "writeblob", 6, SQLITE_UTF8, 0,
149 writeblobFunc, 0, 0);
151 return rc;