summaryrefslogtreecommitdiff
path: root/qmake/tools/qbuffer.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qbuffer.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qbuffer.cpp495
1 files changed, 495 insertions, 0 deletions
diff --git a/qmake/tools/qbuffer.cpp b/qmake/tools/qbuffer.cpp
new file mode 100644
index 0000000..b213dd9
--- a/dev/null
+++ b/qmake/tools/qbuffer.cpp
@@ -0,0 +1,495 @@
1/****************************************************************************
2** $Id$
3**
4** Implementation of QBuffer class
5**
6** Created : 930812
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qbuffer.h"
39#include <stdlib.h>
40
41/*!
42 \class QBuffer qbuffer.h
43 \reentrant
44 \brief The QBuffer class is an I/O device that operates on a QByteArray.
45
46 \ingroup io
47 \ingroup collection
48
49 QBuffer is used to read and write to a memory buffer. It is
50 normally used with a QTextStream or a QDataStream. QBuffer has an
51 associated QByteArray which holds the buffer data. The size() of
52 the buffer is automatically adjusted as data is written.
53
54 The constructor \c QBuffer(QByteArray) creates a QBuffer using an
55 existing byte array. The byte array can also be set with
56 setBuffer(). Writing to the QBuffer will modify the original byte
57 array because QByteArray is \link shclass.html explicitly
58 shared.\endlink
59
60 Use open() to open the buffer before use and to set the mode
61 (read-only, write-only, etc.). close() closes the buffer. The
62 buffer must be closed before reopening or calling setBuffer().
63
64 A common way to use QBuffer is through \l QDataStream or \l
65 QTextStream, which have constructors that take a QBuffer
66 parameter. For convenience, there are also QDataStream and
67 QTextStream constructors that take a QByteArray parameter. These
68 constructors create and open an internal QBuffer.
69
70 Note that QTextStream can also operate on a QString (a Unicode
71 string); a QBuffer cannot.
72
73 You can also use QBuffer directly through the standard QIODevice
74 functions readBlock(), writeBlock() readLine(), at(), getch(),
75 putch() and ungetch().
76
77 \sa QFile, QDataStream, QTextStream, QByteArray, \link shclass.html Shared Classes\endlink
78*/
79
80
81/*!
82 Constructs an empty buffer.
83*/
84
85QBuffer::QBuffer()
86{
87 setFlags( IO_Direct );
88 a_inc = 16; // initial increment
89 a_len = 0;
90 ioIndex = 0;
91}
92
93
94/*!
95 Constructs a buffer that operates on \a buf.
96
97 If you open the buffer in write mode (\c IO_WriteOnly or
98 \c IO_ReadWrite) and write something into the buffer, \a buf
99 will be modified.
100
101 Example:
102 \code
103 QCString str = "abc";
104 QBuffer b( str );
105 b.open( IO_WriteOnly );
106 b.at( 3 ); // position at the 4th character (the terminating \0)
107 b.writeBlock( "def", 4 ); // write "def" including the terminating \0
108 b.close();
109 // Now, str == "abcdef" with a terminating \0
110 \endcode
111
112 \sa setBuffer()
113*/
114
115QBuffer::QBuffer( QByteArray buf ) : a(buf)
116{
117 setFlags( IO_Direct );
118 a_len = a.size();
119 a_inc = (a_len > 512) ? 512 : a_len; // initial increment
120 if ( a_inc < 16 )
121 a_inc = 16;
122 ioIndex = 0;
123}
124
125/*!
126 Destroys the buffer.
127*/
128
129QBuffer::~QBuffer()
130{
131}
132
133
134/*!
135 Replaces the buffer's contents with \a buf and returns TRUE.
136
137 Does nothing (and returns FALSE) if isOpen() is TRUE.
138
139 Note that if you open the buffer in write mode (\c IO_WriteOnly or
140 IO_ReadWrite) and write something into the buffer, \a buf is also
141 modified because QByteArray is an explicitly shared class.
142
143 \sa buffer(), open(), close()
144*/
145
146bool QBuffer::setBuffer( QByteArray buf )
147{
148 if ( isOpen() ) {
149#if defined(QT_CHECK_STATE)
150 qWarning( "QBuffer::setBuffer: Buffer is open" );
151#endif
152 return FALSE;
153 }
154 a = buf;
155 a_len = a.size();
156 a_inc = (a_len > 512) ? 512 : a_len; // initial increment
157 if ( a_inc < 16 )
158 a_inc = 16;
159 ioIndex = 0;
160 return TRUE;
161}
162
163/*!
164 \fn QByteArray QBuffer::buffer() const
165
166 Returns this buffer's byte array.
167
168 \sa setBuffer()
169*/
170
171/*!
172 \reimp
173
174 Opens the buffer in mode \a m. Returns TRUE if successful;
175 otherwise returns FALSE. The buffer must be opened before use.
176
177 The mode parameter \a m must be a combination of the following flags.
178 \list
179 \i \c IO_ReadOnly opens the buffer in read-only mode.
180 \i \c IO_WriteOnly opens the buffer in write-only mode.
181 \i \c IO_ReadWrite opens the buffer in read/write mode.
182 \i \c IO_Append sets the buffer index to the end of the buffer.
183 \i \c IO_Truncate truncates the buffer.
184 \endlist
185
186 \sa close(), isOpen()
187*/
188
189bool QBuffer::open( int m )
190{
191 if ( isOpen() ) { // buffer already open
192#if defined(QT_CHECK_STATE)
193 qWarning( "QBuffer::open: Buffer already open" );
194#endif
195 return FALSE;
196 }
197 setMode( m );
198 if ( m & IO_Truncate ) { // truncate buffer
199 a.resize( 0 );
200 a_len = 0;
201 }
202 if ( m & IO_Append ) { // append to end of buffer
203 ioIndex = a.size();
204 } else {
205 ioIndex = 0;
206 }
207 a_inc = 16;
208 setState( IO_Open );
209 setStatus( 0 );
210 return TRUE;
211}
212
213/*!
214 \reimp
215
216 Closes an open buffer.
217
218 \sa open()
219*/
220
221void QBuffer::close()
222{
223 if ( isOpen() ) {
224 setFlags( IO_Direct );
225 ioIndex = 0;
226 a_inc = 16;
227 }
228}
229
230/*!
231 \reimp
232
233 The flush function does nothing for a QBuffer.
234*/
235
236void QBuffer::flush()
237{
238 return;
239}
240
241
242/*!
243 \fn QIODevice::Offset QBuffer::at() const
244
245 \reimp
246*/
247
248/*!
249 \fn QIODevice::Offset QBuffer::size() const
250
251 \reimp
252*/
253
254/*!
255 \reimp
256*/
257
258bool QBuffer::at( Offset pos )
259{
260#if defined(QT_CHECK_STATE)
261 if ( !isOpen() ) {
262 qWarning( "QBuffer::at: Buffer is not open" );
263 return FALSE;
264 }
265#endif
266 if ( pos > a_len ) {
267#if defined(QT_CHECK_RANGE)
268#if defined(QT_LARGEFILE_SUPPORT) && defined(QT_ABI_64BITOFFSET)
269 qWarning( "QBuffer::at: Index %llu out of range", pos );
270#else
271 qWarning( "QBuffer::at: Index %lu out of range", pos );
272#endif
273#endif
274 return FALSE;
275 }
276 ioIndex = pos;
277 return TRUE;
278}
279
280
281/*!
282 \reimp
283*/
284
285Q_LONG QBuffer::readBlock( char *p, Q_ULONG len )
286{
287#if defined(QT_CHECK_STATE)
288 if ( !p ) {
289 qWarning( "QBuffer::readBlock: Null pointer error" );
290 return -1;
291 }
292 if ( !isOpen() ) { // buffer not open
293 qWarning( "QBuffer::readBlock: Buffer not open" );
294 return -1;
295 }
296 if ( !isReadable() ) { // reading not permitted
297 qWarning( "QBuffer::readBlock: Read operation not permitted" );
298 return -1;
299 }
300#endif
301 if ( ioIndex + len > a.size() ) { // overflow
302 if ( ioIndex >= a.size() ) {
303 return 0;
304 } else {
305 len = a.size() - ioIndex;
306 }
307 }
308 memcpy( p, a.data()+ioIndex, len );
309 ioIndex += len;
310 return len;
311}
312
313/*!
314 \overload Q_LONG QBuffer::writeBlock( const QByteArray& data )
315
316 This convenience function is the same as calling
317 \c{writeBlock( data.data(), data.size() )} with \a data.
318*/
319
320/*!
321 Writes \a len bytes from \a p into the buffer at the current
322 index position, overwriting any characters there and extending the
323 buffer if necessary. Returns the number of bytes actually written.
324
325 Returns -1 if an error occurred.
326
327 \sa readBlock()
328*/
329
330Q_LONG QBuffer::writeBlock( const char *p, Q_ULONG len )
331{
332 if ( len == 0 )
333 return 0;
334
335#if defined(QT_CHECK_NULL)
336 if ( p == 0 ) {
337 qWarning( "QBuffer::writeBlock: Null pointer error" );
338 return -1;
339 }
340#endif
341#if defined(QT_CHECK_STATE)
342 if ( !isOpen() ) { // buffer not open
343 qWarning( "QBuffer::writeBlock: Buffer not open" );
344 return -1;
345 }
346 if ( !isWritable() ) { // writing not permitted
347 qWarning( "QBuffer::writeBlock: Write operation not permitted" );
348 return -1;
349 }
350#endif
351 if ( ioIndex + len >= a_len ) { // overflow
352 Q_ULONG new_len = a_len + a_inc*((ioIndex+len-a_len)/a_inc+1);
353 if ( !a.resize( new_len ) ) { // could not resize
354#if defined(QT_CHECK_NULL)
355 qWarning( "QBuffer::writeBlock: Memory allocation error" );
356#endif
357 setStatus( IO_ResourceError );
358 return -1;
359 }
360 a_inc *= 2; // double increment
361 a_len = new_len;
362 a.shd->len = ioIndex + len;
363 }
364 memcpy( a.data()+ioIndex, p, len );
365 ioIndex += len;
366 if ( a.shd->len < ioIndex )
367 a.shd->len = ioIndex; // fake (not alloc'd) length
368 return len;
369}
370
371
372/*!
373 \reimp
374*/
375
376Q_LONG QBuffer::readLine( char *p, Q_ULONG maxlen )
377{
378#if defined(QT_CHECK_NULL)
379 if ( p == 0 ) {
380 qWarning( "QBuffer::readLine: Null pointer error" );
381 return -1;
382 }
383#endif
384#if defined(QT_CHECK_STATE)
385 if ( !isOpen() ) { // buffer not open
386 qWarning( "QBuffer::readLine: Buffer not open" );
387 return -1;
388 }
389 if ( !isReadable() ) { // reading not permitted
390 qWarning( "QBuffer::readLine: Read operation not permitted" );
391 return -1;
392 }
393#endif
394 if ( maxlen == 0 )
395 return 0;
396 Q_ULONG start = ioIndex;
397 char *d = a.data() + ioIndex;
398 maxlen--; // make room for 0-terminator
399 if ( a.size() - ioIndex < maxlen )
400 maxlen = a.size() - ioIndex;
401 while ( maxlen-- ) {
402 if ( (*p++ = *d++) == '\n' )
403 break;
404 }
405 *p = '\0';
406 ioIndex = d - a.data();
407 return ioIndex - start;
408}
409
410
411/*!
412 \reimp
413*/
414
415int QBuffer::getch()
416{
417#if defined(QT_CHECK_STATE)
418 if ( !isOpen() ) { // buffer not open
419 qWarning( "QBuffer::getch: Buffer not open" );
420 return -1;
421 }
422 if ( !isReadable() ) { // reading not permitted
423 qWarning( "QBuffer::getch: Read operation not permitted" );
424 return -1;
425 }
426#endif
427 if ( ioIndex+1 > a.size() ) { // overflow
428 setStatus( IO_ReadError );
429 return -1;
430 }
431 return uchar(*(a.data()+ioIndex++));
432}
433
434/*!
435 \reimp
436
437 Writes the character \a ch into the buffer at the current index
438 position, overwriting any existing character and extending the
439 buffer if necessary.
440
441 Returns \a ch, or -1 if an error occurred.
442
443 \sa getch(), ungetch()
444*/
445
446int QBuffer::putch( int ch )
447{
448#if defined(QT_CHECK_STATE)
449 if ( !isOpen() ) { // buffer not open
450 qWarning( "QBuffer::putch: Buffer not open" );
451 return -1;
452 }
453 if ( !isWritable() ) { // writing not permitted
454 qWarning( "QBuffer::putch: Write operation not permitted" );
455 return -1;
456 }
457#endif
458 if ( ioIndex + 1 >= a_len ) { // overflow
459 char buf[1];
460 buf[0] = (char)ch;
461 if ( writeBlock(buf,1) != 1 )
462 return -1; // write error
463 } else {
464 *(a.data() + ioIndex++) = (char)ch;
465 if ( a.shd->len < ioIndex )
466 a.shd->len = ioIndex;
467 }
468 return ch;
469}
470
471/*!
472 \reimp
473*/
474
475int QBuffer::ungetch( int ch )
476{
477#if defined(QT_CHECK_STATE)
478 if ( !isOpen() ) { // buffer not open
479 qWarning( "QBuffer::ungetch: Buffer not open" );
480 return -1;
481 }
482 if ( !isReadable() ) { // reading not permitted
483 qWarning( "QBuffer::ungetch: Read operation not permitted" );
484 return -1;
485 }
486#endif
487 if ( ch != -1 ) {
488 if ( ioIndex )
489 ioIndex--;
490 else
491 ch = -1;
492 }
493 return ch;
494}
495