summaryrefslogtreecommitdiff
path: root/src/queuebuf.cpp
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 /src/queuebuf.cpp
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.
Diffstat (limited to 'src/queuebuf.cpp')
-rw-r--r--src/queuebuf.cpp233
1 files changed, 233 insertions, 0 deletions
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