Fixes default log output to console for macOS
[sqlcipher.git] / ext / misc / sqlar.c
blob9f726f0b89d0ee4ded323abcf210aac3451f6d1c
1 /*
2 ** 2017-12-17
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 ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
14 ** for working with sqlar archives and used by the shell tool's built-in
15 ** sqlar support.
17 #include "sqlite3ext.h"
18 SQLITE_EXTENSION_INIT1
19 #include <zlib.h>
20 #include <assert.h>
23 ** Implementation of the "sqlar_compress(X)" SQL function.
25 ** If the type of X is SQLITE_BLOB, and compressing that blob using
26 ** zlib utility function compress() yields a smaller blob, return the
27 ** compressed blob. Otherwise, return a copy of X.
29 ** SQLar uses the "zlib format" for compressed content. The zlib format
30 ** contains a two-byte identification header and a four-byte checksum at
31 ** the end. This is different from ZIP which uses the raw deflate format.
33 ** Future enhancements to SQLar might add support for new compression formats.
34 ** If so, those new formats will be identified by alternative headers in the
35 ** compressed data.
37 static void sqlarCompressFunc(
38 sqlite3_context *context,
39 int argc,
40 sqlite3_value **argv
42 assert( argc==1 );
43 if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
44 const Bytef *pData = sqlite3_value_blob(argv[0]);
45 uLong nData = sqlite3_value_bytes(argv[0]);
46 uLongf nOut = compressBound(nData);
47 Bytef *pOut;
49 pOut = (Bytef*)sqlite3_malloc(nOut);
50 if( pOut==0 ){
51 sqlite3_result_error_nomem(context);
52 return;
53 }else{
54 if( Z_OK!=compress(pOut, &nOut, pData, nData) ){
55 sqlite3_result_error(context, "error in compress()", -1);
56 }else if( nOut<nData ){
57 sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT);
58 }else{
59 sqlite3_result_value(context, argv[0]);
61 sqlite3_free(pOut);
63 }else{
64 sqlite3_result_value(context, argv[0]);
69 ** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
71 ** Parameter SZ is interpreted as an integer. If it is less than or
72 ** equal to zero, then this function returns a copy of X. Or, if
73 ** SZ is equal to the size of X when interpreted as a blob, also
74 ** return a copy of X. Otherwise, decompress blob X using zlib
75 ** utility function uncompress() and return the results (another
76 ** blob).
78 static void sqlarUncompressFunc(
79 sqlite3_context *context,
80 int argc,
81 sqlite3_value **argv
83 uLong nData;
84 sqlite3_int64 sz;
86 assert( argc==2 );
87 sz = sqlite3_value_int(argv[1]);
89 if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
90 sqlite3_result_value(context, argv[0]);
91 }else{
92 uLongf szf = sz;
93 const Bytef *pData= sqlite3_value_blob(argv[0]);
94 Bytef *pOut = sqlite3_malloc(sz);
95 if( pOut==0 ){
96 sqlite3_result_error_nomem(context);
97 }else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){
98 sqlite3_result_error(context, "error in uncompress()", -1);
99 }else{
100 sqlite3_result_blob(context, pOut, szf, SQLITE_TRANSIENT);
102 sqlite3_free(pOut);
106 #ifdef _WIN32
107 __declspec(dllexport)
108 #endif
109 int sqlite3_sqlar_init(
110 sqlite3 *db,
111 char **pzErrMsg,
112 const sqlite3_api_routines *pApi
114 int rc = SQLITE_OK;
115 SQLITE_EXTENSION_INIT2(pApi);
116 (void)pzErrMsg; /* Unused parameter */
117 rc = sqlite3_create_function(db, "sqlar_compress", 1,
118 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
119 sqlarCompressFunc, 0, 0);
120 if( rc==SQLITE_OK ){
121 rc = sqlite3_create_function(db, "sqlar_uncompress", 2,
122 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
123 sqlarUncompressFunc, 0, 0);
125 return rc;