summaryrefslogtreecommitdiff
path: root/qmake/tools/qbitarray.cpp
Side-by-side diff
Diffstat (limited to 'qmake/tools/qbitarray.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qbitarray.cpp661
1 files changed, 661 insertions, 0 deletions
diff --git a/qmake/tools/qbitarray.cpp b/qmake/tools/qbitarray.cpp
new file mode 100644
index 0000000..4f4e14b
--- a/dev/null
+++ b/qmake/tools/qbitarray.cpp
@@ -0,0 +1,661 @@
+/****************************************************************************
+** $Id$
+**
+** Implementation of QBitArray class
+**
+** Created : 940118
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the tools module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
+** licenses may use this file in accordance with the Qt Commercial License
+** Agreement provided with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qbitarray.h"
+#include "qdatastream.h"
+
+#define SHBLOCK ((bitarr_data*)(sharedBlock()))
+
+
+/*!
+ \class QBitVal qbitarray.h
+ \reentrant
+ \brief The QBitVal class is an internal class, used with QBitArray.
+
+ \ingroup collection
+
+ The QBitVal is required by the indexing [] operator on bit arrays.
+ It is not for use in any other context.
+*/
+
+/*!
+ \fn QBitVal::QBitVal (QBitArray* a, uint i)
+
+ Constructs a reference to element \a i in the QBitArray \a a.
+ This is what QBitArray::operator[] constructs its return value
+ with.
+*/
+
+/*!
+ \fn QBitVal::operator int()
+
+ Returns the value referenced by the QBitVal.
+*/
+
+/*!
+ \fn QBitVal& QBitVal::operator= (const QBitVal& v)
+
+ Sets the value referenced by the QBitVal to that referenced by
+ QBitVal \a v.
+*/
+
+/*!
+ \overload QBitVal& QBitVal::operator= (bool v)
+
+ Sets the value referenced by the QBitVal to \a v.
+*/
+
+
+/*!
+ \class QBitArray qbitarray.h
+ \reentrant
+ \brief The QBitArray class provides an array of bits.
+
+ \ingroup collection
+ \ingroup tools
+ \ingroup shared
+
+ Because QBitArray is a QMemArray, it uses explicit \link
+ shclass.html sharing\endlink with a reference count.
+
+ A QBitArray is a special byte array that can access individual
+ bits and perform bit-operations (AND, OR, XOR and NOT) on entire
+ arrays or bits.
+
+ Bits can be manipulated by the setBit() and clearBit() functions,
+ but it is also possible to use the indexing [] operator to test
+ and set individual bits. The [] operator is a little slower than
+ setBit() and clearBit() because some tricks are required to
+ implement single-bit assignments.
+
+ Example:
+ \code
+ QBitArray a(3);
+ a.setBit( 0 );
+ a.clearBit( 1 );
+ a.setBit( 2 ); // a = [1 0 1]
+
+ QBitArray b(3);
+ b[0] = 1;
+ b[1] = 1;
+ b[2] = 0; // b = [1 1 0]
+
+ QBitArray c;
+ c = ~a & b; // c = [0 1 0]
+ \endcode
+
+ When a QBitArray is constructed the bits are uninitialized. Use
+ fill() to set all the bits to 0 or 1. The array can be resized
+ with resize() and copied with copy(). Bits can be set with
+ setBit() and cleared with clearBit(). Bits can be toggled with
+ toggleBit(). A bit's value can be obtained with testBit() and with
+ at().
+
+ QBitArray supports the \& (AND), | (OR), ^ (XOR) and ~ (NOT)
+ operators.
+*/
+
+/*! \class QBitArray::bitarr_data
+ \brief The QBitArray::bitarr_data class is internal.
+ \internal
+*/
+
+
+/*!
+ Constructs an empty bit array.
+*/
+
+QBitArray::QBitArray() : QByteArray( 0, 0 )
+{
+ bitarr_data *x = new bitarr_data;
+ Q_CHECK_PTR( x );
+ x->nbits = 0;
+ setSharedBlock( x );
+}
+
+/*!
+ Constructs a bit array of \a size bits. The bits are uninitialized.
+
+ \sa fill()
+*/
+
+QBitArray::QBitArray( uint size ) : QByteArray( 0, 0 )
+{
+ bitarr_data *x = new bitarr_data;
+ Q_CHECK_PTR( x );
+ x->nbits = 0;
+ setSharedBlock( x );
+ resize( size );
+}
+
+/*!
+ \fn QBitArray::QBitArray( const QBitArray &a )
+
+ Constructs a shallow copy of \a a.
+*/
+
+/*!
+ \fn QBitArray &QBitArray::operator=( const QBitArray &a )
+
+ Assigns a shallow copy of \a a to this bit array and returns a
+ reference to this array.
+*/
+
+
+/*!
+ Pad last byte with 0-bits.
+*/
+void QBitArray::pad0()
+{
+ uint sz = size();
+ if ( sz && sz%8 )
+ *(data()+sz/8) &= (1 << (sz%8)) - 1;
+}
+
+
+/*!
+ \fn uint QBitArray::size() const
+
+ Returns the bit array's size (number of bits).
+
+ \sa resize()
+*/
+
+/*!
+ Resizes the bit array to \a size bits and returns TRUE if the bit
+ array could be resized; otherwise returns FALSE.
+
+ If the array is expanded, the new bits are set to 0.
+
+ \sa size()
+*/
+
+bool QBitArray::resize( uint size )
+{
+ uint s = this->size();
+ if ( !QByteArray::resize( (size+7)/8 ) )
+ return FALSE; // cannot resize
+ SHBLOCK->nbits = size;
+ if ( size != 0 ) { // not null array
+ int ds = (int)(size+7)/8 - (int)(s+7)/8;// number of bytes difference
+ if ( ds > 0 ) // expanding array
+ memset( data() + (s+7)/8, 0, ds ); // reset new data
+ }
+ return TRUE;
+}
+
+
+/*!
+ Fills the bit array with \a v (1's if \a v is TRUE, or 0's if \a v
+ is FALSE).
+
+ fill() resizes the bit array to \a size bits if \a size is
+ nonnegative.
+
+ Returns FALSE if a nonnegative \e size was specified and the bit
+ array could not be resized; otherwise returns TRUE.
+
+ \sa resize()
+*/
+
+bool QBitArray::fill( bool v, int size )
+{
+ if ( size >= 0 ) { // resize first
+ if ( !resize( size ) )
+ return FALSE; // cannot resize
+ } else {
+ size = this->size();
+ }
+ if ( size > 0 )
+ memset( data(), v ? 0xff : 0, (size + 7) / 8 );
+ if ( v )
+ pad0();
+ return TRUE;
+}
+
+
+/*!
+ Detaches from shared bit array data and makes sure that this bit
+ array is the only one referring to the data.
+
+ If multiple bit arrays share common data, this bit array
+ dereferences the data and gets a copy of the data. Nothing happens
+ if there is only a single reference.
+
+ \sa copy()
+*/
+
+void QBitArray::detach()
+{
+ int nbits = SHBLOCK->nbits;
+ this->duplicate( *this );
+ SHBLOCK->nbits = nbits;
+}
+
+/*!
+ Returns a deep copy of the bit array.
+
+ \sa detach()
+*/
+
+QBitArray QBitArray::copy() const
+{
+ QBitArray tmp;
+ tmp.duplicate( *this );
+ ((bitarr_data*)(tmp.sharedBlock()))->nbits = SHBLOCK->nbits;
+ return tmp;
+}
+
+
+/*!
+ Returns TRUE if the bit at position \a index is set, i.e. is 1;
+ otherwise returns FALSE.
+
+ \sa setBit(), clearBit()
+*/
+
+bool QBitArray::testBit( uint index ) const
+{
+#if defined(QT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "QBitArray::testBit: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ return (*(data()+(index>>3)) & (1 << (index & 7))) != 0;
+}
+
+/*!
+ \overload
+
+ Sets the bit at position \a index to 1.
+
+ \sa clearBit() toggleBit()
+*/
+
+void QBitArray::setBit( uint index )
+{
+#if defined(QT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "QBitArray::setBit: Index %d out of range", index );
+ return;
+ }
+#endif
+ *(data()+(index>>3)) |= (1 << (index & 7));
+}
+
+/*!
+ \fn void QBitArray::setBit( uint index, bool value )
+
+ Sets the bit at position \a index to \a value.
+
+ Equivalent to:
+ \code
+ if ( value )
+ setBit( index );
+ else
+ clearBit( index );
+ \endcode
+
+ \sa clearBit() toggleBit()
+*/
+
+/*!
+ Clears the bit at position \a index, i.e. sets it to 0.
+
+ \sa setBit(), toggleBit()
+*/
+
+void QBitArray::clearBit( uint index )
+{
+#if defined(QT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "QBitArray::clearBit: Index %d out of range", index );
+ return;
+ }
+#endif
+ *(data()+(index>>3)) &= ~(1 << (index & 7));
+}
+
+/*!
+ Toggles the bit at position \a index.
+
+ If the previous value was 0, the new value will be 1. If the
+ previous value was 1, the new value will be 0.
+
+ \sa setBit(), clearBit()
+*/
+
+bool QBitArray::toggleBit( uint index )
+{
+#if defined(QT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "QBitArray::toggleBit: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ register uchar *p = (uchar *)data() + (index>>3);
+ uchar b = (1 << (index & 7)); // bit position
+ uchar c = *p & b; // read bit
+ *p ^= b; // toggle bit
+ return c;
+}
+
+
+/*!
+ \fn bool QBitArray::at( uint index ) const
+
+ Returns the value (0 or 1) of the bit at position \a index.
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn QBitVal QBitArray::operator[]( int index )
+
+ Implements the [] operator for bit arrays.
+
+ The returned QBitVal is a context object. It makes it possible to
+ get and set a single bit value by its \a index position.
+
+ Example:
+ \code
+ QBitArray a( 3 );
+ a[0] = 0;
+ a[1] = 1;
+ a[2] = a[0] ^ a[1];
+ \endcode
+
+ The functions testBit(), setBit() and clearBit() are faster.
+
+ \sa at()
+*/
+
+/*!
+ \overload bool QBitArray::operator[]( int index ) const
+
+ Implements the [] operator for constant bit arrays.
+*/
+
+
+/*!
+ Performs the AND operation between all bits in this bit array and
+ \a a. Returns a reference to this bit array.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+ \code
+ QBitArray a( 3 ), b( 2 );
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b[0] = 1; b[1] = 0; // b = [1 0]
+ a &= b; // a = [1 0 0]
+ \endcode
+
+ \sa operator|=(), operator^=(), operator~()
+*/
+
+QBitArray &QBitArray::operator&=( const QBitArray &a )
+{
+ resize( QMAX(size(), a.size()) );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = QMIN( QByteArray::size(), a.QByteArray::size() );
+ int p = QMAX( QByteArray::size(), a.QByteArray::size() ) - n;
+ while ( n-- > 0 )
+ *a1++ &= *a2++;
+ while ( p-- > 0 )
+ *a1++ = 0;
+ return *this;
+}
+
+/*!
+ Performs the OR operation between all bits in this bit array and
+ \a a. Returns a reference to this bit array.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+ \code
+ QBitArray a( 3 ), b( 2 );
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b[0] = 1; b[1] = 0; // b = [1 0]
+ a |= b; // a = [1 0 1]
+ \endcode
+
+ \sa operator&=(), operator^=(), operator~()
+*/
+
+QBitArray &QBitArray::operator|=( const QBitArray &a )
+{
+ resize( QMAX(size(), a.size()) );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = QMIN( QByteArray::size(), a.QByteArray::size() );
+ while ( n-- > 0 )
+ *a1++ |= *a2++;
+ return *this;
+}
+
+/*!
+ Performs the XOR operation between all bits in this bit array and
+ \a a. Returns a reference to this bit array.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+ \code
+ QBitArray a( 3 ), b( 2 );
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b[0] = 1; b[1] = 0; // b = [1 0]
+ a ^= b; // a = [0 0 1]
+ \endcode
+
+ \sa operator&=(), operator|=(), operator~()
+*/
+
+QBitArray &QBitArray::operator^=( const QBitArray &a )
+{
+ resize( QMAX(size(), a.size()) );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = QMIN( QByteArray::size(), a.QByteArray::size() );
+ while ( n-- > 0 )
+ *a1++ ^= *a2++;
+ return *this;
+}
+
+/*!
+ Returns a bit array that contains the inverted bits of this bit array.
+
+ Example:
+ \code
+ QBitArray a( 3 ), b;
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b = ~a; // b = [0 1 0]
+ \endcode
+*/
+
+QBitArray QBitArray::operator~() const
+{
+ QBitArray a( size() );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = QByteArray::size();
+ while ( n-- )
+ *a2++ = ~*a1++;
+ a.pad0();
+ return a;
+}
+
+
+/*!
+ \relates QBitArray
+
+ Returns the AND result between the bit arrays \a a1 and \a a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+
+ \sa QBitArray::operator&=()
+*/
+
+QBitArray operator&( const QBitArray &a1, const QBitArray &a2 )
+{
+ QBitArray tmp = a1.copy();
+ tmp &= a2;
+ return tmp;
+}
+
+/*!
+ \relates QBitArray
+
+ Returns the OR result between the bit arrays \a a1 and \a a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+
+ \sa QBitArray::operator|=()
+*/
+
+QBitArray operator|( const QBitArray &a1, const QBitArray &a2 )
+{
+ QBitArray tmp = a1.copy();
+ tmp |= a2;
+ return tmp;
+}
+
+/*!
+ \relates QBitArray
+
+ Returns the XOR result between the bit arrays \a a1 and \a a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+
+ \sa QBitArray::operator^()
+*/
+
+QBitArray operator^( const QBitArray &a1, const QBitArray &a2 )
+{
+ QBitArray tmp = a1.copy();
+ tmp ^= a2;
+ return tmp;
+}
+
+
+/* \enum QGArray::array_data
+
+ \warning This will be renamed in the next major release of Qt. Until
+ then it is undocumented and we recommend against its use.
+
+ \internal
+
+ ### 3.0 rename ###
+ ### 3.0 move it to QGArray? ###
+*/
+
+
+/*!
+ \fn QBitArray::array_data * QBitArray::newData()
+
+ \internal
+
+ Returns data specific to QBitArray that extends what QGArray provides.
+ QPtrCollection mechanism for allowing extra/different data.
+*/
+
+
+/*!
+ \fn void QBitArray::deleteData ( array_data * d )
+
+ \internal
+
+ Deletes data specific to QBitArray that extended what QGArray provided.
+
+ QPtrCollection mechanism for allowing extra/different data.
+*/
+
+
+/*****************************************************************************
+ QBitArray stream functions
+ *****************************************************************************/
+
+/*!
+ \relates QBitArray
+
+ Writes bit array \a a to stream \a s.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<( QDataStream &s, const QBitArray &a )
+{
+ Q_UINT32 len = a.size();
+ s << len; // write size of array
+ if ( len > 0 ) // write data
+ s.writeRawBytes( a.data(), a.QByteArray::size() );
+ return s;
+}
+
+/*!
+ \relates QBitArray
+
+ Reads a bit array into \a a from stream \a s.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QBitArray &a )
+{
+ Q_UINT32 len;
+ s >> len; // read size of array
+ if ( !a.resize( (uint)len ) ) { // resize array
+#if defined(QT_CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QBitArray" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // read data
+ s.readRawBytes( a.data(), a.QByteArray::size() );
+ return s;
+}
+
+#endif // QT_NO_DATASTREAM