diff options
author | Mike Buland <eichlan@xagasoft.com> | 2010-08-22 05:34:12 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2010-08-22 05:34:12 +0000 |
commit | 611f1c821f9d882f935ac62b0c566d4988f26d1c (patch) | |
tree | 91e69a124cbff0862a8b2f4899d253455a40eaa3 /src | |
parent | 7f17eeb7fccd52b7049f9f598121130dfd1b55ae (diff) | |
download | libbu++-611f1c821f9d882f935ac62b0c566d4988f26d1c.tar.gz libbu++-611f1c821f9d882f935ac62b0c566d4988f26d1c.tar.bz2 libbu++-611f1c821f9d882f935ac62b0c566d4988f26d1c.tar.xz libbu++-611f1c821f9d882f935ac62b0c566d4988f26d1c.zip |
Bu::StreamStack works, it's tested, reasonably, it will be used first in the
gats project in Gats::ProtocolGats.
Diffstat (limited to 'src')
-rw-r--r-- | src/streamstack.cpp | 120 | ||||
-rw-r--r-- | src/streamstack.h | 89 | ||||
-rw-r--r-- | src/tests/streamstack.cpp | 93 |
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 | ||
7 | Bu::StreamStack::StreamStack( Bu::Stream *pStream ) | ||
8 | { | ||
9 | lFilts.prepend( pStream ); | ||
10 | } | ||
11 | |||
7 | Bu::StreamStack::~StreamStack() | 12 | Bu::StreamStack::~StreamStack() |
8 | { | 13 | { |
14 | clearStack(); | ||
15 | } | ||
16 | |||
17 | bool Bu::StreamStack::isEmpty() | ||
18 | { | ||
19 | return lFilts.isEmpty(); | ||
20 | } | ||
21 | |||
22 | bool Bu::StreamStack::hasStream() | ||
23 | { | ||
24 | return !lFilts.isEmpty(); | ||
25 | } | ||
26 | |||
27 | void 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 | |||
35 | void Bu::StreamStack::clearStack() | ||
36 | { | ||
37 | for( FilterList::iterator i = lFilts.begin(); i; i++ ) | ||
38 | { | ||
39 | delete *i; | ||
40 | } | ||
41 | |||
42 | lFilts.clear(); | ||
43 | } | ||
44 | |||
45 | void Bu::StreamStack::popFilter() | ||
46 | { | ||
47 | if( lFilts.isEmpty() ) | ||
48 | return; | ||
49 | |||
50 | delete lFilts.first(); | ||
51 | lFilts.erase( lFilts.begin() ); | ||
52 | } | ||
53 | |||
54 | Bu::Stream *Bu::StreamStack::getTop() | ||
55 | { | ||
56 | checkStack(); | ||
57 | |||
58 | return lFilts.first(); | ||
59 | } | ||
60 | |||
61 | Bu::Stream *Bu::StreamStack::getStream() | ||
62 | { | ||
63 | checkStack(); | ||
64 | |||
65 | return lFilts.last(); | ||
9 | } | 66 | } |
10 | 67 | ||
11 | void Bu::StreamStack::close() | 68 | void Bu::StreamStack::close() |
12 | { | 69 | { |
70 | checkStack(); | ||
71 | |||
72 | lFilts.first()->close(); | ||
13 | } | 73 | } |
14 | 74 | ||
15 | size_t Bu::StreamStack::read( void *pBuf, size_t nBytes ) | 75 | size_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 | ||
19 | size_t Bu::StreamStack::write( const void *pBuf, size_t nBytes ) | 82 | size_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 | ||
23 | size_t Bu::StreamStack::write( const Bu::FString &sBuf ) | 89 | size_t Bu::StreamStack::write( const Bu::FString &sBuf ) |
24 | { | 90 | { |
91 | checkStack(); | ||
92 | |||
93 | return lFilts.first()->write( sBuf ); | ||
25 | } | 94 | } |
26 | 95 | ||
27 | long Bu::StreamStack::tell() | 96 | long Bu::StreamStack::tell() |
28 | { | 97 | { |
98 | checkStack(); | ||
99 | |||
100 | return lFilts.first()->tell(); | ||
29 | } | 101 | } |
30 | 102 | ||
31 | void Bu::StreamStack::seek( long offset ) | 103 | void Bu::StreamStack::seek( long offset ) |
32 | { | 104 | { |
105 | checkStack(); | ||
106 | |||
107 | lFilts.first()->seek( offset ); | ||
33 | } | 108 | } |
34 | 109 | ||
35 | void Bu::StreamStack::setPos( long pos ) | 110 | void Bu::StreamStack::setPos( long pos ) |
36 | { | 111 | { |
112 | checkStack(); | ||
113 | |||
114 | lFilts.first()->setPos( pos ); | ||
37 | } | 115 | } |
38 | 116 | ||
39 | void Bu::StreamStack::setPosEnd( long pos ) | 117 | void Bu::StreamStack::setPosEnd( long pos ) |
40 | { | 118 | { |
119 | checkStack(); | ||
120 | |||
121 | lFilts.first()->setPosEnd( pos ); | ||
41 | } | 122 | } |
42 | 123 | ||
43 | bool Bu::StreamStack::isEos() | 124 | bool Bu::StreamStack::isEos() |
44 | { | 125 | { |
126 | checkStack(); | ||
127 | |||
128 | return lFilts.first()->isEos(); | ||
45 | } | 129 | } |
46 | 130 | ||
47 | bool Bu::StreamStack::isOpen() | 131 | bool Bu::StreamStack::isOpen() |
48 | { | 132 | { |
133 | checkStack(); | ||
134 | |||
135 | return lFilts.first()->isOpen(); | ||
49 | } | 136 | } |
50 | 137 | ||
51 | void Bu::StreamStack::flush() | 138 | void Bu::StreamStack::flush() |
52 | { | 139 | { |
140 | checkStack(); | ||
141 | |||
142 | lFilts.first()->flush(); | ||
53 | } | 143 | } |
54 | 144 | ||
55 | bool Bu::StreamStack::canRead() | 145 | bool Bu::StreamStack::canRead() |
56 | { | 146 | { |
147 | checkStack(); | ||
148 | |||
149 | return lFilts.first()->canRead(); | ||
57 | } | 150 | } |
58 | 151 | ||
59 | bool Bu::StreamStack::canWrite() | 152 | bool Bu::StreamStack::canWrite() |
60 | { | 153 | { |
154 | checkStack(); | ||
155 | |||
156 | return lFilts.first()->canWrite(); | ||
61 | } | 157 | } |
62 | 158 | ||
63 | bool Bu::StreamStack::isReadable() | 159 | bool Bu::StreamStack::isReadable() |
64 | { | 160 | { |
161 | checkStack(); | ||
162 | |||
163 | return lFilts.first()->isReadable(); | ||
65 | } | 164 | } |
66 | 165 | ||
67 | bool Bu::StreamStack::isWritable() | 166 | bool Bu::StreamStack::isWritable() |
68 | { | 167 | { |
168 | checkStack(); | ||
169 | |||
170 | return lFilts.first()->isWritable(); | ||
69 | } | 171 | } |
70 | 172 | ||
71 | bool Bu::StreamStack::isSeekable() | 173 | bool Bu::StreamStack::isSeekable() |
72 | { | 174 | { |
175 | checkStack(); | ||
176 | |||
177 | return lFilts.first()->isSeekable(); | ||
73 | } | 178 | } |
74 | 179 | ||
75 | bool Bu::StreamStack::isBlocking() | 180 | bool Bu::StreamStack::isBlocking() |
76 | { | 181 | { |
182 | checkStack(); | ||
183 | |||
184 | return lFilts.first()->isBlocking(); | ||
77 | } | 185 | } |
78 | 186 | ||
79 | void Bu::StreamStack::setBlocking( bool bBlocking ) | 187 | void Bu::StreamStack::setBlocking( bool bBlocking ) |
80 | { | 188 | { |
189 | checkStack(); | ||
190 | |||
191 | lFilts.first()->setBlocking( bBlocking ); | ||
81 | } | 192 | } |
82 | 193 | ||
83 | void Bu::StreamStack::setSize( long iSize ) | 194 | void Bu::StreamStack::setSize( long iSize ) |
84 | { | 195 | { |
196 | checkStack(); | ||
197 | |||
198 | lFilts.first()->setSize( iSize ); | ||
199 | } | ||
200 | |||
201 | inline 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 | |||
6 | namespace Bu | 8 | namespace 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 | |||
11 | using namespace Bu; | ||
12 | |||
13 | class DoStuff | ||
14 | { | ||
15 | public: | ||
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 | |||
45 | private: | ||
46 | Bu::Stream &rStream; | ||
47 | }; | ||
48 | |||
49 | int 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 | |||