44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
if( rid==0 ) return;
if( content_get(rid, &cx) ){
sqlite3_result_blob(context, blob_buffer(&cx), blob_size(&cx),
SQLITE_TRANSIENT);
blob_reset(&cx);
}
}
/*
** Implementation of the "compress(X)" SQL function. The input X is
** compressed using zLib and the output is returned.
*/
static void sqlcmd_compress(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const unsigned char *pIn;
unsigned char *pOut;
unsigned int nIn;
unsigned long int nOut;
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
nOut = 13 + nIn + (nIn+999)/1000;
pOut = sqlite3_malloc( nOut+4 );
pOut[0] = nIn>>24 & 0xff;
pOut[1] = nIn>>16 & 0xff;
pOut[2] = nIn>>8 & 0xff;
pOut[3] = nIn & 0xff;
compress(&pOut[4], &nOut, pIn, nIn);
sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free);
}
/*
** Implementation of the "uncontent(X)" SQL function. The argument X
** is a blob which was obtained from compress(Y). The output will be
** the value Y.
*/
static void sqlcmd_decompress(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const unsigned char *pIn;
unsigned char *pOut;
unsigned int nIn;
unsigned long int nOut;
int rc;
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
pOut = sqlite3_malloc( nOut+1 );
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
if( rc==Z_OK ){
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
}else{
sqlite3_result_error(context, "input is not zlib compressed", -1);
}
}
/*
** This is the "automatic extensionn" initializer that runs right after
** the connection to the repository database is opened. Set up the
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
sqlite3 *db,
const char **pzErrMsg,
const void *notUsed
){
sqlite3_create_function(db, "content", 1, SQLITE_ANY, 0,
sqlcmd_content, 0, 0);
sqlite3_create_function(db, "compress", 1, SQLITE_ANY, 0,
sqlcmd_compress, 0, 0);
sqlite3_create_function(db, "decompress", 1, SQLITE_ANY, 0,
sqlcmd_decompress, 0, 0);
return SQLITE_OK;
}
/*
** COMMAND: sqlite3
**
|