source: vendor/trolltech/current/src/tools/qbitarray.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 16.1 KB
Line 
1/****************************************************************************
2** $Id: qbitarray.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QBitArray class
5**
6** Created : 940118
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 "qbitarray.h"
39#include "qdatastream.h"
40
41#define SHBLOCK ((bitarr_data*)(sharedBlock()))
42
43
44/*!
45 \class QBitVal qbitarray.h
46 \reentrant
47 \brief The QBitVal class is an internal class, used with QBitArray.
48
49 \ingroup collection
50
51 The QBitVal is required by the indexing [] operator on bit arrays.
52 It is not for use in any other context.
53*/
54
55/*!
56 \fn QBitVal::QBitVal (QBitArray* a, uint i)
57
58 Constructs a reference to element \a i in the QBitArray \a a.
59 This is what QBitArray::operator[] constructs its return value
60 with.
61*/
62
63/*!
64 \fn QBitVal::operator int()
65
66 Returns the value referenced by the QBitVal.
67*/
68
69/*!
70 \fn QBitVal& QBitVal::operator= (const QBitVal& v)
71
72 Sets the value referenced by the QBitVal to that referenced by
73 QBitVal \a v.
74*/
75
76/*!
77 \overload QBitVal& QBitVal::operator= (bool v)
78
79 Sets the value referenced by the QBitVal to \a v.
80*/
81
82
83/*!
84 \class QBitArray qbitarray.h
85 \reentrant
86 \brief The QBitArray class provides an array of bits.
87
88 \ingroup collection
89 \ingroup tools
90 \ingroup shared
91
92 Because QBitArray is a QMemArray, it uses explicit \link
93 shclass.html sharing\endlink with a reference count.
94
95 A QBitArray is a special byte array that can access individual
96 bits and perform bit-operations (AND, OR, XOR and NOT) on entire
97 arrays or bits.
98
99 Bits can be manipulated by the setBit() and clearBit() functions,
100 but it is also possible to use the indexing [] operator to test
101 and set individual bits. The [] operator is a little slower than
102 setBit() and clearBit() because some tricks are required to
103 implement single-bit assignments.
104
105 Example:
106 \code
107 QBitArray a(3);
108 a.setBit( 0 );
109 a.clearBit( 1 );
110 a.setBit( 2 ); // a = [1 0 1]
111
112 QBitArray b(3);
113 b[0] = 1;
114 b[1] = 1;
115 b[2] = 0; // b = [1 1 0]
116
117 QBitArray c;
118 c = ~a & b; // c = [0 1 0]
119 \endcode
120
121 When a QBitArray is constructed the bits are uninitialized. Use
122 fill() to set all the bits to 0 or 1. The array can be resized
123 with resize() and copied with copy(). Bits can be set with
124 setBit() and cleared with clearBit(). Bits can be toggled with
125 toggleBit(). A bit's value can be obtained with testBit() and with
126 at().
127
128 QBitArray supports the \& (AND), | (OR), ^ (XOR) and ~ (NOT)
129 operators.
130*/
131
132/*! \class QBitArray::bitarr_data
133 \brief The QBitArray::bitarr_data class is internal.
134 \internal
135*/
136
137
138/*!
139 Constructs an empty bit array.
140*/
141
142QBitArray::QBitArray() : QByteArray( 0, 0 )
143{
144 bitarr_data *x = new bitarr_data;
145 Q_CHECK_PTR( x );
146 x->nbits = 0;
147 setSharedBlock( x );
148}
149
150/*!
151 Constructs a bit array of \a size bits. The bits are uninitialized.
152
153 \sa fill()
154*/
155
156QBitArray::QBitArray( uint size ) : QByteArray( 0, 0 )
157{
158 bitarr_data *x = new bitarr_data;
159 Q_CHECK_PTR( x );
160 x->nbits = 0;
161 setSharedBlock( x );
162 resize( size );
163}
164
165/*!
166 \fn QBitArray::QBitArray( const QBitArray &a )
167
168 Constructs a shallow copy of \a a.
169*/
170
171/*!
172 \fn QBitArray &QBitArray::operator=( const QBitArray &a )
173
174 Assigns a shallow copy of \a a to this bit array and returns a
175 reference to this array.
176*/
177
178
179/*!
180 Pad last byte with 0-bits.
181*/
182void QBitArray::pad0()
183{
184 uint sz = size();
185 if ( sz && sz%8 )
186 *(data()+sz/8) &= (1 << (sz%8)) - 1;
187}
188
189
190/*!
191 \fn uint QBitArray::size() const
192
193 Returns the bit array's size (number of bits).
194
195 \sa resize()
196*/
197
198/*!
199 Resizes the bit array to \a size bits and returns TRUE if the bit
200 array could be resized; otherwise returns FALSE. The array becomes
201 a null array if \a size == 0.
202
203 If the array is expanded, the new bits are set to 0.
204
205 \sa size()
206*/
207
208bool QBitArray::resize( uint size )
209{
210 uint s = this->size();
211 if ( !QByteArray::resize( (size+7)/8 ) )
212 return FALSE; // cannot resize
213 SHBLOCK->nbits = size;
214 if ( size != 0 ) { // not null array
215 int ds = (int)(size+7)/8 - (int)(s+7)/8;// number of bytes difference
216 if ( ds > 0 ) // expanding array
217 memset( data() + (s+7)/8, 0, ds ); // reset new data
218 }
219 return TRUE;
220}
221
222
223/*!
224 Fills the bit array with \a v (1's if \a v is TRUE, or 0's if \a v
225 is FALSE).
226
227 fill() resizes the bit array to \a size bits if \a size is
228 nonnegative.
229
230 Returns FALSE if a nonnegative \e size was specified and the bit
231 array could not be resized; otherwise returns TRUE.
232
233 \sa resize()
234*/
235
236bool QBitArray::fill( bool v, int size )
237{
238 if ( size >= 0 ) { // resize first
239 if ( !resize( size ) )
240 return FALSE; // cannot resize
241 } else {
242 size = this->size();
243 }
244 if ( size > 0 )
245 memset( data(), v ? 0xff : 0, (size + 7) / 8 );
246 if ( v )
247 pad0();
248 return TRUE;
249}
250
251
252/*!
253 Detaches from shared bit array data and makes sure that this bit
254 array is the only one referring to the data.
255
256 If multiple bit arrays share common data, this bit array
257 dereferences the data and gets a copy of the data. Nothing happens
258 if there is only a single reference.
259
260 \sa copy()
261*/
262
263void QBitArray::detach()
264{
265 int nbits = SHBLOCK->nbits;
266 this->duplicate( *this );
267 SHBLOCK->nbits = nbits;
268}
269
270/*!
271 Returns a deep copy of the bit array.
272
273 \sa detach()
274*/
275
276QBitArray QBitArray::copy() const
277{
278 QBitArray tmp;
279 tmp.duplicate( *this );
280 ((bitarr_data*)(tmp.sharedBlock()))->nbits = SHBLOCK->nbits;
281 return tmp;
282}
283
284
285/*!
286 Returns TRUE if the bit at position \a index is set, i.e. is 1;
287 otherwise returns FALSE.
288
289 \sa setBit(), clearBit()
290*/
291
292bool QBitArray::testBit( uint index ) const
293{
294#if defined(QT_CHECK_RANGE)
295 if ( index >= size() ) {
296 qWarning( "QBitArray::testBit: Index %d out of range", index );
297 return FALSE;
298 }
299#endif
300 return (*(data()+(index>>3)) & (1 << (index & 7))) != 0;
301}
302
303/*!
304 \overload
305
306 Sets the bit at position \a index to 1.
307
308 \sa clearBit() toggleBit()
309*/
310
311void QBitArray::setBit( uint index )
312{
313#if defined(QT_CHECK_RANGE)
314 if ( index >= size() ) {
315 qWarning( "QBitArray::setBit: Index %d out of range", index );
316 return;
317 }
318#endif
319 *(data()+(index>>3)) |= (1 << (index & 7));
320}
321
322/*!
323 \fn void QBitArray::setBit( uint index, bool value )
324
325 Sets the bit at position \a index to \a value.
326
327 Equivalent to:
328 \code
329 if ( value )
330 setBit( index );
331 else
332 clearBit( index );
333 \endcode
334
335 \sa clearBit() toggleBit()
336*/
337
338/*!
339 Clears the bit at position \a index, i.e. sets it to 0.
340
341 \sa setBit(), toggleBit()
342*/
343
344void QBitArray::clearBit( uint index )
345{
346#if defined(QT_CHECK_RANGE)
347 if ( index >= size() ) {
348 qWarning( "QBitArray::clearBit: Index %d out of range", index );
349 return;
350 }
351#endif
352 *(data()+(index>>3)) &= ~(1 << (index & 7));
353}
354
355/*!
356 Toggles the bit at position \a index.
357
358 If the previous value was 0, the new value will be 1. If the
359 previous value was 1, the new value will be 0.
360
361 \sa setBit(), clearBit()
362*/
363
364bool QBitArray::toggleBit( uint index )
365{
366#if defined(QT_CHECK_RANGE)
367 if ( index >= size() ) {
368 qWarning( "QBitArray::toggleBit: Index %d out of range", index );
369 return FALSE;
370 }
371#endif
372 register uchar *p = (uchar *)data() + (index>>3);
373 uchar b = (1 << (index & 7)); // bit position
374 uchar c = *p & b; // read bit
375 *p ^= b; // toggle bit
376 return c;
377}
378
379
380/*!
381 \fn bool QBitArray::at( uint index ) const
382
383 Returns the value (0 or 1) of the bit at position \a index.
384
385 \sa operator[]()
386*/
387
388/*!
389 \fn QBitVal QBitArray::operator[]( int index )
390
391 Implements the [] operator for bit arrays.
392
393 The returned QBitVal is a context object. It makes it possible to
394 get and set a single bit value by its \a index position.
395
396 Example:
397 \code
398 QBitArray a( 3 );
399 a[0] = 0;
400 a[1] = 1;
401 a[2] = a[0] ^ a[1];
402 \endcode
403
404 The functions testBit(), setBit() and clearBit() are faster.
405
406 \sa at()
407*/
408
409/*!
410 \overload bool QBitArray::operator[]( int index ) const
411
412 Implements the [] operator for constant bit arrays.
413*/
414
415
416/*!
417 Performs the AND operation between all bits in this bit array and
418 \a a. Returns a reference to this bit array.
419
420 The result has the length of the longest of the two bit arrays,
421 with any missing bits (i.e. if one array is shorter than the
422 other), taken to be 0.
423 \code
424 QBitArray a( 3 ), b( 2 );
425 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
426 b[0] = 1; b[1] = 0; // b = [1 0]
427 a &= b; // a = [1 0 0]
428 \endcode
429
430 \sa operator|=(), operator^=(), operator~()
431*/
432
433QBitArray &QBitArray::operator&=( const QBitArray &a )
434{
435 resize( QMAX(size(), a.size()) );
436 register uchar *a1 = (uchar *)data();
437 register uchar *a2 = (uchar *)a.data();
438 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
439 int p = QMAX( QByteArray::size(), a.QByteArray::size() ) - n;
440 while ( n-- > 0 )
441 *a1++ &= *a2++;
442 while ( p-- > 0 )
443 *a1++ = 0;
444 return *this;
445}
446
447/*!
448 Performs the OR operation between all bits in this bit array and
449 \a a. Returns a reference to this bit array.
450
451 The result has the length of the longest of the two bit arrays,
452 with any missing bits (i.e. if one array is shorter than the
453 other), taken to be 0.
454 \code
455 QBitArray a( 3 ), b( 2 );
456 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
457 b[0] = 1; b[1] = 0; // b = [1 0]
458 a |= b; // a = [1 0 1]
459 \endcode
460
461 \sa operator&=(), operator^=(), operator~()
462*/
463
464QBitArray &QBitArray::operator|=( const QBitArray &a )
465{
466 resize( QMAX(size(), a.size()) );
467 register uchar *a1 = (uchar *)data();
468 register uchar *a2 = (uchar *)a.data();
469 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
470 while ( n-- > 0 )
471 *a1++ |= *a2++;
472 return *this;
473}
474
475/*!
476 Performs the XOR operation between all bits in this bit array and
477 \a a. Returns a reference to this bit array.
478
479 The result has the length of the longest of the two bit arrays,
480 with any missing bits (i.e. if one array is shorter than the
481 other), taken to be 0.
482 \code
483 QBitArray a( 3 ), b( 2 );
484 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
485 b[0] = 1; b[1] = 0; // b = [1 0]
486 a ^= b; // a = [0 0 1]
487 \endcode
488
489 \sa operator&=(), operator|=(), operator~()
490*/
491
492QBitArray &QBitArray::operator^=( const QBitArray &a )
493{
494 resize( QMAX(size(), a.size()) );
495 register uchar *a1 = (uchar *)data();
496 register uchar *a2 = (uchar *)a.data();
497 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
498 while ( n-- > 0 )
499 *a1++ ^= *a2++;
500 return *this;
501}
502
503/*!
504 Returns a bit array that contains the inverted bits of this bit array.
505
506 Example:
507 \code
508 QBitArray a( 3 ), b;
509 a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
510 b = ~a; // b = [0 1 0]
511 \endcode
512*/
513
514QBitArray QBitArray::operator~() const
515{
516 QBitArray a( size() );
517 register uchar *a1 = (uchar *)data();
518 register uchar *a2 = (uchar *)a.data();
519 int n = QByteArray::size();
520 while ( n-- )
521 *a2++ = ~*a1++;
522 a.pad0();
523 return a;
524}
525
526
527/*!
528 \relates QBitArray
529
530 Returns the AND result between the bit arrays \a a1 and \a a2.
531
532 The result has the length of the longest of the two bit arrays,
533 with any missing bits (i.e. if one array is shorter than the
534 other), taken to be 0.
535
536 \sa QBitArray::operator&=()
537*/
538
539QBitArray operator&( const QBitArray &a1, const QBitArray &a2 )
540{
541 QBitArray tmp = a1.copy();
542 tmp &= a2;
543 return tmp;
544}
545
546/*!
547 \relates QBitArray
548
549 Returns the OR result between the bit arrays \a a1 and \a a2.
550
551 The result has the length of the longest of the two bit arrays,
552 with any missing bits (i.e. if one array is shorter than the
553 other), taken to be 0.
554
555 \sa QBitArray::operator|=()
556*/
557
558QBitArray operator|( const QBitArray &a1, const QBitArray &a2 )
559{
560 QBitArray tmp = a1.copy();
561 tmp |= a2;
562 return tmp;
563}
564
565/*!
566 \relates QBitArray
567
568 Returns the XOR result between the bit arrays \a a1 and \a a2.
569
570 The result has the length of the longest of the two bit arrays,
571 with any missing bits (i.e. if one array is shorter than the
572 other), taken to be 0.
573
574 \sa QBitArray::operator^()
575*/
576
577QBitArray operator^( const QBitArray &a1, const QBitArray &a2 )
578{
579 QBitArray tmp = a1.copy();
580 tmp ^= a2;
581 return tmp;
582}
583
584
585/* \enum QGArray::array_data
586
587 \warning This will be renamed in the next major release of Qt. Until
588 then it is undocumented and we recommend against its use.
589
590 \internal
591
592 ### 3.0 rename ###
593 ### 3.0 move it to QGArray? ###
594*/
595
596
597/*!
598 \fn QBitArray::array_data * QBitArray::newData()
599
600 \internal
601
602 Returns data specific to QBitArray that extends what QGArray provides.
603 QPtrCollection mechanism for allowing extra/different data.
604*/
605
606
607/*!
608 \fn void QBitArray::deleteData ( array_data * d )
609
610 \internal
611
612 Deletes data specific to QBitArray that extended what QGArray provided.
613
614 QPtrCollection mechanism for allowing extra/different data.
615*/
616
617
618/*****************************************************************************
619 QBitArray stream functions
620 *****************************************************************************/
621
622/*!
623 \relates QBitArray
624
625 Writes bit array \a a to stream \a s.
626
627 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
628*/
629#ifndef QT_NO_DATASTREAM
630QDataStream &operator<<( QDataStream &s, const QBitArray &a )
631{
632 Q_UINT32 len = a.size();
633 s << len; // write size of array
634 if ( len > 0 ) // write data
635 s.writeRawBytes( a.data(), a.QByteArray::size() );
636 return s;
637}
638
639/*!
640 \relates QBitArray
641
642 Reads a bit array into \a a from stream \a s.
643
644 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
645*/
646
647QDataStream &operator>>( QDataStream &s, QBitArray &a )
648{
649 Q_UINT32 len;
650 s >> len; // read size of array
651 if ( !a.resize( (uint)len ) ) { // resize array
652#if defined(QT_CHECK_NULL)
653 qWarning( "QDataStream: Not enough memory to read QBitArray" );
654#endif
655 len = 0;
656 }
657 if ( len > 0 ) // read data
658 s.readRawBytes( a.data(), a.QByteArray::size() );
659 return s;
660}
661
662#endif // QT_NO_DATASTREAM
Note: See TracBrowser for help on using the repository browser.