aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/csvreader.cpp100
-rw-r--r--src/csvreader.h38
-rw-r--r--src/csvwriter.cpp39
-rw-r--r--src/csvwriter.h36
-rw-r--r--src/fbasicstring.h9
-rw-r--r--src/newline.cpp56
-rw-r--r--src/newline.h34
-rw-r--r--src/tests/csv.cpp41
8 files changed, 352 insertions, 1 deletions
diff --git a/src/csvreader.cpp b/src/csvreader.cpp
new file mode 100644
index 0000000..a28c2c3
--- /dev/null
+++ b/src/csvreader.cpp
@@ -0,0 +1,100 @@
1#include "bu/csvreader.h"
2#include "bu/stream.h"
3
4#include "bu/sio.h"
5using namespace Bu;
6
7Bu::CsvReader::CsvReader( Bu::Stream &sIn, Bu::CsvReader::Style eStyle ) :
8 sIn( sIn )
9{
10 switch( eStyle )
11 {
12 case styleExcel:
13 sDecode = Bu::slot( &decodeExcel );
14 break;
15
16 case styleC:
17 sDecode = Bu::slot( &decodeExcel );
18 break;
19 }
20}
21
22Bu::CsvReader::CsvReader( Bu::Stream &sIn,
23 Bu::CsvReader::DecodeSignal sDecode ) :
24 sIn( sIn ),
25 sDecode( sDecode )
26{
27}
28
29Bu::CsvReader::~CsvReader()
30{
31}
32
33Bu::StrArray Bu::CsvReader::readLine()
34{
35 Bu::StrArray aVals;
36
37 Bu::FString sLine = sIn.readLine();
38
39 for( Bu::FString::iterator i = sLine.begin(); i; i++ )
40 {
41 if( *i == ',' )
42 {
43 }
44 else
45 {
46 aVals.append( sDecode( i ) );
47 }
48 }
49
50 return aVals;
51}
52
53Bu::FString Bu::CsvReader::decodeExcel( Bu::FString::iterator &i )
54{
55 Bu::FString sRet;
56
57 for(; i && (*i == ' ' || *i == '\t'); i++ ) { }
58
59 if( *i == '\"' )
60 {
61 for( i++ ; i; i++ )
62 {
63 if( *i == '\"' )
64 {
65 i++;
66 if( *i == '\"' )
67 {
68 sRet += *i;
69 }
70 else
71 {
72 return sRet;
73 }
74 }
75 else
76 {
77 sRet += *i;
78 }
79 }
80 }
81 else
82 {
83 for( ; i; i++ )
84 {
85 if( *i == ',' )
86 {
87 return sRet;
88 }
89 sRet += *i;
90 }
91 }
92
93 return sRet;
94}
95
96Bu::FString Bu::CsvReader::decodeC( Bu::FString::iterator &i )
97{
98 return "";
99}
100
diff --git a/src/csvreader.h b/src/csvreader.h
new file mode 100644
index 0000000..d89fabe
--- /dev/null
+++ b/src/csvreader.h
@@ -0,0 +1,38 @@
1#ifndef BU_CSV_READER_H
2#define BU_CSV_READER_H
3
4#include "bu/fstring.h"
5#include "bu/array.h"
6#include "bu/signals.h"
7
8namespace Bu
9{
10 class Stream;
11 typedef Bu::Array<Bu::FString> StrArray;
12
13 class CsvReader
14 {
15 public:
16 typedef Bu::Signal1<Bu::FString, Bu::FString::iterator &> DecodeSignal;
17 enum Style
18 {
19 styleExcel, ///< Excel style quotes around things that need em
20 styleC ///< Escape things that need it C-style
21 };
22
23 CsvReader( Stream &sIn, Style eStyle=styleExcel );
24 CsvReader( Stream &sIn, DecodeSignal sDecode );
25 virtual ~CsvReader();
26
27 StrArray readLine();
28
29 private:
30 Stream &sIn;
31 DecodeSignal sDecode;
32
33 static Bu::FString decodeExcel( Bu::FString::iterator &i );
34 static Bu::FString decodeC( Bu::FString::iterator &i );
35 };
36};
37
38#endif
diff --git a/src/csvwriter.cpp b/src/csvwriter.cpp
new file mode 100644
index 0000000..b66dca8
--- /dev/null
+++ b/src/csvwriter.cpp
@@ -0,0 +1,39 @@
1#include "bu/csvwriter.h"
2#include "bu/stream.h"
3
4Bu::CsvWriter::CsvWriter( Bu::Stream &sOut, Bu::CsvWriter::Style eStyle ) :
5 sOut( sOut )
6{
7 switch( eStyle )
8 {
9 case styleExcel:
10 sEncode = Bu::slot( &encodeExcel );
11 break;
12
13 case styleC:
14 sEncode = Bu::slot( &encodeExcel );
15 break;
16 }
17}
18
19Bu::CsvWriter::CsvWriter( Bu::Stream &sOut,
20 Bu::CsvWriter::EncodeSignal sEncode ) :
21 sOut( sOut ),
22 sEncode( sEncode )
23{
24}
25
26Bu::CsvWriter::~CsvWriter()
27{
28}
29
30Bu::FString Bu::CsvWriter::encodeExcel( const Bu::FString &sIn )
31{
32 return "";
33}
34
35Bu::FString Bu::CsvWriter::encodeC( const Bu::FString &sIn )
36{
37 return "";
38}
39
diff --git a/src/csvwriter.h b/src/csvwriter.h
new file mode 100644
index 0000000..82f36d7
--- /dev/null
+++ b/src/csvwriter.h
@@ -0,0 +1,36 @@
1#ifndef BU_CSV_WRITER_H
2#define BU_CSV_WRITER_H
3
4#include "bu/fstring.h"
5#include "bu/array.h"
6#include "bu/signals.h"
7
8namespace Bu
9{
10 class Stream;
11 typedef Bu::Array<Bu::FString> StrArray;
12
13 class CsvWriter
14 {
15 public:
16 typedef Bu::Signal1<Bu::FString, const Bu::FString &> EncodeSignal;
17 enum Style
18 {
19 styleExcel, ///< Excel style quotes around things that need em
20 styleC ///< Escape things that need it C-style
21 };
22
23 CsvWriter( Stream &sOut, Style eStyle=styleExcel );
24 CsvWriter( Stream &sOut, EncodeSignal sEncode );
25 virtual ~CsvWriter();
26
27 private:
28 Stream &sOut;
29 EncodeSignal sEncode;
30
31 static Bu::FString encodeExcel( const Bu::FString &sIn );
32 static Bu::FString encodeC( const Bu::FString &sIn );
33 };
34};
35
36#endif
diff --git a/src/fbasicstring.h b/src/fbasicstring.h
index 838fbc2..535df55 100644
--- a/src/fbasicstring.h
+++ b/src/fbasicstring.h
@@ -796,7 +796,7 @@ namespace Bu
796 append( &cData, 1 ); 796 append( &cData, 1 );
797 } 797 }
798 } 798 }
799 799
800 /** 800 /**
801 * Append another FString to this one. 801 * Append another FString to this one.
802 *@param sData (MyType &) The FString to append. 802 *@param sData (MyType &) The FString to append.
@@ -1280,6 +1280,13 @@ namespace Bu
1280 return (*this); 1280 return (*this);
1281 } 1281 }
1282 1282
1283 MyType &operator+=( const MyType::const_iterator &i )
1284 {
1285 append( i, i+1 );
1286
1287 return (*this);
1288 }
1289
1283 /** 1290 /**
1284 * Plus equals operator for FString. 1291 * Plus equals operator for FString.
1285 *@param cData (const chr) The character to append to your FString. 1292 *@param cData (const chr) The character to append to your FString.
diff --git a/src/newline.cpp b/src/newline.cpp
new file mode 100644
index 0000000..0dbbae5
--- /dev/null
+++ b/src/newline.cpp
@@ -0,0 +1,56 @@
1#include "bu/newline.h"
2
3Bu::NewLine::NewLine( Bu::Stream &rNext ) :
4 Bu::Filter( rNext ),
5 bExChar( false )
6{
7}
8
9Bu::NewLine::~NewLine()
10{
11}
12
13void Bu::NewLine::start()
14{
15}
16
17size_t Bu::NewLine::stop()
18{
19 return 0;
20}
21
22size_t Bu::NewLine::read( void *pBuf, size_t iAmnt )
23{
24 size_t iRead = rNext.read( pBuf, iAmnt );
25 size_t iOffset = 0;
26
27 for( size_t i = 0; i < iRead; i++ )
28 {
29 if( pBuf[i] == '\r' )
30 {
31 pBuf[i+iOffset] = '\n';
32 if( pBuf[j+1] == '\n' )
33 {
34 iOffset--;
35 }
36 }
37 else if( pBuf[i] == '\n' )
38 {
39 if( pBuf[j+1] == '\r' )
40 {
41 iOffset--;
42 }
43 }
44 else if( iOffset )
45 {
46 pBuf[i+iOffset] = pBuf[i];
47 }
48 }
49
50 iRead += iOffset;
51}
52
53size_t Bu::NewLine::write( const void *pBuf, size_t iAmnt )
54{
55}
56
diff --git a/src/newline.h b/src/newline.h
new file mode 100644
index 0000000..8ee5779
--- /dev/null
+++ b/src/newline.h
@@ -0,0 +1,34 @@
1#ifndef BU_NEW_LINE_H
2#define BU_NEW_LINE_H
3
4#include "bu/filter.h"
5
6namespace Bu
7{
8 /**
9 * Converts new-line characters from any standard convention into linefeeds
10 * (\n) on reading, and converts them to either your OS's standard or a
11 * specified standard, depending on how you construct the class.
12 *
13 * If you're reading in a text file, then this filter is practically
14 * required.
15 */
16 class NewLine : public Bu::Filter
17 {
18 public:
19 NewLine( Bu::Stream &rNext );
20 virtual ~NewLine();
21
22 virtual void start();
23 virtual size_t stop();
24
25 virtual size_t read( void *pBuf, size_t iAmnt );
26 virtual size_t write( const void *pBuf, size_t iAmnt );
27
28 private:
29 bool bExChar;
30 char cExChar;
31 };
32};
33
34#endif
diff --git a/src/tests/csv.cpp b/src/tests/csv.cpp
new file mode 100644
index 0000000..03e1df8
--- /dev/null
+++ b/src/tests/csv.cpp
@@ -0,0 +1,41 @@
1#include "bu/optparser.h"
2#include "bu/file.h"
3#include "bu/newline.h"
4#include "bu/csvreader.h"
5#include "bu/sio.h"
6
7using namespace Bu;
8
9class Options : public OptParser
10{
11public:
12 Options( int argc, char *argv[] )
13 {
14 addOption( slot( this, &Options::onRead ), 'r', "read",
15 "Read and display a csv file." );
16
17 addHelpOption();
18
19 parse( argc, argv );
20 }
21
22 int onRead( StrArray aArgs )
23 {
24 File fIn( aArgs[1], File::Read );
25 NewLine nlIn( fIn );
26 CsvReader rCsv( nlIn );
27 while( !fIn.isEos() )
28 {
29 sio << rCsv.readLine() << sio.nl;
30 }
31 sio << sio.nl;
32 return 1;
33 }
34};
35
36int main( int argc, char *argv[] )
37{
38 Options opts( argc, argv );
39 return 0;
40}
41