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 <tqptrlist.h> 00026 #include <tqcstring.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 #ifdef USE_QT3 00115 int KBufferedIO::bytesAvailable() const 00116 #endif // USE_QT3 00117 #ifdef USE_QT4 00118 qint64 KBufferedIO::bytesAvailable() const 00119 #endif // USE_QT4 00120 { 00121 return readBufferSize(); 00122 } 00123 00124 #ifdef USE_QT3 00125 int KBufferedIO::bytesToWrite() const 00126 #endif // USE_QT3 00127 #ifdef USE_QT4 00128 qint64 KBufferedIO::bytesToWrite() const 00129 #endif // USE_QT4 00130 { 00131 return writeBufferSize(); 00132 } 00133 00134 // This function will scan the read buffer for a '\n' 00135 bool KBufferedIO::canReadLine() const 00136 { 00137 if (bytesAvailable() == 0) 00138 return false; // no new line in here 00139 00140 TQByteArray* buf; 00141 00142 // scan each TQByteArray for the occurrence of '\n' 00143 TQPtrList<TQByteArray> &buflist = ((KBufferedIO*)this)->inBuf; 00144 buf = buflist.first(); 00145 char *p = buf->data() + inBufIndex; 00146 int n = buf->size() - inBufIndex; 00147 while (buf != NULL) 00148 { 00149 while (n--) 00150 if (*p++ == '\n') 00151 return true; 00152 buf = buflist.next(); 00153 if (buf != NULL) 00154 { 00155 p = buf->data(); 00156 n = buf->size(); 00157 } 00158 } 00159 00160 return false; // no new line found 00161 } 00162 00163 // unreads the current data 00164 // that is, writes into the read buffer, at the beginning 00165 int KBufferedIO::unreadBlock(const char *data, uint len) 00166 { 00167 return feedReadBuffer(len, data, true); 00168 } 00169 00170 // 00171 // protected member functions 00172 // 00173 00174 unsigned KBufferedIO::consumeReadBuffer(unsigned nbytes, char *destbuffer, bool discard) 00175 { 00176 { 00177 unsigned u = readBufferSize(); 00178 if (nbytes > u) 00179 nbytes = u; // we can't consume more than there is 00180 } 00181 00182 TQByteArray *buf; 00183 unsigned copied = 0; 00184 unsigned index = inBufIndex; 00185 00186 buf = inBuf.first(); 00187 while (nbytes && buf) 00188 { 00189 // should we copy it all? 00190 unsigned to_copy = buf->size() - index; 00191 if (to_copy > nbytes) 00192 to_copy = nbytes; 00193 00194 if (destbuffer) 00195 memcpy(destbuffer + copied, buf->data() + index, to_copy); 00196 nbytes -= to_copy; 00197 copied += to_copy; 00198 00199 if (buf->size() - index > to_copy) 00200 { 00201 index += to_copy; 00202 break; // we aren't copying everything, that means that's 00203 // all the user wants 00204 } 00205 else 00206 { 00207 index = 0; 00208 if (discard) 00209 { 00210 inBuf.remove(); 00211 buf = inBuf.first(); 00212 } 00213 else 00214 buf = inBuf.next(); 00215 } 00216 } 00217 00218 if (discard) 00219 inBufIndex = index; 00220 00221 return copied; 00222 } 00223 00224 void KBufferedIO::consumeWriteBuffer(unsigned nbytes) 00225 { 00226 TQByteArray *buf = outBuf.first(); 00227 if (buf == NULL) 00228 return; // nothing to consume 00229 00230 if (nbytes < buf->size() - outBufIndex) 00231 // we want to consume less than there is in the first buffer 00232 outBufIndex += nbytes; 00233 else 00234 { 00235 nbytes -= buf->size() - outBufIndex; 00236 outBufIndex = 0; 00237 outBuf.remove(); 00238 00239 while ((buf = outBuf.current()) != NULL) 00240 if (buf->size() <= nbytes) 00241 { 00242 nbytes -= buf->size(); 00243 outBuf.remove(); 00244 } 00245 else 00246 { 00247 outBufIndex = nbytes; 00248 break; 00249 } 00250 } 00251 } 00252 00253 unsigned KBufferedIO::feedReadBuffer(unsigned nbytes, const char *buffer, bool atBeginning) 00254 { 00255 if (nbytes == 0) 00256 return 0; 00257 00258 TQByteArray *a = new TQByteArray(nbytes); 00259 a->duplicate(buffer, nbytes); 00260 00261 if (atBeginning) 00262 inBuf.prepend(a); 00263 else 00264 inBuf.append(a); 00265 00266 return nbytes; 00267 } 00268 00269 unsigned KBufferedIO::feedWriteBuffer(unsigned nbytes, const char *buffer) 00270 { 00271 if (nbytes == 0) 00272 return 0; 00273 00274 TQByteArray *a = new TQByteArray(nbytes); 00275 a->duplicate(buffer, nbytes); 00276 outBuf.append(a); 00277 return nbytes; 00278 } 00279 00280 unsigned KBufferedIO::readBufferSize() const 00281 { 00282 unsigned count = 0; 00283 TQByteArray *buf = ((KBufferedIO*)this)->inBuf.first(); 00284 while (buf != NULL) 00285 { 00286 count += buf->size(); 00287 buf = ((KBufferedIO*)this)->inBuf.next(); 00288 } 00289 00290 return count - inBufIndex; 00291 } 00292 00293 unsigned KBufferedIO::writeBufferSize() const 00294 { 00295 unsigned count = 0; 00296 TQByteArray *buf = ((KBufferedIO*)this)->outBuf.first(); 00297 while (buf != NULL) 00298 { 00299 count += buf->size(); 00300 buf = (const_cast<KBufferedIO*>(this))->outBuf.next(); 00301 } 00302 00303 return count - outBufIndex; 00304 } 00305 00306 void KBufferedIO::virtual_hook( int id, void* data ) 00307 { KAsyncIO::virtual_hook( id, data ); } 00308 00309 #include "kbufferedio.moc"