FILE *f; /* File pointer for source CSV file */
long offsetFirstRow; /* ftell position of first row */
int eof; /* True when at end of file */
- char zRow[4096]; /* Buffer for current CSV row */
+ int maxRow; /* Size of zRow buffer */
+ char *zRow; /* Buffer for current CSV row */
char cDelim; /* Character to use for delimiting columns */
int nCol; /* Number of columns in current row */
int maxCol; /* Size of aCols array */
static long csv_tell( CSV *pCSV ){
return ftell( pCSV->f );
}
-static char *csv_gets( CSV *pCSV ){
- return fgets( pCSV->zRow, sizeof(pCSV->zRow), pCSV->f );
+
+
+/*
+** This routine reads a line of text from FILE in, stores
+** the text in memory obtained from malloc() and returns a pointer
+** to the text. NULL is returned at end of file, or if malloc()
+** fails.
+**
+** The interface is like "readline" but no command-line editing
+** is done.
+**
+** This code was modified from existing code in shell.c of the sqlite3 CLI.
+*/
+static char *csv_getline( CSV *pCSV ){
+ int n = 0;
+ int bEol = 0;
+ int bShrink = 0;
+
+ /* allocate initial row buffer */
+ if( pCSV->maxRow < 1 ){
+ pCSV->zRow = sqlite3_malloc( 100 );
+ if( pCSV->zRow ){
+ pCSV->maxRow = 100;
+ }
+ }
+ if( !pCSV->zRow ) return 0;
+
+ /* read until eol */
+ while( !bEol ){
+ /* grow row buffer as needed */
+ if( n+100>pCSV->maxRow ){
+ int newSize = pCSV->maxRow*2 + 100;
+ char *p = sqlite3_realloc(pCSV->zRow, newSize);
+ if( !p ) return 0;
+ pCSV->maxRow = newSize;
+ pCSV->zRow = p;
+ bShrink = -1;
+ }
+ if( fgets(&pCSV->zRow[n], pCSV->maxRow-n, pCSV->f)==0 ){
+ if( n==0 ){
+ break;
+ }
+ pCSV->zRow[n] = '\0';
+ bEol = -1;
+ break;
+ }
+ /* look for line delimiter */
+ while( pCSV->zRow[n] ){ n++; }
+ if( (n>0) && ((pCSV->zRow[n-1]=='\n') || (pCSV->zRow[n-1]=='\r')) ){
+ pCSV->zRow[n-1] = '\n'; /* uniform line ending */
+ pCSV->zRow[n] = '\0';
+ bEol = -1;
+ }
+ }
+ if( bShrink ){ pCSV->zRow = realloc( pCSV->zRow, n+1 ); }
+ return bEol ? pCSV->zRow : 0;
}
CSVCursor *pCsr = (CSVCursor *)pVtabCursor;
int nCol = 0;
char *s;
- char zDelims[4] = ",\r\n";
+ char zDelims[3] = ",\n";
char cDelim; /* char that delimited current col */
if( pCSV->eof ){
pCsr->csvpos = csv_tell( pCSV );
/* read the next row of data */
- s = csv_gets( pCSV );
+ s = csv_getline( pCSV );
if( !s ){
/* and error or eof occured */
pCSV->eof = -1;
/* allocate initial space for the column pointers */
if( pCSV->maxCol < 1 ){
/* take a guess */
- pCSV->maxCol = (int)(strlen(pCSV->zRow) / 5 + 1);
- if( pCSV->aCols ) sqlite3_free( pCSV->aCols );
- pCSV->aCols = (char **)sqlite3_malloc( sizeof(char*) * pCSV->maxCol );
- if( !pCSV->aCols ){
- /* out of memory */
- return SQLITE_NOMEM;
+ int maxCol = (int)(strlen(pCSV->zRow) / 5 + 1);
+ pCSV->aCols = (char **)sqlite3_malloc( sizeof(char*) * maxCol );
+ if( pCSV->aCols ){
+ pCSV->maxCol = maxCol;
}
}
+ if( !pCSV->aCols ) return SQLITE_NOMEM;
/* add custom delim character */
zDelims[0] = pCSV->cDelim;
if( *s=='\"' ){
s++; /* skip quote */
pCSV->aCols[nCol] = s; /* save pointer for this col */
+ /* TBD: handle escaped quotes "" */
/* find closing quote */
-#if 1
s = strchr(s, '\"');
if( !s ){
/* no closing quote */
return SQLITE_ERROR;
}
*s = '\0'; /* null terminate this col */
- /* fall through and look for following ",\n\r" */
+ /* fall through and look for following ",\n" */
s++;
-#else
- /* TBD: handle escaped quotes "" */
- while( s[0] ){
- if( s[0]=='\"' ){
- if( s[1]=='\"' ){
- }
- break;
- }
- s++;
- }
-#endif
}else{
pCSV->aCols[nCol] = s; /* save pointer for this col */
}
*s = '\0';
nCol++;
/* if end of zRow, stop parsing cols */
- if( (cDelim == '\n') || (cDelim == '\r') ) break;
+ if( cDelim == '\n' ) break;
/* move to start of next col */
s++; /* skip delimiter */
/* finalize any prepared statements here */
csv_close( pCSV );
+ if( pCSV->zRow ) sqlite3_free( pCSV->zRow );
if( pCSV->aCols ) sqlite3_free( pCSV->aCols );
sqlite3_free( pCSV );
}
-C Initial\simplementation\sof\sa\svirtual\stable\sfor\sCSV\sfiles.
-D 2009-11-05T02:34:43
+C Removed\sline\slimit\son\srows.
+D 2009-11-05T04:01:04
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in a77dfde96ad86aafd3f71651a4333a104debe86a
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F ext/async/README.txt 0c541f418b14b415212264cbaaf51c924ec62e5b
F ext/async/sqlite3async.c 3d5396cd69851f5633ef29c7491ca9249eac903a
F ext/async/sqlite3async.h a21e1252deb14a2c211f0e165c4b9122a8f1f344
-F ext/csv/csv.c 7df206eadb1faf0d02cd06df76e37917643f9813
+F ext/csv/csv.c 8180ed6901f7ebe4609a5ae242ebb463b83a319e
F ext/csv/csv.h 9d200dd0511a41f22561d3100cd3cc924818c04a
F ext/csv/csv1.test 822780d05036796c3f2ff4432b5451fe47ae3355
F ext/csv/test1.csv 888555e2a197fecaf9d0b90133551ebb8cbac8ce
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P eb7a544fe49d1626bacecfe53ddc03fe082e3243
-R 27eb092351aa8c08879582048eb7304c
-T *bgcolor * orange
-T *branch * csv_ext
-T *sym-csv_ext *
-T -sym-trunk *
+P 90e63b7d845bacc9a1a1db13c1e9a406e5306faa
+R 83bf0c403b72a6abf0e42b60e4c904e3
U shaneh
-Z c880cba03cce7d6961f66416059a9bd1
+Z 5a62ad1ad3faa27f07afe28862888de9