kbufferedio.cpp
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 2001 Thiago Macieira <thiago.macieira@kdemail.net> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 * Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "config.h" 00022 00023 #include <string.h> 00024 00025 #include <qptrlist.h> 00026 #include <qcstring.h> 00027 #include "kbufferedio.h" 00028 00088 // constructor 00089 KBufferedIO::KBufferedIO() : 00090 inBufIndex(0), outBufIndex(0) 00091 { 00092 inBuf.setAutoDelete(true); 00093 outBuf.setAutoDelete(true); 00094 } 00095 00096 // destructor 00097 KBufferedIO::~KBufferedIO() 00098 { 00099 } 00100 00101 // sets the buffer sizes 00102 // this implementation doesn't support setting the buffer sizes 00103 // if any parameter is different than -1 or -2, fail 00104 bool KBufferedIO::setBufferSize(int rsize, int wsize /* = -2 */) 00105 { 00106 if (wsize != -2 && wsize != -1) 00107 return false; 00108 if (rsize != -2 && rsize != -1) 00109 return false; 00110 00111 return true; 00112 } 00113 00114 int KBufferedIO::bytesAvailable() const 00115 { 00116 return readBufferSize(); 00117 } 00118 00119 int KBufferedIO::bytesToWrite() const 00120 { 00121 return writeBufferSize(); 00122 } 00123 00124 // This function will scan the read buffer for a '\n' 00125 bool KBufferedIO::canReadLine() const 00126 { 00127 if (bytesAvailable() == 0) 00128 return false; // no new line in here 00129 00130 QByteArray* buf; 00131 00132 // scan each QByteArray for the occurrence of '\n' 00133 QPtrList<QByteArray> &buflist = ((KBufferedIO*)this)->inBuf; 00134 buf = buflist.first(); 00135 char *p = buf->data() + inBufIndex; 00136 int n = buf->size() - inBufIndex; 00137 while (buf != NULL) 00138 { 00139 while (n--) 00140 if (*p++ == '\n') 00141 return true; 00142 buf = buflist.next(); 00143 if (buf != NULL) 00144 { 00145 p = buf->data(); 00146 n = buf->size(); 00147 } 00148 } 00149 00150 return false; // no new line found 00151 } 00152 00153 // unreads the current data 00154 // that is, writes into the read buffer, at the beginning 00155 int KBufferedIO::unreadBlock(const char *data, uint len) 00156 { 00157 return feedReadBuffer(len, data, true); 00158 } 00159 00160 // 00161 // protected member functions 00162 // 00163 00164 unsigned KBufferedIO::consumeReadBuffer(unsigned nbytes, char *destbuffer, bool discard) 00165 { 00166 { 00167 register unsigned u = readBufferSize(); 00168 if (nbytes > u) 00169 nbytes = u; // we can't consume more than there is 00170 } 00171 00172 QByteArray *buf; 00173 unsigned copied = 0; 00174 unsigned index = inBufIndex; 00175 00176 buf = inBuf.first(); 00177 while (nbytes && buf) 00178 { 00179 // should we copy it all? 00180 unsigned to_copy = buf->size() - index; 00181 if (to_copy > nbytes) 00182 to_copy = nbytes; 00183 00184 if (destbuffer) 00185 memcpy(destbuffer + copied, buf->data() + index, to_copy); 00186 nbytes -= to_copy; 00187 copied += to_copy; 00188 00189 if (buf->size() - index > to_copy) 00190 { 00191 index += to_copy; 00192 break; // we aren't copying everything, that means that's 00193 // all the user wants 00194 } 00195 else 00196 { 00197 index = 0; 00198 if (discard) 00199 { 00200 inBuf.remove(); 00201 buf = inBuf.first(); 00202 } 00203 else 00204 buf = inBuf.next(); 00205 } 00206 } 00207 00208 if (discard) 00209 inBufIndex = index; 00210 00211 return copied; 00212 } 00213 00214 void KBufferedIO::consumeWriteBuffer(unsigned nbytes) 00215 { 00216 QByteArray *buf = outBuf.first(); 00217 if (buf == NULL) 00218 return; // nothing to consume 00219 00220 if (nbytes < buf->size() - outBufIndex) 00221 // we want to consume less than there is in the first buffer 00222 outBufIndex += nbytes; 00223 else 00224 { 00225 nbytes -= buf->size() - outBufIndex; 00226 outBufIndex = 0; 00227 outBuf.remove(); 00228 00229 while ((buf = outBuf.current()) != NULL) 00230 if (buf->size() <= nbytes) 00231 { 00232 nbytes -= buf->size(); 00233 outBuf.remove(); 00234 } 00235 else 00236 { 00237 outBufIndex = nbytes; 00238 break; 00239 } 00240 } 00241 } 00242 00243 unsigned KBufferedIO::feedReadBuffer(unsigned nbytes, const char *buffer, bool atBeginning) 00244 { 00245 if (nbytes == 0) 00246 return 0; 00247 00248 QByteArray *a = new QByteArray(nbytes); 00249 a->duplicate(buffer, nbytes); 00250 00251 if (atBeginning) 00252 inBuf.prepend(a); 00253 else 00254 inBuf.append(a); 00255 00256 return nbytes; 00257 } 00258 00259 unsigned KBufferedIO::feedWriteBuffer(unsigned nbytes, const char *buffer) 00260 { 00261 if (nbytes == 0) 00262 return 0; 00263 00264 QByteArray *a = new QByteArray(nbytes); 00265 a->duplicate(buffer, nbytes); 00266 outBuf.append(a); 00267 return nbytes; 00268 } 00269 00270 unsigned KBufferedIO::readBufferSize() const 00271 { 00272 unsigned count = 0; 00273 QByteArray *buf = ((KBufferedIO*)this)->inBuf.first(); 00274 while (buf != NULL) 00275 { 00276 count += buf->size(); 00277 buf = ((KBufferedIO*)this)->inBuf.next(); 00278 } 00279 00280 return count - inBufIndex; 00281 } 00282 00283 unsigned KBufferedIO::writeBufferSize() const 00284 { 00285 unsigned count = 0; 00286 QByteArray *buf = ((KBufferedIO*)this)->outBuf.first(); 00287 while (buf != NULL) 00288 { 00289 count += buf->size(); 00290 buf = (const_cast<KBufferedIO*>(this))->outBuf.next(); 00291 } 00292 00293 return count - outBufIndex; 00294 } 00295 00296 void KBufferedIO::virtual_hook( int id, void* data ) 00297 { KAsyncIO::virtual_hook( id, data ); } 00298 00299 #include "kbufferedio.moc"