Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/qtools/qbuffer.cpp

Source at commit 1322 created 9 years 5 months ago.
By meklort, Add doxygen to utils folder
1/****************************************************************************
2**
3**
4** Implementation of QBuffer class
5**
6** Created : 930812
7**
8** Copyright (C) 1992-2000 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// REVISED: paul
42/*!
43 \class QBuffer qbuffer.h
44 \brief The QBuffer class is an I/O device that operates on a QByteArray
45
46 \ingroup io
47
48 QBuffer allows reading and writing a memory buffer. It is normally
49 used together with a QTextStream or a QDataStream. QBuffer has an
50 associated QByteArray which holds the buffer data. The size() of the
51 buffer is automatically adjusted as data is written.
52
53 The constructor \c QBuffer(QByteArray) creates a QBuffer with an
54 existing byte array. The byte array can also be set with setBuffer().
55 Writing to the QBuffer will modify the original byte array, since
56 QByteArray is \link shclass.html explicitly shared.\endlink
57
58 Use open() to open the buffer before use, and to set the mode
59 (read-only,write-only, etc.). close() closes the buffer. The buffer
60 must be closed before reopening or calling setBuffer().
61
62 The common way to use QBuffer is through \l QDataStream or \l QTextStream
63 which have constructors that take a QBuffer parameter. For
64 convenience, there are also QDataStream and QTextStream constructors
65 that take a QByteArray parameter. These constructors create and open
66 an internal QBuffer.
67
68 Note that QTextStream can also operate on a QString (a Unicode
69 string); a QBuffer cannot.
70
71 You can also use QBuffer directly through the standard QIODevice
72 functions readBlock(), writeBlock() readLine(), at(), getch(), putch() and
73 ungetch().
74
75 \sa QFile, QDataStream, QTextStream, QByteArray, \link shclass.html Shared Classes\endlink
76*/
77
78
79/*!
80 Constructs an empty buffer.
81*/
82
83QBuffer::QBuffer()
84{
85 setFlags( IO_Direct );
86 a_inc = 16;// initial increment
87 a_len = 0;
88 ioIndex = 0;
89}
90
91
92/*!
93 Constructs a buffer that operates on \a buf.
94 If you open the buffer in write mode (\c IO_WriteOnly or
95 \c IO_ReadWrite) and write something into the buffer, \a buf
96 will be modified.
97
98
99 Example:
100 \code
101 QCString str = "abc";
102 QBuffer b( str );
103 b.open( IO_WriteOnly );
104 b.at( 3 );// position at \0
105 b.writeBlock( "def", 4 );// write including \0
106 b.close();
107 // Now, str == "abcdef"
108 \endcode
109
110
111 \sa setBuffer()
112*/
113
114QBuffer::QBuffer( QByteArray buf ) : a(buf)
115{
116 setFlags( IO_Direct );
117 a_len = a.size();
118 a_inc = (a_len > 512) ? 512 : a_len;// initial increment
119 if ( a_inc < 16 )
120a_inc = 16;
121 ioIndex = 0;
122}
123
124/*!
125 Destructs the buffer.
126*/
127
128QBuffer::~QBuffer()
129{
130}
131
132
133/*!
134 Replaces the buffer's contents with \a buf.
135
136 This may not be done when isOpen() is TRUE.
137
138 Note that if you open the buffer in write mode (\c IO_WriteOnly or
139 IO_ReadWrite) and write something into the buffer, \a buf is also
140 modified because QByteArray is an explicitly shared class.
141
142 \sa buffer(), open(), close()
143*/
144
145bool QBuffer::setBuffer( QByteArray buf )
146{
147 if ( isOpen() ) {
148#if defined(CHECK_STATE)
149qWarning( "QBuffer::setBuffer: Buffer is open");
150#endif
151return FALSE;
152 }
153 a = buf;
154 a_len = a.size();
155 a_inc = (a_len > 512) ? 512 : a_len;// initial increment
156 if ( a_inc < 16 )
157a_inc = 16;
158 ioIndex = 0;
159 return TRUE;
160}
161
162/*!
163 \fn QByteArray QBuffer::buffer() const
164
165 Returns this buffer's byte array.
166
167 \sa setBuffer()
168*/
169
170/*!
171 \reimp
172 Opens the buffer in the mode \a m. Returns TRUE if successful,
173 otherwise FALSE. The buffer must be opened before use.
174
175 The mode parameter \a m must be a combination of the following flags.
176 <ul>
177 <li>\c IO_ReadOnly opens a buffer in read-only mode.
178 <li>\c IO_WriteOnly opens a buffer in write-only mode.
179 <li>\c IO_ReadWrite opens a buffer in read/write mode.
180 <li>\c IO_Append sets the buffer index to the end of the buffer.
181 <li>\c IO_Truncate truncates the buffer.
182 </ul>
183
184 \sa close(), isOpen()
185*/
186
187bool QBuffer::open( int m )
188{
189 if ( isOpen() ) {// buffer already open
190#if defined(CHECK_STATE)
191qWarning( "QBuffer::open: Buffer already open" );
192#endif
193return FALSE;
194 }
195 setMode( m );
196 if ( m & IO_Truncate ) {// truncate buffer
197a.resize( 0 );
198a_len = 0;
199 }
200 if ( m & IO_Append ) {// append to end of buffer
201ioIndex = a.size();
202 } else {
203ioIndex = 0;
204 }
205 a_inc = 16;
206 setState( IO_Open );
207 setStatus( 0 );
208 return TRUE;
209}
210
211/*!
212 \reimp
213 Closes an open buffer.
214 \sa open()
215*/
216
217void QBuffer::close()
218{
219 if ( isOpen() ) {
220setFlags( IO_Direct );
221ioIndex = 0;
222a_inc = 16;
223 }
224}
225
226/*!
227 \reimp
228 The flush function does nothing for a QBuffer.
229*/
230
231void QBuffer::flush()
232{
233 return;
234}
235
236
237/*!
238 \fn int QBuffer::at() const
239 \reimp
240*/
241
242/*!
243 \fn uint QBuffer::size() const
244 \reimp
245*/
246
247/*!
248 \reimp
249*/
250
251bool QBuffer::at( int pos )
252{
253#if defined(CHECK_STATE)
254 if ( !isOpen() ) {
255qWarning( "QBuffer::at: Buffer is not open" );
256return FALSE;
257 }
258#endif
259 if ( (uint)pos > a_len ) {
260#if defined(CHECK_RANGE)
261qWarning( "QBuffer::at: Index %d out of range", pos );
262#endif
263return FALSE;
264 }
265 ioIndex = pos;
266 return TRUE;
267}
268
269
270/*!
271 \reimp
272*/
273
274int QBuffer::readBlock( char *p, uint len )
275{
276#if defined(CHECK_STATE)
277 CHECK_PTR( p );
278 if ( !isOpen() ) {// buffer not open
279qWarning( "QBuffer::readBlock: Buffer not open" );
280return -1;
281 }
282 if ( !isReadable() ) {// reading not permitted
283qWarning( "QBuffer::readBlock: Read operation not permitted" );
284return -1;
285 }
286#endif
287 if ( (uint)ioIndex + len > a.size() ) {// overflow
288if ( (uint)ioIndex >= a.size() ) {
289 setStatus( IO_ReadError );
290 return -1;
291} else {
292 len = a.size() - (uint)ioIndex;
293}
294 }
295 memcpy( p, a.data()+ioIndex, len );
296 ioIndex += len;
297 return len;
298}
299
300/*!
301 \reimp
302
303 Writes \a len bytes from \a p into the buffer at the current index,
304 overwriting any characters there and extending the buffer if necessary.
305 Returns the number of bytes actually written.
306
307 Returns -1 if a serious error occurred.
308
309 \sa readBlock()
310*/
311
312int QBuffer::writeBlock( const char *p, uint len )
313{
314#if defined(CHECK_NULL)
315 if ( p == 0 && len != 0 )
316qWarning( "QBuffer::writeBlock: Null pointer error" );
317#endif
318#if defined(CHECK_STATE)
319 if ( !isOpen() ) {// buffer not open
320qWarning( "QBuffer::writeBlock: Buffer not open" );
321return -1;
322 }
323 if ( !isWritable() ) {// writing not permitted
324qWarning( "QBuffer::writeBlock: Write operation not permitted" );
325return -1;
326 }
327#endif
328 if ( (uint)ioIndex + len >= a_len ) {// overflow
329uint new_len = a_len + a_inc*(((uint)ioIndex+len-a_len)/a_inc+1);
330if ( !a.resize( new_len ) ) {// could not resize
331#if defined(CHECK_NULL)
332 qWarning( "QBuffer::writeBlock: Memory allocation error" );
333#endif
334 setStatus( IO_ResourceError );
335 return -1;
336}
337a_inc *= 2;// double increment
338a_len = new_len;
339a.shd->len = (uint)ioIndex + len;
340 }
341 memcpy( a.data()+ioIndex, p, len );
342 ioIndex += len;
343 if ( a.shd->len < (uint)ioIndex )
344a.shd->len = (uint)ioIndex;// fake (not alloc'd) length
345 return len;
346}
347
348
349/*!
350 \reimp
351*/
352
353int QBuffer::readLine( char *p, uint maxlen )
354{
355#if defined(CHECK_STATE)
356 CHECK_PTR( p );
357 if ( !isOpen() ) {// buffer not open
358qWarning( "QBuffer::readLine: Buffer not open" );
359return -1;
360 }
361 if ( !isReadable() ) {// reading not permitted
362qWarning( "QBuffer::readLine: Read operation not permitted" );
363return -1;
364 }
365#endif
366 if ( maxlen == 0 )
367return 0;
368 uint start = (uint)ioIndex;
369 char *d = a.data() + ioIndex;
370 maxlen--;// make room for 0-terminator
371 if ( a.size() - (uint)ioIndex < maxlen )
372maxlen = a.size() - (uint)ioIndex;
373 while ( maxlen-- ) {
374if ( (*p++ = *d++) == '\n' )
375 break;
376 }
377 *p = '\0';
378 ioIndex = d - a.data();
379 return (uint)ioIndex - start;
380}
381
382
383/*!
384 \reimp
385*/
386
387int QBuffer::getch()
388{
389#if defined(CHECK_STATE)
390 if ( !isOpen() ) {// buffer not open
391qWarning( "QBuffer::getch: Buffer not open" );
392return -1;
393 }
394 if ( !isReadable() ) {// reading not permitted
395qWarning( "QBuffer::getch: Read operation not permitted" );
396return -1;
397 }
398#endif
399 if ( (uint)ioIndex+1 > a.size() ) {// overflow
400setStatus( IO_ReadError );
401return -1;
402 }
403 return uchar(*(a.data()+ioIndex++));
404}
405
406/*!
407 \reimp
408 Writes the character \a ch into the buffer, overwriting
409 the character at the current index, extending the buffer
410 if necessary.
411
412 Returns \a ch, or -1 if some error occurred.
413
414 \sa getch(), ungetch()
415*/
416
417int QBuffer::putch( int ch )
418{
419#if defined(CHECK_STATE)
420 if ( !isOpen() ) {// buffer not open
421qWarning( "QBuffer::putch: Buffer not open" );
422return -1;
423 }
424 if ( !isWritable() ) {// writing not permitted
425qWarning( "QBuffer::putch: Write operation not permitted" );
426return -1;
427 }
428#endif
429 if ( (uint)ioIndex + 1 >= a_len ) {// overflow
430char buf[1];
431buf[0] = (char)ch;
432if ( writeBlock(buf,1) != 1 )
433 return -1;// write error
434 } else {
435*(a.data() + ioIndex++) = (char)ch;
436if ( a.shd->len < (uint)ioIndex )
437 a.shd->len = (uint)ioIndex;
438 }
439 return ch;
440}
441
442/*!
443 \reimp
444*/
445
446int QBuffer::ungetch( int ch )
447{
448#if defined(CHECK_STATE)
449 if ( !isOpen() ) {// buffer not open
450qWarning( "QBuffer::ungetch: Buffer not open" );
451return -1;
452 }
453 if ( !isReadable() ) {// reading not permitted
454qWarning( "QBuffer::ungetch: Read operation not permitted" );
455return -1;
456 }
457#endif
458 if ( ch != -1 ) {
459if ( ioIndex )
460 ioIndex--;
461else
462 ch = -1;
463 }
464 return ch;
465}
466

Archive Download this file

Revision: 1322