aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-05-10 03:31:08 +0000
committerMike Buland <eichlan@xagasoft.com>2010-05-10 03:31:08 +0000
commit8baf7e1e75a185c742dc6d5b27e50058635e5522 (patch)
tree76ccf80b005c85df2d887ccda73679cae8d28a26
parent51c5bfa4881b5def142092e10dd402fd40e2e712 (diff)
downloadlibbu++-8baf7e1e75a185c742dc6d5b27e50058635e5522.tar.gz
libbu++-8baf7e1e75a185c742dc6d5b27e50058635e5522.tar.bz2
libbu++-8baf7e1e75a185c742dc6d5b27e50058635e5522.tar.xz
libbu++-8baf7e1e75a185c742dc6d5b27e50058635e5522.zip
Added the new QueueBuf. It's brilliant, and I've wanted it for a long time.
...I mean brilliant as in cool.
-rw-r--r--src/cache.h5
-rw-r--r--src/queuebuf.cpp233
-rw-r--r--src/queuebuf.h62
-rw-r--r--src/tests/queuebuf.cpp23
4 files changed, 323 insertions, 0 deletions
diff --git a/src/cache.h b/src/cache.h
index dc5ab39..7b55b80 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -112,6 +112,11 @@ namespace Bu
112 return pData != NULL; 112 return pData != NULL;
113 } 113 }
114 114
115 bool isSet() const
116 {
117 return pCache != NULL;
118 }
119
115 const keytype &getKey() const 120 const keytype &getKey() const
116 { 121 {
117 return kId; 122 return kId;
diff --git a/src/queuebuf.cpp b/src/queuebuf.cpp
new file mode 100644
index 0000000..9404164
--- /dev/null
+++ b/src/queuebuf.cpp
@@ -0,0 +1,233 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/queuebuf.h"
9
10#include "bu/sio.h"
11using Bu::sio;
12
13Bu::QueueBuf::QueueBuf( int iBlockSize /*=256*/ ) :
14 iBlockSize( iBlockSize ),
15 iReadOffset( 0 ),
16 iWriteOffset( 0 ),
17 iTotalSize( 0 )
18{
19}
20
21Bu::QueueBuf::~QueueBuf()
22{
23 for( BlockList::iterator i = lBlocks.begin(); i; i++ )
24 delete[] *i;
25}
26
27int Bu::QueueBuf::getSize()
28{
29 return iTotalSize;
30}
31
32void Bu::QueueBuf::close()
33{
34 for( BlockList::iterator i = lBlocks.begin(); i; i++ )
35 delete[] *i;
36 lBlocks.clear();
37 iReadOffset = iWriteOffset = iTotalSize = 0;
38}
39
40size_t Bu::QueueBuf::read( void *pRawBuf, size_t nBytes )
41{
42 if( nBytes <= 0 )
43 return 0;
44
45 if( lBlocks.isEmpty() )
46 return 0;
47
48 size_t iLeft = nBytes;
49 char *pBuf = (char *)pRawBuf;
50
51 while( iLeft > 0 && iTotalSize > 0 )
52 {
53 if( iReadOffset == iBlockSize )
54 {
55 removeBlock();
56 if( lBlocks.isEmpty() )
57 {
58 return nBytes-iLeft;
59 }
60 iReadOffset = 0;
61 }
62 char *pBlock = lBlocks.first();
63 size_t iCopy = iBlockSize-iReadOffset;
64 if( iLeft < iCopy )
65 iCopy = iLeft;
66 if( iTotalSize < iCopy )
67 iCopy = iTotalSize;
68 memcpy( pBuf, pBlock+iReadOffset, iCopy );
69 iReadOffset += iCopy;
70 iLeft -= iCopy;
71 pBuf += iCopy;
72 iTotalSize -= iCopy;
73 sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl;
74 }
75
76 return nBytes - iLeft;
77}
78
79size_t QueueBuf::peek( void *pBuf, size_t nBytes )
80{
81 if( nBytes <= 0 )
82 return 0;
83
84 if( lBlocks.isEmpty() )
85 return 0;
86
87 size_t iLeft = nBytes;
88 char *pBuf = (char *)pRawBuf;
89
90 int iTmpReadOffset = iReadOffset;
91 int iTmpRemSize = iTotalSize;
92 while( iLeft > 0 && iTmpRemSize > 0 )
93 {
94
95 // Switching to use temp variables instead of iReadOffset and iTotalSize
96 if( iReadOffset == iBlockSize )
97 {
98 if( lBlocks.isEmpty() )
99 {
100 return nBytes-iLeft;
101 }
102 iReadOffset = 0;
103 }
104 char *pBlock = lBlocks.first();
105 size_t iCopy = iBlockSize-iReadOffset;
106 if( iLeft < iCopy )
107 iCopy = iLeft;
108 if( iTotalSize < iCopy )
109 iCopy = iTotalSize;
110 memcpy( pBuf, pBlock+iReadOffset, iCopy );
111 iReadOffset += iCopy;
112 iLeft -= iCopy;
113 pBuf += iCopy;
114 iTotalSize -= iCopy;
115 sio << "Read " << iCopy << " bytes, new size: " << iTotalSize << sio.nl;
116 }
117
118 return nBytes - iLeft;
119}
120
121size_t Bu::QueueBuf::write( const void *pRawBuf, size_t nBytes )
122{
123 if( nBytes <= 0 )
124 return 0;
125
126 if( lBlocks.isEmpty() )
127 {
128 addBlock();
129 iWriteOffset = 0;
130 }
131 size_t iLeft = nBytes;
132 const char *pBuf = (const char *)pRawBuf;
133
134 while( iLeft > 0 )
135 {
136 if( iWriteOffset == iBlockSize )
137 {
138 addBlock();
139 iWriteOffset = 0;
140 }
141 char *pBlock = lBlocks.last();
142 size_t iCopy = iBlockSize-iWriteOffset;
143 if( iLeft < iCopy )
144 iCopy = iLeft;
145 memcpy( pBlock+iWriteOffset, pBuf, iCopy );
146 iWriteOffset += iCopy;
147 iLeft -= iCopy;
148 pBuf += iCopy;
149 iTotalSize += iCopy;
150 sio << "Wrote " << iCopy << " bytes, new size: " << iTotalSize << sio.nl;
151 }
152
153 return nBytes;
154}
155
156long Bu::QueueBuf::tell()
157{
158 return -1;
159}
160
161void Bu::QueueBuf::seek( long )
162{
163}
164
165void Bu::QueueBuf::setPos( long )
166{
167}
168
169void Bu::QueueBuf::setPosEnd( long )
170{
171}
172
173bool Bu::QueueBuf::isEos()
174{
175 return iTotalSize == 0;
176}
177
178bool Bu::QueueBuf::isOpen()
179{
180 return true;
181}
182
183void Bu::QueueBuf::flush()
184{
185}
186
187bool Bu::QueueBuf::canRead()
188{
189 return iTotalSize > 0;
190}
191
192bool Bu::QueueBuf::canWrite()
193{
194 return true;
195}
196
197bool Bu::QueueBuf::isReadable()
198{
199 return true;
200}
201
202bool Bu::QueueBuf::isWritable()
203{
204 return true;
205}
206
207bool Bu::QueueBuf::isSeekable()
208{
209 return false;
210}
211
212bool Bu::QueueBuf::isBlocking()
213{
214 return false;
215}
216
217void Bu::QueueBuf::setBlocking( bool )
218{
219}
220
221void Bu::QueueBuf::addBlock()
222{
223 lBlocks.append( new char[iBlockSize] );
224 sio << "Added new block." << sio.nl;
225}
226
227void Bu::QueueBuf::removeBlock()
228{
229 delete[] lBlocks.first();
230 lBlocks.erase( lBlocks.begin() );
231 sio << "Removed block." << sio.nl;
232}
233
diff --git a/src/queuebuf.h b/src/queuebuf.h
new file mode 100644
index 0000000..3591959
--- /dev/null
+++ b/src/queuebuf.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_QUEUE_BUF_H
9#define BU_QUEUE_BUF_H
10
11#include "bu/stream.h"
12
13namespace Bu
14{
15 /**
16 * A queuing buffer stream class. All data written to this class is
17 * appended to it, there is no stored position. All data read is read
18 * from the begining and then thrown away. It operates by using a linked
19 * list of small buffers, and deallocating or reusing them when it can.
20 */
21 class QueueBuf : public Bu::Stream
22 {
23 public:
24 QueueBuf( int iBlockSize=256 );
25 virtual ~QueueBuf();
26
27 int getSize();
28
29 virtual void close();
30 virtual size_t read( void *pBuf, size_t nBytes );
31 virtual size_t peek( void *pBuf, size_t nBytes );
32 virtual size_t write( const void *pBuf, size_t nBytes );
33 virtual long tell();
34 virtual void seek( long offset );
35 virtual void setPos( long pos );
36 virtual void setPosEnd( long pos );
37 virtual bool isEos();
38 virtual bool isOpen();
39 virtual void flush();
40 virtual bool canRead();
41 virtual bool canWrite();
42 virtual bool isReadable();
43 virtual bool isWritable();
44 virtual bool isSeekable();
45 virtual bool isBlocking();
46 virtual void setBlocking( bool bBlocking=true );
47
48 private:
49 void addBlock();
50 void removeBlock();
51
52 private:
53 int iBlockSize;
54 int iReadOffset;
55 int iWriteOffset;
56 size_t iTotalSize;
57 typedef Bu::List<char *> BlockList;
58 BlockList lBlocks;
59 };
60};
61
62#endif
diff --git a/src/tests/queuebuf.cpp b/src/tests/queuebuf.cpp
new file mode 100644
index 0000000..accc723
--- /dev/null
+++ b/src/tests/queuebuf.cpp
@@ -0,0 +1,23 @@
1#include <bu/queuebuf.h>
2#include <bu/sio.h>
3
4using namespace Bu;
5
6int main()
7{
8 static const char *src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789%#";
9 QueueBuf qb;
10
11 for( int j = 0; j < 8; j++ )
12 {
13 qb.write( src, 60 );
14 }
15
16 char buf[11];
17 while( !qb.isEos() )
18 {
19 buf[qb.read( buf, 9 )] = '\0';
20 sio << "Read: >>" << buf << "<<" << sio.nl;
21 }
22}
23