// file.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "file.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out){
int i, j, e, m;
int cnt[256];
if( n<=0 ){
out[0] = 'x';
out[1] = 0;
return 1;
}
memset(cnt, 0, sizeof(cnt));
for(i=n-1; i>=0; i--){ cnt[in[i]]++; }
m = n;
for(i=1; i<256; i++){
int sum;
if( i=='\'' ) continue;
sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff];
if( sum<m ){
m = sum;
e = i;
if( m==0 ) break;
}
}
out[0] = e;
j = 1;
for(i=0; i<n; i++){
int c = (in[i] - e)&0xff;
if( c==0 ){
out[j++] = 1;
out[j++] = 1;
}else if( c==1 ){
out[j++] = 1;
out[j++] = 2;
}else if( c=='\'' ){
out[j++] = 1;
out[j++] = 3;
}else{
out[j++] = c;
}
}
out[j] = 0;
return j;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
/*
** The fileFunc() SQL function returns the encoded contents of a file
*/
static void fileFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
sqlite3_result_null(context);
return;
}
const char *filename = (const char *)sqlite3_value_text(argv[0]);
if( 0==filename ){
filename="";
}
struct _stat sbuf;
int res = _stat( filename, &sbuf );
if (res!=0){
sqlite3_result_error(context, "file not found", -1);
return;
}
long size = sbuf.st_size;
FILE * pFile;
pFile = fopen (filename, "rb" );
if (pFile){
char *buf = (char*)sqlite3_malloc(size); // +1
fread((void *)buf, sizeof( char ), size, pFile);
fclose (pFile);
char *out = (char*)sqlite3_malloc(2 +(257*size)/254);
size = sqlite_encode_binary((const unsigned char *)buf, size, (unsigned char *)out);
sqlite3_free(buf);
sqlite3_result_text(context, out, -1, SQLITE_TRANSIENT);
sqlite3_free(out);
}else
sqlite3_result_error(context, "file could not be opened", -1);
}
/* SQLite invokes this routine once when it loads the extension.
** Create new functions, collating sequences, and virtual table
** modules here. This is usually the only exported symbol in
** the shared library.
*/
int sqlite3_extension_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi)
sqlite3_create_function(db, "FILE", 1, SQLITE_ANY, 0, fileFunc, 0, 0);
return 0;
}