1. // file.cpp : Defines the entry point for the DLL application.
  2.  
  3. //
  4.  
  5.  
  6.  
  7. #include "stdafx.h"
  8.  
  9. #include "file.h"
  10.  
  11.  
  12.  
  13. #include <stdio.h>
  14.  
  15. #include <stdlib.h>
  16.  
  17. #include <sys/types.h>
  18.  
  19. #include <sys/stat.h>
  20.  
  21. #include <io.h>
  22.  
  23.  
  24.  
  25. #include "sqlite3ext.h"
  26.  
  27. SQLITE_EXTENSION_INIT1
  28.  
  29.  
  30.  
  31. int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out){
  32.  
  33.   int i, j, e, m;
  34.  
  35.   int cnt[256];
  36.  
  37.   if( n<=0 ){
  38.  
  39.     out[0] = 'x';
  40.  
  41.     out[1] = 0;
  42.  
  43.     return 1;
  44.  
  45.   }
  46.  
  47.   memset(cnt, 0, sizeof(cnt));
  48.  
  49.   for(i=n-1; i>=0; i--){ cnt[in[i]]++; }
  50.  
  51.   m = n;
  52.  
  53.   for(i=1; i<256; i++){
  54.  
  55.     int sum;
  56.  
  57.     if( i=='\'' ) continue;
  58.  
  59.     sum = cnt[i] + cnt[(i+1)&0xff] + cnt[(i+'\'')&0xff];
  60.  
  61.     if( sum<m ){
  62.  
  63.       m = sum;
  64.  
  65.       e = i;
  66.  
  67.       if( m==0 ) break;
  68.  
  69.     }
  70.  
  71.   }
  72.  
  73.   out[0] = e;
  74.  
  75.   j = 1;
  76.  
  77.   for(i=0; i<n; i++){
  78.  
  79.     int c = (in[i] - e)&0xff;
  80.  
  81.     if( c==0 ){
  82.  
  83.       out[j++] = 1;
  84.  
  85.       out[j++] = 1;
  86.  
  87.     }else if( c==1 ){
  88.  
  89.       out[j++] = 1;
  90.  
  91.       out[j++] = 2;
  92.  
  93.     }else if( c=='\'' ){
  94.  
  95.       out[j++] = 1;
  96.  
  97.       out[j++] = 3;
  98.  
  99.     }else{
  100.  
  101.       out[j++] = c;
  102.  
  103.     }
  104.  
  105.   }
  106.  
  107.   out[j] = 0;
  108.  
  109.   return j;
  110.  
  111. }
  112.  
  113.  
  114.  
  115. BOOL APIENTRY DllMain( HANDLE hModule,
  116.  
  117.                        DWORD  ul_reason_for_call,
  118.  
  119.                        LPVOID lpReserved
  120.  
  121.                      )
  122.  
  123. {
  124.  
  125.     switch (ul_reason_for_call)
  126.  
  127.     {
  128.  
  129.         case DLL_PROCESS_ATTACH:
  130.  
  131.         case DLL_THREAD_ATTACH:
  132.  
  133.         case DLL_THREAD_DETACH:
  134.  
  135.         case DLL_PROCESS_DETACH:
  136.  
  137.             break;
  138.  
  139.     }
  140.  
  141.     return TRUE;
  142.  
  143. }
  144.  
  145.  
  146.  
  147.  
  148.  
  149. /*
  150.  
  151. ** The fileFunc() SQL function returns the encoded contents of a file
  152.  
  153. */
  154.  
  155. static void fileFunc(
  156.  
  157.   sqlite3_context *context,
  158.  
  159.   int argc,
  160.  
  161.   sqlite3_value **argv
  162.  
  163. ){
  164.  
  165.  
  166.  
  167.     if( SQLITE_NULL==sqlite3_value_type(argv[0]) ){
  168.  
  169.     sqlite3_result_null(context);
  170.  
  171.     return;
  172.  
  173.   }
  174.  
  175.  
  176.  
  177.     const char *filename = (const char *)sqlite3_value_text(argv[0]);
  178.  
  179.   if( 0==filename ){
  180.  
  181.     filename="";
  182.  
  183.   }
  184.  
  185.  
  186.  
  187.     struct _stat sbuf;
  188.  
  189.     int res = _stat( filename, &sbuf );
  190.  
  191.     if (res!=0){
  192.  
  193.         sqlite3_result_error(context, "file not found", -1);
  194.  
  195.         return;
  196.  
  197.     }
  198.  
  199.     long size = sbuf.st_size;
  200.  
  201.  
  202.  
  203.     FILE * pFile;
  204.  
  205.   pFile = fopen (filename, "rb" );
  206.  
  207.     if (pFile){
  208.  
  209.  
  210.  
  211.         char *buf = (char*)sqlite3_malloc(size); // +1
  212.  
  213.         fread((void *)buf, sizeof( char ), size, pFile);
  214.  
  215.         fclose (pFile);
  216.  
  217.  
  218.  
  219.         char *out = (char*)sqlite3_malloc(2 +(257*size)/254);
  220.  
  221.         size = sqlite_encode_binary((const unsigned char *)buf, size, (unsigned char *)out);
  222.  
  223.         sqlite3_free(buf);
  224.  
  225.  
  226.  
  227.         sqlite3_result_text(context, out, -1, SQLITE_TRANSIENT);
  228.  
  229.         sqlite3_free(out);
  230.  
  231.  
  232.  
  233.     }else
  234.  
  235.         sqlite3_result_error(context, "file could not be opened", -1);
  236.  
  237. }
  238.  
  239.  
  240.  
  241. /* SQLite invokes this routine once when it loads the extension.
  242.  
  243. ** Create new functions, collating sequences, and virtual table
  244.  
  245. ** modules here.  This is usually the only exported symbol in
  246.  
  247. ** the shared library.
  248.  
  249. */
  250.  
  251. int sqlite3_extension_init(
  252.  
  253.   sqlite3 *db,
  254.  
  255.   char **pzErrMsg,
  256.  
  257.   const sqlite3_api_routines *pApi
  258.  
  259. ){
  260.  
  261.   SQLITE_EXTENSION_INIT2(pApi)
  262.  
  263.   sqlite3_create_function(db, "FILE", 1, SQLITE_ANY, 0, fileFunc, 0, 0);
  264.  
  265.   return 0;
  266.  
  267. }
  268.  
  269.  
[raw code]