aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/streamstack.cpp120
-rw-r--r--src/streamstack.h89
-rw-r--r--src/tests/streamstack.cpp93
3 files changed, 301 insertions, 1 deletions
diff --git a/src/streamstack.cpp b/src/streamstack.cpp
index 9e45cc4..c7f8af5 100644
--- a/src/streamstack.cpp
+++ b/src/streamstack.cpp
@@ -4,83 +4,203 @@ Bu::StreamStack::StreamStack()
4{ 4{
5} 5}
6 6
7Bu::StreamStack::StreamStack( Bu::Stream *pStream )
8{
9 lFilts.prepend( pStream );
10}
11
7Bu::StreamStack::~StreamStack() 12Bu::StreamStack::~StreamStack()
8{ 13{
14 clearStack();
15}
16
17bool Bu::StreamStack::isEmpty()
18{
19 return lFilts.isEmpty();
20}
21
22bool Bu::StreamStack::hasStream()
23{
24 return !lFilts.isEmpty();
25}
26
27void Bu::StreamStack::setStream( Bu::Stream *pStream )
28{
29 if( !lFilts.isEmpty() )
30 throw Bu::ExceptionBase("There is already a stream set.");
31
32 lFilts.prepend( pStream );
33}
34
35void Bu::StreamStack::clearStack()
36{
37 for( FilterList::iterator i = lFilts.begin(); i; i++ )
38 {
39 delete *i;
40 }
41
42 lFilts.clear();
43}
44
45void Bu::StreamStack::popFilter()
46{
47 if( lFilts.isEmpty() )
48 return;
49
50 delete lFilts.first();
51 lFilts.erase( lFilts.begin() );
52}
53
54Bu::Stream *Bu::StreamStack::getTop()
55{
56 checkStack();
57
58 return lFilts.first();
59}
60
61Bu::Stream *Bu::StreamStack::getStream()
62{
63 checkStack();
64
65 return lFilts.last();
9} 66}
10 67
11void Bu::StreamStack::close() 68void Bu::StreamStack::close()
12{ 69{
70 checkStack();
71
72 lFilts.first()->close();
13} 73}
14 74
15size_t Bu::StreamStack::read( void *pBuf, size_t nBytes ) 75size_t Bu::StreamStack::read( void *pBuf, size_t nBytes )
16{ 76{
77 checkStack();
78
79 return lFilts.first()->read( pBuf, nBytes );
17} 80}
18 81
19size_t Bu::StreamStack::write( const void *pBuf, size_t nBytes ) 82size_t Bu::StreamStack::write( const void *pBuf, size_t nBytes )
20{ 83{
84 checkStack();
85
86 return lFilts.first()->write( pBuf, nBytes );
21} 87}
22 88
23size_t Bu::StreamStack::write( const Bu::FString &sBuf ) 89size_t Bu::StreamStack::write( const Bu::FString &sBuf )
24{ 90{
91 checkStack();
92
93 return lFilts.first()->write( sBuf );
25} 94}
26 95
27long Bu::StreamStack::tell() 96long Bu::StreamStack::tell()
28{ 97{
98 checkStack();
99
100 return lFilts.first()->tell();
29} 101}
30 102
31void Bu::StreamStack::seek( long offset ) 103void Bu::StreamStack::seek( long offset )
32{ 104{
105 checkStack();
106
107 lFilts.first()->seek( offset );
33} 108}
34 109
35void Bu::StreamStack::setPos( long pos ) 110void Bu::StreamStack::setPos( long pos )
36{ 111{
112 checkStack();
113
114 lFilts.first()->setPos( pos );
37} 115}
38 116
39void Bu::StreamStack::setPosEnd( long pos ) 117void Bu::StreamStack::setPosEnd( long pos )
40{ 118{
119 checkStack();
120
121 lFilts.first()->setPosEnd( pos );
41} 122}
42 123
43bool Bu::StreamStack::isEos() 124bool Bu::StreamStack::isEos()
44{ 125{
126 checkStack();
127
128 return lFilts.first()->isEos();
45} 129}
46 130
47bool Bu::StreamStack::isOpen() 131bool Bu::StreamStack::isOpen()
48{ 132{
133 checkStack();
134
135 return lFilts.first()->isOpen();
49} 136}
50 137
51void Bu::StreamStack::flush() 138void Bu::StreamStack::flush()
52{ 139{
140 checkStack();
141
142 lFilts.first()->flush();
53} 143}
54 144
55bool Bu::StreamStack::canRead() 145bool Bu::StreamStack::canRead()
56{ 146{
147 checkStack();
148
149 return lFilts.first()->canRead();
57} 150}
58 151
59bool Bu::StreamStack::canWrite() 152bool Bu::StreamStack::canWrite()
60{ 153{
154 checkStack();
155
156 return lFilts.first()->canWrite();
61} 157}
62 158
63bool Bu::StreamStack::isReadable() 159bool Bu::StreamStack::isReadable()
64{ 160{
161 checkStack();
162
163 return lFilts.first()->isReadable();
65} 164}
66 165
67bool Bu::StreamStack::isWritable() 166bool Bu::StreamStack::isWritable()
68{ 167{
168 checkStack();
169
170 return lFilts.first()->isWritable();
69} 171}
70 172
71bool Bu::StreamStack::isSeekable() 173bool Bu::StreamStack::isSeekable()
72{ 174{
175 checkStack();
176
177 return lFilts.first()->isSeekable();
73} 178}
74 179
75bool Bu::StreamStack::isBlocking() 180bool Bu::StreamStack::isBlocking()
76{ 181{
182 checkStack();
183
184 return lFilts.first()->isBlocking();
77} 185}
78 186
79void Bu::StreamStack::setBlocking( bool bBlocking ) 187void Bu::StreamStack::setBlocking( bool bBlocking )
80{ 188{
189 checkStack();
190
191 lFilts.first()->setBlocking( bBlocking );
81} 192}
82 193
83void Bu::StreamStack::setSize( long iSize ) 194void Bu::StreamStack::setSize( long iSize )
84{ 195{
196 checkStack();
197
198 lFilts.first()->setSize( iSize );
199}
200
201inline void Bu::StreamStack::checkStack()
202{
203 if( lFilts.isEmpty() )
204 throw Bu::ExceptionBase("StreamStack is empty.");
85} 205}
86 206
diff --git a/src/streamstack.h b/src/streamstack.h
index 03d8d8f..89e683d 100644
--- a/src/streamstack.h
+++ b/src/streamstack.h
@@ -3,14 +3,99 @@
3 3
4#include "bu/stream.h" 4#include "bu/stream.h"
5 5
6#include <typeinfo>
7
6namespace Bu 8namespace Bu
7{ 9{
8 class StreamStack : public Bu::Stream 10 class StreamStack : public Bu::Stream
9 { 11 {
12 private:
13 typedef Bu::List<Bu::Stream *> FilterList;
14
10 public: 15 public:
11 StreamStack(); 16 StreamStack();
17 StreamStack( Bu::Stream *pStream );
12 virtual ~StreamStack(); 18 virtual ~StreamStack();
13 19
20 bool isEmpty();
21 bool hasStream();
22 void setStream( Bu::Stream *pStream );
23
24 void clearStack();
25 void popFilter();
26 Bu::Stream *getTop();
27
28 Bu::Stream *getStream();
29
30 template<typename filter>
31 Bu::Stream *findFilter()
32 {
33 for( FilterList::iterator i = lFilts.begin(); i; i++ )
34 {
35 if( typeid(**i) == typeid( filter ) )
36 {
37 return *i;
38 }
39 }
40
41 throw Bu::ExceptionBase("Filter not found.");
42 }
43
44 template<typename filter>
45 void pushFilter()
46 {
47 checkStack();
48
49 filter *pFlt = new filter( *lFilts.first() );
50 lFilts.prepend( pFlt );
51 }
52
53 template<typename filter, typename p1t>
54 void pushFilter( p1t p1 )
55 {
56 checkStack();
57
58 filter *pFlt = new filter( *lFilts.first(), p1 );
59 lFilts.prepend( pFlt );
60 }
61
62 template<typename filter, typename p1t, typename p2t>
63 void pushFilter( p1t p1, p2t p2 )
64 {
65 checkStack();
66
67 filter *pFlt = new filter( *lFilts.first(), p1, p2 );
68 lFilts.prepend( pFlt );
69 }
70
71 template<typename filter, typename p1t, typename p2t, typename p3t>
72 void pushFilter( p1t p1, p2t p2, p3t p3 )
73 {
74 checkStack();
75
76 filter *pFlt = new filter( *lFilts.first(), p1, p2, p3 );
77 lFilts.prepend( pFlt );
78 }
79
80 template<typename filter, typename p1t, typename p2t, typename p3t,
81 typename p4t>
82 void pushFilter( p1t p1, p2t p2, p3t p3, p4t p4 )
83 {
84 checkStack();
85
86 filter *pFlt = new filter( *lFilts.first(), p1, p2, p3, p4 );
87 lFilts.prepend( pFlt );
88 }
89
90 template<typename filter, typename p1t, typename p2t, typename p3t,
91 typename p4t, typename p5t>
92 void pushFilter( p1t p1, p2t p2, p3t p3, p4t p4, p5t p5 )
93 {
94 checkStack();
95
96 filter *pFlt = new filter( *lFilts.first(), p1, p2, p3, p4, p5 );
97 lFilts.prepend( pFlt );
98 }
14 99
15 // 100 //
16 // Everything below here merely passes on the call to the top of the 101 // Everything below here merely passes on the call to the top of the
@@ -39,7 +124,9 @@ namespace Bu
39 virtual void setSize( long iSize ); 124 virtual void setSize( long iSize );
40 125
41 private: 126 private:
42 typedef Bu::List<Bu::Stream *> FilterList; 127 void checkStack();
128
129 private:
43 FilterList lFilts; 130 FilterList lFilts;
44 }; 131 };
45}; 132};
diff --git a/src/tests/streamstack.cpp b/src/tests/streamstack.cpp
new file mode 100644
index 0000000..56a7076
--- /dev/null
+++ b/src/tests/streamstack.cpp
@@ -0,0 +1,93 @@
1#include "bu/streamstack.h"
2
3#include "bu/file.h"
4#include "bu/base64.h"
5#include "bu/bzip2.h"
6
7#include "bu/sio.h"
8
9#include <time.h>
10
11using namespace Bu;
12
13class DoStuff
14{
15public:
16 DoStuff( Bu::Stream &rStream ) :
17 rStream( rStream )
18 {
19 }
20
21 virtual ~DoStuff()
22 {
23 }
24
25 void write()
26 {
27 Bu::FString s;
28 time_t tNow = time( NULL );
29 s = ctime( &tNow );
30 long lSize = s.getSize()-1;
31 rStream.write( &lSize, sizeof(long) );
32 rStream.write( s.getStr(), lSize );
33 }
34
35 void read()
36 {
37 Bu::FString s;
38 long lSize;
39 rStream.read( &lSize, sizeof(long) );
40 s.setSize( lSize );
41 rStream.read( s.getStr(), lSize );
42 sio << "Read str(" << lSize << ") = '" << s << "'" << sio.nl;
43 }
44
45private:
46 Bu::Stream &rStream;
47};
48
49int main()
50{
51 Bu::StreamStack ss;
52
53 DoStuff ds( ss );
54
55 try
56 {
57 ds.write();
58 sio << "This shouldn't have worked." << sio.nl;
59 }
60 catch( Bu::ExceptionBase &e )
61 {
62 sio << "Got exception, this is good: " << e.what() << sio.nl;
63 }
64
65 ss.setStream( new Bu::File("Hello.test", Bu::File::WriteNew ) );
66
67 ds.write();
68
69 ss.pushFilter<Bu::Base64>();
70
71 ds.write();
72
73 ss.pushFilter<Bu::BZip2>();
74
75 ds.write();
76
77 ss.clearStack();
78
79 ss.setStream( new Bu::File("Hello.test", Bu::File::Read ) );
80
81 ds.read();
82
83 ss.pushFilter<Bu::Base64>();
84
85 ds.read();
86
87 ss.pushFilter<Bu::BZip2>();
88
89 ds.read();
90
91 return 0;
92}
93