00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qbitarray.h"
00039 #include "qdatastream.h"
00040
00041 #define SHBLOCK ((bitarr_data*)(sharedBlock()))
00042
00043
00142 QBitArray::QBitArray() : QByteArray( 0, 0 )
00143 {
00144 bitarr_data *x = new bitarr_data;
00145 Q_CHECK_PTR( x );
00146 x->nbits = 0;
00147 setSharedBlock( x );
00148 }
00149
00156 QBitArray::QBitArray( uint size ) : QByteArray( 0, 0 )
00157 {
00158 bitarr_data *x = new bitarr_data;
00159 Q_CHECK_PTR( x );
00160 x->nbits = 0;
00161 setSharedBlock( x );
00162 resize( size );
00163 }
00164
00182 void QBitArray::pad0()
00183 {
00184 uint sz = size();
00185 if ( sz && sz%8 )
00186 *(data()+sz/8) &= (1 << (sz%8)) - 1;
00187 }
00188
00189
00208 bool QBitArray::resize( uint size )
00209 {
00210 uint s = this->size();
00211 if ( !QByteArray::resize( (size+7)/8 ) )
00212 return FALSE;
00213 SHBLOCK->nbits = size;
00214 if ( size != 0 ) {
00215 int ds = (int)(size+7)/8 - (int)(s+7)/8;
00216 if ( ds > 0 )
00217 memset( data() + (s+7)/8, 0, ds );
00218 }
00219 return TRUE;
00220 }
00221
00222
00236 bool QBitArray::fill( bool v, int size )
00237 {
00238 if ( size >= 0 ) {
00239 if ( !resize( size ) )
00240 return FALSE;
00241 } else {
00242 size = this->size();
00243 }
00244 if ( size > 0 )
00245 memset( data(), v ? 0xff : 0, (size + 7) / 8 );
00246 if ( v )
00247 pad0();
00248 return TRUE;
00249 }
00250
00251
00263 void QBitArray::detach()
00264 {
00265 int nbits = SHBLOCK->nbits;
00266 this->duplicate( *this );
00267 SHBLOCK->nbits = nbits;
00268 }
00269
00276 QBitArray QBitArray::copy() const
00277 {
00278 QBitArray tmp;
00279 tmp.duplicate( *this );
00280 ((bitarr_data*)(tmp.sharedBlock()))->nbits = SHBLOCK->nbits;
00281 return tmp;
00282 }
00283
00284
00292 bool QBitArray::testBit( uint index ) const
00293 {
00294 #if defined(QT_CHECK_RANGE)
00295 if ( index >= size() ) {
00296 qWarning( "QBitArray::testBit: Index %d out of range", index );
00297 return FALSE;
00298 }
00299 #endif
00300 return (*(data()+(index>>3)) & (1 << (index & 7))) != 0;
00301 }
00302
00311 void QBitArray::setBit( uint index )
00312 {
00313 #if defined(QT_CHECK_RANGE)
00314 if ( index >= size() ) {
00315 qWarning( "QBitArray::setBit: Index %d out of range", index );
00316 return;
00317 }
00318 #endif
00319 *(data()+(index>>3)) |= (1 << (index & 7));
00320 }
00321
00344 void QBitArray::clearBit( uint index )
00345 {
00346 #if defined(QT_CHECK_RANGE)
00347 if ( index >= size() ) {
00348 qWarning( "QBitArray::clearBit: Index %d out of range", index );
00349 return;
00350 }
00351 #endif
00352 *(data()+(index>>3)) &= ~(1 << (index & 7));
00353 }
00354
00364 bool QBitArray::toggleBit( uint index )
00365 {
00366 #if defined(QT_CHECK_RANGE)
00367 if ( index >= size() ) {
00368 qWarning( "QBitArray::toggleBit: Index %d out of range", index );
00369 return FALSE;
00370 }
00371 #endif
00372 register uchar *p = (uchar *)data() + (index>>3);
00373 uchar b = (1 << (index & 7));
00374 uchar c = *p & b;
00375 *p ^= b;
00376 return c;
00377 }
00378
00379
00433 QBitArray &QBitArray::operator&=( const QBitArray &a )
00434 {
00435 resize( QMAX(size(), a.size()) );
00436 register uchar *a1 = (uchar *)data();
00437 register uchar *a2 = (uchar *)a.data();
00438 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
00439 int p = QMAX( QByteArray::size(), a.QByteArray::size() ) - n;
00440 while ( n-- > 0 )
00441 *a1++ &= *a2++;
00442 while ( p-- > 0 )
00443 *a1++ = 0;
00444 return *this;
00445 }
00446
00464 QBitArray &QBitArray::operator|=( const QBitArray &a )
00465 {
00466 resize( QMAX(size(), a.size()) );
00467 register uchar *a1 = (uchar *)data();
00468 register uchar *a2 = (uchar *)a.data();
00469 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
00470 while ( n-- > 0 )
00471 *a1++ |= *a2++;
00472 return *this;
00473 }
00474
00492 QBitArray &QBitArray::operator^=( const QBitArray &a )
00493 {
00494 resize( QMAX(size(), a.size()) );
00495 register uchar *a1 = (uchar *)data();
00496 register uchar *a2 = (uchar *)a.data();
00497 int n = QMIN( QByteArray::size(), a.QByteArray::size() );
00498 while ( n-- > 0 )
00499 *a1++ ^= *a2++;
00500 return *this;
00501 }
00502
00514 QBitArray QBitArray::operator~() const
00515 {
00516 QBitArray a( size() );
00517 register uchar *a1 = (uchar *)data();
00518 register uchar *a2 = (uchar *)a.data();
00519 int n = QByteArray::size();
00520 while ( n-- )
00521 *a2++ = ~*a1++;
00522 a.pad0();
00523 return a;
00524 }
00525
00526
00539 QBitArray operator&( const QBitArray &a1, const QBitArray &a2 )
00540 {
00541 QBitArray tmp = a1.copy();
00542 tmp &= a2;
00543 return tmp;
00544 }
00545
00558 QBitArray operator|( const QBitArray &a1, const QBitArray &a2 )
00559 {
00560 QBitArray tmp = a1.copy();
00561 tmp |= a2;
00562 return tmp;
00563 }
00564
00577 QBitArray operator^( const QBitArray &a1, const QBitArray &a2 )
00578 {
00579 QBitArray tmp = a1.copy();
00580 tmp ^= a2;
00581 return tmp;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00618
00619
00620
00621
00629 #ifndef QT_NO_DATASTREAM
00630 QDataStream &operator<<( QDataStream &s, const QBitArray &a )
00631 {
00632 Q_UINT32 len = a.size();
00633 s << len;
00634 if ( len > 0 )
00635 s.writeRawBytes( a.data(), a.QByteArray::size() );
00636 return s;
00637 }
00638
00647 QDataStream &operator>>( QDataStream &s, QBitArray &a )
00648 {
00649 Q_UINT32 len;
00650 s >> len;
00651 if ( !a.resize( (uint)len ) ) {
00652 #if defined(QT_CHECK_NULL)
00653 qWarning( "QDataStream: Not enough memory to read QBitArray" );
00654 #endif
00655 len = 0;
00656 }
00657 if ( len > 0 )
00658 s.readRawBytes( a.data(), a.QByteArray::size() );
00659 return s;
00660 }
00661
00662 #endif // QT_NO_DATASTREAM