-C Fix\sfor\sticket\s#26:\sDocument\sthe\sfact\sthat\sCREATE\sTABLE\smight\snot\sbe\nimmediately\svisible\sto\sother\sprocesses\sthat\sare\sholding\sthe\sdatabase\sopen.\s(CVS\s544)
-D 2002-04-25T00:21:50
+C Added\sthe\s"encode.c"\ssource\sfile\sthat\scontains\stwo\sutility\ssubroutines\sthat\ncan\sbe\sused\sto\sencode\sbinary\sdata\sfor\suse\sin\sINSERT\sand\sUPDATE\sstatements.\nThis\sis\sjust\san\sinitial\schecking.\s\sThe\scode\shas\snot\syet\sbeen\sintegrated\sinto\nthe\slibrary.\s(CVS\s545)
+D 2002-04-25T11:45:42
F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
F src/build.c d01b81f41481e733e27ab2fa8e1bfcc64f24257d
F src/delete.c 6a6b8192cdff5e4b083da3bc63de099f3790d01f
+F src/encode.c cf929a63c3db5d893c24c89377871cb89ede44e2
F src/expr.c cf8d2ea17e419fc83b23e080195b2952e0be4164
F src/func.c a31dcba85bc2ecb9b752980289cf7e6cd0cafbce
F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P a06d9acdd5af0dc69b3a4d024de082631254aead
-R cfeb54c57cf6f9ec54bd35534c55c306
+P 18b31b7ab90ab330e271e0ed5d316f63846845be
+R 6048f8bfc097ad26d4d3ee4d7998e4f3
U drh
-Z d14450a4a0ba6fe1648be69426d0ab18
+Z fcb6af942153d3111f8e4a67cbb6971e
--- /dev/null
+/*
+** 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.1 2002/04/25 11:45:42 drh Exp $
+*/
+#include "sqliteInt.h"
+#include "encode.h"
+
+/*
+** 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.
+**
+** The result is written into a preallocated output buffer "out".
+** "out" must be able to hold at least 2 + (n+255)*3/256 + n bytes.
+** In other words, the output will be expanded by as much as 3
+** bytes for every 256 bytes of input plus 2 bytes of fixed overhead.
+*/
+void sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out){
+ int i, j, e, m;
+ int cnt[256];
+ 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;
+}
+
+/*
+** Decode the string "in" into binary data and write it into "out".
+** This routine reverses the encoded created by sqlite_encode_binary().
+** The output will always be a few bytes less than the input. The number
+** of bytes of output is returned. If the input is not a well-formed
+** encoding, -1 is returned.
+**
+** The "in" and "out" parameters may point to the same buffer in order
+** to decode a string in place.
+*/
+int sqlite_decode_binary(const unsigned char *in, unsigned char *out){
+ int i, c, e;
+ e = *(in++);
+ i = 0;
+ while( (c = *(in++))!=0 ){
+ if( c==1 ){
+ c = *(in++);
+ if( c==1 ){
+ c = 0;
+ }else if( c==2 ){
+ c = 1;
+ }else if( c==3 ){
+ c = '\'';
+ }else{
+ return -1;
+ }
+ }
+ out[i++] = (c + e)&0xff;
+ }
+ return i;
+}
+
+#ifdef ENCODER_TEST
+/*
+** The subroutines above are not tested by the usual test suite. To test
+** these routines, compile just this one file with a -DENCODER_TEST=1 option
+** and run the result.
+*/
+int main(int argc, char **argv){
+ int i, j, n, m;
+ unsigned char in[20000];
+ unsigned char out[30000];
+
+ for(i=0; i<10000; i++){
+ printf("Test %d: ", i+1);
+ n = rand() % sizeof(in);
+ for(j=0; j<n; j++) in[j] = rand() & 0xff;
+ sqlite_encode_binary(in, n, out);
+ printf("size %d->%d ", n, strlen(out)+1);
+ m = 2 + (n+255)*3/256 + n;
+ 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 */