diff options
author | dan <dan@noemail.net> | 2017-12-16 19:11:26 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2017-12-16 19:11:26 +0000 |
commit | d1b51d49551d03ac2d47f3164df4096e4b8c6efb (patch) | |
tree | a3016018a3030f77f577bf8a5bc4c19559c72ea1 /ext/misc/sqlar.c | |
parent | ac15e2d7ccfb706d020d4a42fc4d809f6ca1cca8 (diff) | |
download | sqlite-d1b51d49551d03ac2d47f3164df4096e4b8c6efb.tar.gz sqlite-d1b51d49551d03ac2d47f3164df4096e4b8c6efb.zip |
Do not use the compress() and uncompress() functions in ext/misc/compress.c -
they are not quite compatible with the spec. Instead use new functions in
ext/misc/sqlar.c.
FossilOrigin-Name: 7652b3c2374084047b6c1da3e525e0cac34fe220597f81e793bc4fd9f33358da
Diffstat (limited to 'ext/misc/sqlar.c')
-rw-r--r-- | ext/misc/sqlar.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/ext/misc/sqlar.c b/ext/misc/sqlar.c new file mode 100644 index 000000000..17d087593 --- /dev/null +++ b/ext/misc/sqlar.c @@ -0,0 +1,113 @@ +/* +** 2017-12-17 +** +** 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. +** +****************************************************************************** +** +** Utility functions sqlar_compress() and sqlar_uncompress(). Useful +** for working with sqlar archives and used by the shell tool's built-in +** sqlar support. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include <zlib.h> + +/* +** Implementation of the "sqlar_compress(X)" SQL function. +** +** If the type of X is SQLITE_BLOB, and compressing that blob using +** zlib utility function compress() yields a smaller blob, return the +** compressed blob. Otherwise, return a copy of X. +*/ +static void sqlarCompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ + const Bytef *pData = sqlite3_value_blob(argv[0]); + uLong nData = sqlite3_value_bytes(argv[0]); + uLongf nOut = compressBound(nData); + Bytef *pOut; + + pOut = (Bytef*)sqlite3_malloc(nOut); + if( pOut==0 ){ + sqlite3_result_error_nomem(context); + return; + }else{ + if( Z_OK!=compress(pOut, &nOut, pData, nData) ){ + sqlite3_result_error(context, "error in compress()", -1); + }else if( nOut<nData ){ + sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT); + }else{ + sqlite3_result_value(context, argv[0]); + } + sqlite3_free(pOut); + } + }else{ + sqlite3_result_value(context, argv[0]); + } +} + +/* +** Implementation of the "sqlar_uncompress(X,SZ)" SQL function +** +** Parameter SZ is interpreted as an integer. If it is less than or +** equal to zero, then this function returns a copy of X. Or, if +** SZ is equal to the size of X when interpreted as a blob, also +** return a copy of X. Otherwise, decompress blob X using zlib +** utility function uncompress() and return the results (another +** blob). +*/ +static void sqlarUncompressFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + uLong nData; + uLongf sz; + + assert( argc==2 ); + sz = sqlite3_value_int(argv[1]); + + if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ + sqlite3_result_value(context, argv[0]); + }else{ + const Bytef *pData= sqlite3_value_blob(argv[0]); + Bytef *pOut = sqlite3_malloc(sz); + if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){ + sqlite3_result_error(context, "error in uncompress()", -1); + }else{ + sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT); + } + sqlite3_free(pOut); + } +} + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_sqlar_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0, + sqlarCompressFunc, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0, + sqlarUncompressFunc, 0, 0); + } + return rc; +} |