modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/misc/compress.c (about)

     1  /*
     2  ** 2014-06-13
     3  **
     4  ** The author disclaims copyright to this source code.  In place of
     5  ** a legal notice, here is a blessing:
     6  **
     7  **    May you do good and not evil.
     8  **    May you find forgiveness for yourself and forgive others.
     9  **    May you share freely, never taking more than you give.
    10  **
    11  ******************************************************************************
    12  **
    13  ** This SQLite extension implements SQL compression functions
    14  ** compress() and uncompress() using ZLIB.
    15  */
    16  #include "sqlite3ext.h"
    17  SQLITE_EXTENSION_INIT1
    18  #include <zlib.h>
    19  
    20  /*
    21  ** Implementation of the "compress(X)" SQL function.  The input X is
    22  ** compressed using zLib and the output is returned.
    23  **
    24  ** The output is a BLOB that begins with a variable-length integer that
    25  ** is the input size in bytes (the size of X before compression).  The
    26  ** variable-length integer is implemented as 1 to 5 bytes.  There are
    27  ** seven bits per integer stored in the lower seven bits of each byte.
    28  ** More significant bits occur first.  The most significant bit (0x80)
    29  ** is a flag to indicate the end of the integer.
    30  */
    31  static void compressFunc(
    32    sqlite3_context *context,
    33    int argc,
    34    sqlite3_value **argv
    35  ){
    36    const unsigned char *pIn;
    37    unsigned char *pOut;
    38    unsigned int nIn;
    39    unsigned long int nOut;
    40    unsigned char x[8];
    41    int rc;
    42    int i, j;
    43  
    44    pIn = sqlite3_value_blob(argv[0]);
    45    nIn = sqlite3_value_bytes(argv[0]);
    46    nOut = 13 + nIn + (nIn+999)/1000;
    47    pOut = sqlite3_malloc( nOut+5 );
    48    for(i=4; i>=0; i--){
    49      x[i] = (nIn >> (7*(4-i)))&0x7f;
    50    }
    51    for(i=0; i<4 && x[i]==0; i++){}
    52    for(j=0; i<=4; i++, j++) pOut[j] = x[i];
    53    pOut[j-1] |= 0x80;
    54    rc = compress(&pOut[j], &nOut, pIn, nIn);
    55    if( rc==Z_OK ){
    56      sqlite3_result_blob(context, pOut, nOut+j, sqlite3_free);
    57    }else{
    58      sqlite3_free(pOut);
    59    }
    60  }
    61  
    62  /*
    63  ** Implementation of the "uncompress(X)" SQL function.  The argument X
    64  ** is a blob which was obtained from compress(Y).  The output will be
    65  ** the value Y.
    66  */
    67  static void uncompressFunc(
    68    sqlite3_context *context,
    69    int argc,
    70    sqlite3_value **argv
    71  ){
    72    const unsigned char *pIn;
    73    unsigned char *pOut;
    74    unsigned int nIn;
    75    unsigned long int nOut;
    76    int rc;
    77    int i;
    78  
    79    pIn = sqlite3_value_blob(argv[0]);
    80    nIn = sqlite3_value_bytes(argv[0]);
    81    nOut = 0;
    82    for(i=0; i<nIn && i<5; i++){
    83      nOut = (nOut<<7) | (pIn[i]&0x7f);
    84      if( (pIn[i]&0x80)!=0 ){ i++; break; }
    85    }
    86    pOut = sqlite3_malloc( nOut+1 );
    87    rc = uncompress(pOut, &nOut, &pIn[i], nIn-i);
    88    if( rc==Z_OK ){
    89      sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
    90    }else{
    91      sqlite3_free(pOut);
    92    }
    93  }
    94  
    95  
    96  #ifdef _WIN32
    97  __declspec(dllexport)
    98  #endif
    99  int sqlite3_compress_init(
   100    sqlite3 *db, 
   101    char **pzErrMsg, 
   102    const sqlite3_api_routines *pApi
   103  ){
   104    int rc = SQLITE_OK;
   105    SQLITE_EXTENSION_INIT2(pApi);
   106    (void)pzErrMsg;  /* Unused parameter */
   107    rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, 0,
   108                                 compressFunc, 0, 0);
   109    if( rc==SQLITE_OK ){
   110      rc = sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8, 0,
   111                                   uncompressFunc, 0, 0);
   112    }
   113    return rc;
   114  }