wasCSharpSQLite – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System.Diagnostics;
2 using System.IO;
3 using System.Text;
4  
5 namespace Community.CsharpSqlite
6 {
7 #if TCLSH
8 using tcl.lang;
9 using Tcl_Interp = tcl.lang.Interp;
10 using Tcl_Obj = tcl.lang.TclObject;
11  
12  
13 public partial class Sqlite3
14 {
15 /*
16 ** 2007 April 6
17 **
18 ** The author disclaims copyright to this source code. In place of
19 ** a legal notice, here is a blessing:
20 **
21 ** May you do good and not evil.
22 ** May you find forgiveness for yourself and forgive others.
23 ** May you share freely, never taking more than you give.
24 **
25 *************************************************************************
26 ** Code for testing all sorts of SQLite interfaces. This code
27 ** implements TCL commands for reading and writing the binary
28 ** database files and displaying the content of those files as
29 ** hexadecimal. We could, _in theory, use the built-_in "binary"
30 ** command of TCL to do a lot of this, but there are some issues
31 ** with historical versions of the "binary" command. So it seems
32 ** easier and safer to build our own mechanism.
33 *************************************************************************
34 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
35 ** C#-SQLite is an independent reimplementation of the SQLite software library
36 **
37 ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e
38 **
39 *************************************************************************
40 */
41 //#include "sqliteInt.h"
42 //#include "tcl.h"
43 //#include <stdlib.h>
44 //#include <string.h>
45 //#include <assert.h>
46  
47  
48 /*
49 ** Convert binary to hex. The input zBuf[] contains N bytes of
50 ** binary data. zBuf[] is 2*n+1 bytes long. Overwrite zBuf[]
51 ** with a hexadecimal representation of its original binary input.
52 */
53 static void sqlite3TestBinToHex( byte[] zBuf, int N )
54 {
55 StringBuilder zHex = new StringBuilder( "0123456789ABCDEF" );
56 int i, j;
57 byte c;
58 i = N * 2;
59 zBuf[i--] = 0;
60 for ( j = N - 1; j >= 0; j-- )
61 {
62 c = zBuf[j];
63 zBuf[i--] = (byte)zHex[c & 0xf];
64 zBuf[i--] = (byte)zHex[c >> 4];
65 }
66 Debug.Assert( i == -1 );
67 }
68  
69 /*
70 ** Convert hex to binary. The input zIn[] contains N bytes of
71 ** hexadecimal. Convert this into binary and write aOut[] with
72 ** the binary data. Spaces _in the original input are ignored.
73 ** Return the number of bytes of binary rendered.
74 */
75 static int sqlite3TestHexToBin( string zIn, int N, byte[] aOut )
76 {
77 int[] aMap = new int[] {
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0,
82 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
88 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 };
95 int i, j;
96 int hi = 1;
97 int c;
98  
99 for ( i = j = 0; i < N; i++ )
100 {
101 c = aMap[zIn[i]];
102 if ( c == 0 )
103 continue;
104 if ( hi != 0 )
105 {
106 aOut[j] = (byte)( ( c - 1 ) << 4 );
107 hi = 0;
108 }
109 else
110 {
111 aOut[j++] |= (byte)( c - 1 );
112 hi = 1;
113 }
114 }
115 return j;
116 }
117  
118  
119 /*
120 ** Usage: hexio_read FILENAME OFFSET AMT
121 **
122 ** Read AMT bytes from file FILENAME beginning at OFFSET from the
123 ** beginning of the file. Convert that information to hexadecimal
124 ** and return the resulting HEX string.
125 */
126 static int hexio_read(
127 object clientdata,
128 Tcl_Interp interp,
129 int objc,
130 Tcl_Obj[] objv
131 )
132 {
133 int offset = 0;
134 int amt = 0, got;
135 string zFile;
136 byte[] zBuf;
137 FileStream _in;
138  
139 if ( objc != 4 )
140 {
141 TCL.Tcl_WrongNumArgs( interp, 1, objv, "FILENAME OFFSET AMT" );
142 return TCL.TCL_ERROR;
143 }
144 if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out offset ) )
145 return TCL.TCL_ERROR;
146 if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out amt ) )
147 return TCL.TCL_ERROR;
148 zFile = TCL.Tcl_GetString( objv[1] );
149 zBuf = new byte[amt * 2 + 1];// sqlite3Malloc( amt * 2 + 1 );
150 if ( zBuf == null )
151 {
152 return TCL.TCL_ERROR;
153 }
154 _in = new FileStream( zFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite );
155 //if( _in==null){
156 // _in = fopen(zFile, "r");
157 //}
158 if ( _in == null )
159 {
160 TCL.Tcl_AppendResult( interp, "cannot open input file ", zFile );
161 return TCL.TCL_ERROR;
162 }
163 _in.Seek( offset, SeekOrigin.Begin ); //fseek(_in, offset, SEEK_SET);
164 got = _in.Read( zBuf, 0, amt ); // got = fread( zBuf, 1, amt, _in );
165 _in.Flush();
166 _in.Close();// fclose( _in );
167 if ( got < 0 )
168 {
169 got = 0;
170 }
171 sqlite3TestBinToHex( zBuf, got );
172 TCL.Tcl_AppendResult( interp, System.Text.Encoding.UTF8.GetString( zBuf, 0, zBuf.Length ).Substring( 0, got * 2 ) );
173 zBuf = null;// sqlite3DbFree( db, ref zBuf );
174 return TCL.TCL_OK;
175 }
176  
177  
178 /*
179 ** Usage: hexio_write FILENAME OFFSET DATA
180 **
181 ** Write DATA into file FILENAME beginning at OFFSET from the
182 ** beginning of the file. DATA is expressed _in hexadecimal.
183 */
184 static int hexio_write(
185 object clientdata,
186 Tcl_Interp interp,
187 int objc,
188 Tcl_Obj[] objv
189 )
190 {
191 int offset = 0;
192 int nIn = 0, nOut, written;
193 string zFile;
194 string zIn;
195 byte[] aOut;
196 FileStream _out;
197  
198 if ( objc != 4 )
199 {
200 TCL.Tcl_WrongNumArgs( interp, 1, objv, "FILENAME OFFSET HEXDATA" );
201 return TCL.TCL_ERROR;
202 }
203 if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out offset ) )
204 return TCL.TCL_ERROR;
205 zFile = TCL.Tcl_GetString( objv[1] );
206 zIn = TCL.Tcl_GetStringFromObj( objv[3], out nIn );
207 aOut = new byte[nIn / 2 + 1];//sqlite3Malloc( nIn/2 );
208 if ( aOut == null )
209 {
210 return TCL.TCL_ERROR;
211 }
212 nOut = sqlite3TestHexToBin( zIn, nIn, aOut );
213 _out = new FileStream( zFile, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite );// fopen( zFile, "r+b" );
214 //if( _out==0 ){
215 // _out = fopen(zFile, "r+");
216 //}
217 if ( _out == null )
218 {
219 TCL.Tcl_AppendResult( interp, "cannot open output file ", zFile );
220 return TCL.TCL_ERROR;
221 }
222 _out.Seek( offset, SeekOrigin.Begin );// fseek( _out, offset, SEEK_SET );
223 written = (int)_out.Position;
224 _out.Write( aOut, 0, nOut );// written = fwrite( aOut, 1, nOut, _out );
225 written = (int)_out.Position - written;
226 aOut = null;// sqlite3DbFree( db, ref aOut );
227 _out.Flush();
228 _out.Close();// fclose( _out );
229 TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( written ) );
230 return TCL.TCL_OK;
231 }
232  
233 /*
234 ** USAGE: hexio_get_int HEXDATA
235 **
236 ** Interpret the HEXDATA argument as a big-endian integer. Return
237 ** the value of that integer. HEXDATA can contain between 2 and 8
238 ** hexadecimal digits.
239 */
240 static int hexio_get_int(
241 object clientdata,
242 Tcl_Interp interp,
243 int objc,
244 Tcl_Obj[] objv
245 )
246 {
247 int val;
248 int nIn = 0, nOut;
249 string zIn;
250 byte[] aOut;
251 byte[] aNum = new byte[4];
252  
253 if ( objc != 2 )
254 {
255 TCL.Tcl_WrongNumArgs( interp, 1, objv, "HEXDATA" );
256 return TCL.TCL_ERROR;
257 }
258 zIn = TCL.Tcl_GetStringFromObj( objv[1], out nIn );
259 aOut = new byte[nIn / 2];// sqlite3Malloc( nIn / 2 );
260 if ( aOut == null )
261 {
262 return TCL.TCL_ERROR;
263 }
264 nOut = sqlite3TestHexToBin( zIn, nIn, aOut );
265 if ( nOut >= 4 )
266 {
267 aNum[0] = aOut[0]; // memcpy( aNum, aOut, 4 );
268 aNum[1] = aOut[1];
269 aNum[2] = aOut[2];
270 aNum[3] = aOut[3];
271 }
272 else
273 {
274 //memset(aNum, 0, sizeof(aNum));
275 //memcpy(&aNum[4-nOut], aOut, nOut);
276 aNum[4 - nOut] = aOut[0];
277 if ( nOut > 1 )
278 aNum[4 - nOut + 1] = aOut[1];
279 if ( nOut > 2 )
280 aNum[4 - nOut + 2] = aOut[2];
281 if ( nOut > 3 )
282 aNum[4 - nOut + 3] = aOut[3];
283 }
284 aOut = null;// sqlite3DbFree( db, ref aOut );
285 val = ( aNum[0] << 24 ) | ( aNum[1] << 16 ) | ( aNum[2] << 8 ) | aNum[3];
286 TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( val ) );
287 return TCL.TCL_OK;
288 }
289  
290  
291 /*
292 ** USAGE: hexio_render_int16 INTEGER
293 **
294 ** Render INTEGER has a 16-bit big-endian integer _in hexadecimal.
295 */
296 static int hexio_render_int16(
297 object clientdata,
298 Tcl_Interp interp,
299 int objc,
300 Tcl_Obj[] objv
301 )
302 {
303 int val = 0;
304 byte[] aNum = new byte[10];
305  
306 if ( objc != 2 )
307 {
308 TCL.Tcl_WrongNumArgs( interp, 1, objv, "INTEGER" );
309 return TCL.TCL_ERROR;
310 }
311 if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out val ) )
312 return TCL.TCL_ERROR;
313 aNum[0] = (byte)( val >> 8 );
314 aNum[1] = (byte)val;
315 sqlite3TestBinToHex( aNum, 2 );
316 TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewStringObj( aNum, 4 ) );
317 return TCL.TCL_OK;
318 }
319  
320  
321 /*
322 ** USAGE: hexio_render_int32 INTEGER
323 **
324 ** Render INTEGER has a 32-bit big-endian integer _in hexadecimal.
325 */
326 static int hexio_render_int32(
327 object clientdata,
328 Tcl_Interp interp,
329 int objc,
330 Tcl_Obj[] objv
331 )
332 {
333 int val = 0;
334 byte[] aNum = new byte[10];
335  
336 if ( objc != 2 )
337 {
338 TCL.Tcl_WrongNumArgs( interp, 1, objv, "INTEGER" );
339 return TCL.TCL_ERROR;
340 }
341 if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out val ) )
342 return TCL.TCL_ERROR;
343 aNum[0] = (byte)( val >> 24 );
344 aNum[1] = (byte)( val >> 16 );
345 aNum[2] = (byte)( val >> 8 );
346 aNum[3] = (byte)val;
347 sqlite3TestBinToHex( aNum, 4 );
348 TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewStringObj( aNum, 8 ) );
349 return TCL.TCL_OK;
350 }
351  
352 /*
353 ** USAGE: utf8_to_utf8 HEX
354 **
355 ** The argument is a UTF8 string represented _in hexadecimal.
356 ** The UTF8 might not be well-formed. Run this string through
357 ** sqlite3Utf8to8() convert it back to hex and return the result.
358 */
359 static int utf8_to_utf8(
360 object clientdata,
361 Tcl_Interp interp,
362 int objc,
363 Tcl_Obj[] objv
364 ){
365 #if SQLITE_DEBUG
366 int n = 0;
367 int nOut;
368 string zOrig;
369 byte[] z;
370 if( objc!=2 ){
371 TCL.Tcl_WrongNumArgs(interp, 1, objv, "HEX");
372 return TCL.TCL_ERROR;
373 }
374 zOrig = TCL.Tcl_GetStringFromObj(objv[1], out n);
375 z = new byte[2 * n + 1];//sqlite3Malloc( n + 3 );
376 nOut = sqlite3TestHexToBin( zOrig, n, z );
377 //z[n] = 0;
378 nOut = sqlite3Utf8To8(z);
379 sqlite3TestBinToHex( z, zOrig.Length );
380 TCL.Tcl_AppendResult(interp, Encoding.ASCII.GetString(z,0,n));
381 //sqlite3_free( z );
382 return TCL.TCL_OK;
383 #else
384 Tcl_AppendResult(interp,
385 "[utf8_to_utf8] unavailable - SQLITE_DEBUG not defined", 0
386 );
387 return TCL.TCL_ERROR;
388 #endif
389 }
390  
391  
392 //static int getFts3Varint(string p, sqlite_int64 *v){
393 // const unsigned char *q = (const unsigned char ) p;
394 // sqlite_uint64 x = 0, y = 1;
395 // while( (*q & 0x80) == 0x80 ){
396 // x += y * (*q++ & 0x7f);
397 // y <<= 7;
398 // }
399 // x += y * (*q++);
400 // *v = (sqlite_int64) x;
401 // return (int) (q - (unsigned char )p);
402 //}
403  
404  
405 ///*
406 //** USAGE: read_fts3varint BLOB VARNAME
407 //**
408 //** Read a varint from the start of BLOB. Set variable VARNAME to contain
409 //** the interpreted value. Return the number of bytes of BLOB consumed.
410 //*/
411 //static int read_fts3varint(
412 // void * clientData,
413 // Tcl_Interp interp,
414 // int objc,
415 // Tcl_Obj[] objv
416 //){
417 // int nBlob;
418 // unsigned string zBlob;
419 // sqlite3_int64 iVal;
420 // int nVal;
421  
422 // if( objc!=3 ){
423 // Tcl_WrongNumArgs(interp, 1, objv, "BLOB VARNAME");
424 // return TCL.TCL_ERROR;
425 // }
426 // zBlob = TCL.Tcl_GetByteArrayFromObj(objv[1], &nBlob);
427  
428 // nVal = getFts3Varint((char)zBlob, (sqlite3_int64 )(&iVal));
429 // Tcl_ObjSetVar2(interp, objv[2], 0, TCL.TCL_NewWideIntObj(iVal), 0);
430 // Tcl_SetObjResult(interp, TCL.TCL_NewIntObj(nVal));
431 // return TCL.TCL_OK;
432 //}
433  
434  
435 /*
436 ** Register commands with the TCL interpreter.
437 */
438 static public int Sqlitetest_hexio_Init( Tcl_Interp interp )
439 {
440 //static struct {
441 // string zName;
442 // Tcl_ObjCmdProc *xProc;
443 //}
444 _aObjCmd[] aObjCmd = new _aObjCmd[] {
445 new _aObjCmd( "hexio_read", hexio_read ),
446 new _aObjCmd( "hexio_write", hexio_write ),
447 new _aObjCmd( "hexio_get_int", hexio_get_int ),
448 new _aObjCmd( "hexio_render_int16", hexio_render_int16 ),
449 new _aObjCmd( "hexio_render_int32", hexio_render_int32 ),
450 new _aObjCmd( "utf8_to_utf8", utf8_to_utf8 ),
451 // { "read_fts3varint", read_fts3varint },
452 };
453 int i;
454 for ( i = 0; i < aObjCmd.Length; i++ )
455 {
456 TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName, aObjCmd[i].xProc, null, null );
457 }
458 return TCL.TCL_OK;
459 }
460 }
461 #endif
462 }