Adding the sqlite sourcecode
This commit is contained in:
1 parent
bdb54a1f8f
commit
406b584760
2208 files changed
+1172785
-1
No files matched your search
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
** 2014-06-13
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
******************************************************************************
|
||||
**
|
||||
** This SQLite extension implements SQL compression functions
|
||||
** compress() and uncompress() using ZLIB.
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <zlib.h>
|
||||
|
||||
/*
|
||||
** Implementation of the "compress(X)" SQL function. The input X is
|
||||
** compressed using zLib and the output is returned.
|
||||
**
|
||||
** The output is a BLOB that begins with a variable-length integer that
|
||||
** is the input size in bytes (the size of X before compression). The
|
||||
** variable-length integer is implemented as 1 to 5 bytes. There are
|
||||
** seven bits per integer stored in the lower seven bits of each byte.
|
||||
** More significant bits occur first. The most significant bit (0x80)
|
||||
** is a flag to indicate the end of the integer.
|
||||
**
|
||||
** This function, SQLAR, and ZIP all use the same "deflate" compression
|
||||
** algorithm, but each is subtly different:
|
||||
**
|
||||
** * ZIP uses raw deflate.
|
||||
**
|
||||
** * SQLAR uses the "zlib format" which is raw deflate with a two-byte
|
||||
** algorithm-identification header and a four-byte checksum at the end.
|
||||
**
|
||||
** * This utility uses the "zlib format" like SQLAR, but adds the variable-
|
||||
** length integer uncompressed size value at the beginning.
|
||||
**
|
||||
** This function might be extended in the future to support compression
|
||||
** formats other than deflate, by providing a different algorithm-id
|
||||
** mark following the variable-length integer size parameter.
|
||||
*/
|
||||
static void compressFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const unsigned char *pIn;
|
||||
unsigned char *pOut;
|
||||
unsigned int nIn;
|
||||
unsigned long int nOut;
|
||||
unsigned char x[8];
|
||||
int rc;
|
||||
int i, j;
|
||||
|
||||
pIn = sqlite3_value_blob(argv[0]);
|
||||
nIn = sqlite3_value_bytes(argv[0]);
|
||||
nOut = 13 + nIn + (nIn+999)/1000;
|
||||
pOut = sqlite3_malloc( nOut+5 );
|
||||
for(i=4; i>=0; i--){
|
||||
x[i] = (nIn >> (7*(4-i)))&0x7f;
|
||||
}
|
||||
for(i=0; i<4 && x[i]==0; i++){}
|
||||
for(j=0; i<=4; i++, j++) pOut[j] = x[i];
|
||||
pOut[j-1] |= 0x80;
|
||||
rc = compress(&pOut[j], &nOut, pIn, nIn);
|
||||
if( rc==Z_OK ){
|
||||
sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pOut);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the "uncompress(X)" SQL function. The argument X
|
||||
** is a blob which was obtained from compress(Y). The output will be
|
||||
** the value Y.
|
||||
*/
|
||||
static void uncompressFunc(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
const unsigned char *pIn;
|
||||
unsigned char *pOut;
|
||||
unsigned int nIn;
|
||||
unsigned long int nOut;
|
||||
int rc;
|
||||
unsigned int i;
|
||||
|
||||
pIn = sqlite3_value_blob(argv[0]);
|
||||
nIn = sqlite3_value_bytes(argv[0]);
|
||||
nOut = 0;
|
||||
for(i=0; i<nIn && i<5; i++){
|
||||
nOut = (nOut<<7) | (pIn[i]&0x7f);
|
||||
if( (pIn[i]&0x80)!=0 ){ i++; break; }
|
||||
}
|
||||
pOut = sqlite3_malloc( nOut+1 );
|
||||
rc = uncompress(pOut, &nOut, &pIn[i], nIn-i);
|
||||
if( rc==Z_OK ){
|
||||
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
|
||||
}else{
|
||||
sqlite3_free(pOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int sqlite3_compress_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, "compress", 1,
|
||||
SQLITE_UTF8 | SQLITE_INNOCUOUS,
|
||||
0, compressFunc, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_create_function(db, "uncompress", 1,
|
||||
SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
|
||||
0, uncompressFunc, 0, 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
Reference in new issue
Block a user