/* ** 2002 April 25 ** ** 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 file contains helper routines used to translate binary data into ** a null-terminated string (suitable for use in SQLite) and back again. ** These are convenience routines for use by people who want to store binary ** data in an SQLite database. The code in this file is used by any other ** part of the SQLite library. ** ** $Id: encode.c,v 1.4 2003/01/11 14:25:40 drh Exp $ */ #include /* ** Encode a binary buffer "in" of size n bytes so that it contains ** no instances of characters '\'' or '\000'. The output is ** null-terminated and can be used as a string value in an INSERT ** or UPDATE statement. Use sqlite_decode_binary() to convert the ** string back into its original binary. ** ** The result is written into a preallocated output buffer "out". ** "out" must be able to hold at least (256*n + 1262)/253 bytes. ** In other words, the output will be expanded by as much as 3 ** bytes for every 253 bytes of input plus 2 bytes of fixed overhead. ** (This is approximately 2 + 1.019*n or about a 2% size increase.) ** ** The return value is the number of characters in the encoded ** string, excluding the "\000" terminator. */ 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%d (max %d)", n, strlen(out)+1, m); if( strlen(out)+1>m ){ printf(" ERROR output too big\n"); exit(1); } for(j=0; out[j]; j++){ if( out[j]=='\'' ){ printf(" ERROR contains (')\n"); exit(1); } } j = sqlite_decode_binary(out, out); if( j!=n ){ printf(" ERROR decode size %d\n", j); exit(1); } if( memcmp(in, out, n)!=0 ){ printf(" ERROR decode mismatch\n"); exit(1); } printf(" OK\n"); } } #endif /* ENCODER_TEST */