📄 qgarray.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** 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 "qglobal.h"#if defined(Q_CC_BOR) // needed for qsort() because of a std namespace problem on Borland# include "qplatformdefs.h"#elif defined(Q_WS_WIN) // needed for bsearch on some platforms# include "qt_windows.h"#endif#define QGARRAY_CPP#include "qgarray.h"#include <stdlib.h>#include <string.h>#ifdef QT_THREAD_SUPPORT# include <private/qmutexpool_p.h>#endif // QT_THREAD_SUPPORT/* If USE_MALLOC isn't defined, we use new[] and delete[] to allocate memory. The documentation for QMemArray<T>::assign() explicitly mentions that the array is freed using free(), so don't mess around with USE_MALLOC unless you know what you're doing.*/#define USE_MALLOC#undef NEW#undef DELETE#if defined(USE_MALLOC)#define NEW(type,size) ((type*)malloc(size*sizeof(type)))#define DELETE(array) (free((char*)array))#else#define NEW(type,size) (new type[size])#define DELETE(array) (delete[] array)#define DONT_USE_REALLOC // comment to use realloc()#endif/*! \class QShared qshared.h \reentrant \ingroup shared \brief The QShared class is used internally for implementing shared classes. \internal It only contains a reference count and member functions to increment and decrement it. Shared classes normally have internal classes that inherit QShared and add the shared data. \sa \link shclass.html Shared Classes\endlink*//*! \class QGArray qgarray.h \reentrant \ingroup shared \ingroup collection \brief The QGArray class is an internal class for implementing the QMemArray class. \internal QGArray is a strictly internal class that acts as base class for the QMemArray template array. It contains an array of bytes and has no notion of an array element.*//*! Constructs a null array.*/QGArray::QGArray(){ shd = newData(); Q_CHECK_PTR( shd );}/*! Dummy constructor; does not allocate any data. This constructor does not initialize any array data so subclasses must do it. The intention is to make the code more efficient.*/QGArray::QGArray( int, int ){}/*! Constructs an array with room for \a size bytes.*/QGArray::QGArray( int size ){ if ( size < 0 ) {#if defined(QT_CHECK_RANGE) qWarning( "QGArray: Cannot allocate array with negative length" );#endif size = 0; } shd = newData(); Q_CHECK_PTR( shd ); if ( size == 0 ) // zero length return; shd->data = NEW(char,size); Q_CHECK_PTR( shd->data ); shd->len =#ifdef QT_QGARRAY_SPEED_OPTIM shd->maxl =#endif size;}/*! Constructs a shallow copy of \a a.*/QGArray::QGArray( const QGArray &a ){ shd = a.shd; shd->ref();}/*! Dereferences the array data and deletes it if this was the last reference.*/QGArray::~QGArray(){ if ( shd && shd->deref() ) { // delete when last reference if ( shd->data ) // is lost DELETE(shd->data); deleteData( shd ); shd = 0; }}/*! \fn QGArray &QGArray::operator=( const QGArray &a ) Assigns a shallow copy of \a a to this array and returns a reference to this array. Equivalent to assign().*//*! \fn void QGArray::detach() Detaches this array from shared array data.*//*! \fn char *QGArray::data() const Returns a pointer to the actual array data.*//*! \fn uint QGArray::nrefs() const Returns the reference count.*//*! \fn uint QGArray::size() const Returns the size of the array, in bytes.*//*! Returns TRUE if this array is equal to \a a, otherwise FALSE. The comparison is bitwise, of course.*/bool QGArray::isEqual( const QGArray &a ) const{ if ( size() != a.size() ) // different size return FALSE; if ( data() == a.data() ) // has same data return TRUE; return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;}/*! Resizes the array to \a newsize bytes. \a optim is either MemOptim (the default) or SpeedOptim.*/bool QGArray::resize( uint newsize, Optimization optim ){#ifndef QT_QGARRAY_SPEED_OPTIM Q_UNUSED(optim);#endif if ( newsize == shd->len#ifdef QT_QGARRAY_SPEED_OPTIM && newsize == shd->maxl#endif ) // nothing to do return TRUE; if ( newsize == 0 ) { // remove array if ( shd->data ) DELETE(shd->data); shd->data = 0; shd->len = 0;#ifdef QT_QGARRAY_SPEED_OPTIM shd->maxl = 0;#endif return TRUE; } uint newmaxl = newsize;#ifdef QT_QGARRAY_SPEED_OPTIM if ( optim == SpeedOptim ) { if ( newsize <= shd->maxl && ( newsize * 4 > shd->maxl || shd->maxl <= 4 ) ) { shd->len = newsize; return TRUE; } newmaxl = 4; while ( newmaxl < newsize ) newmaxl *= 2; // try to spare some memory if ( newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2) ) newmaxl -= newmaxl >> 2; } shd->maxl = newmaxl;#endif if ( shd->data ) { // existing data#if defined(DONT_USE_REALLOC) char *newdata = NEW(char,newsize); // manual realloc memcpy( newdata, shd->data, QMIN(shd->len,newmaxl) ); DELETE(shd->data); shd->data = newdata;#else shd->data = (char *)realloc( shd->data, newmaxl );#endif } else { shd->data = NEW(char,newmaxl); } if ( !shd->data ) // no memory return FALSE; shd->len = newsize; return TRUE;}/*!\overload*/bool QGArray::resize( uint newsize ){ return resize( newsize, MemOptim );}/*! Fills the array with the repeated occurrences of \a d, which is \a sz bytes long. If \a len is specified as different from -1, then the array will be resized to \a len*sz before it is filled. Returns TRUE if successful, or FALSE if the memory cannot be allocated (only when \a len != -1). \sa resize()*/bool QGArray::fill( const char *d, int len, uint sz ){ if ( len < 0 ) len = shd->len/sz; // default: use array length else if ( !resize( len*sz ) ) return FALSE; if ( sz == 1 ) // 8 bit elements memset( data(), *d, len ); else if ( sz == 4 ) { // 32 bit elements register Q_INT32 *x = (Q_INT32*)data(); Q_INT32 v = *((Q_INT32*)d); while ( len-- ) *x++ = v; } else if ( sz == 2 ) { // 16 bit elements register Q_INT16 *x = (Q_INT16*)data(); Q_INT16 v = *((Q_INT16*)d); while ( len-- ) *x++ = v; } else { // any other size elements register char *x = data(); while ( len-- ) { // more complicated memcpy( x, d, sz ); x += sz; } } return TRUE;}/*! \overload Shallow copy. Dereference the current array and references the data contained in \a a instead. Returns a reference to this array. \sa operator=()*/QGArray &QGArray::assign( const QGArray &a ){ a.shd->ref(); // avoid 'a = a' if ( shd->deref() ) { // delete when last reference if ( shd->data ) // is lost DELETE(shd->data); deleteData( shd ); } shd = a.shd; return *this;}/*! Shallow copy. Dereference the current array and references the array data \a d, which contains \a len bytes. Returns a reference to this array. Do not delete \a d later, because QGArray takes care of that.*/QGArray &QGArray::assign( const char *d, uint len ){ if ( shd->count > 1 ) { // disconnect this shd->count--; shd = newData(); Q_CHECK_PTR( shd ); } else { if ( shd->data ) DELETE(shd->data); } shd->data = (char *)d; shd->len =#ifdef QT_QGARRAY_SPEED_OPTIM shd->maxl =#endif len; return *this;}/*! Deep copy. Dereference the current array and obtains a copy of the data contained in \a a instead. Returns a reference to this array. \sa assign(), operator=()*/QGArray &QGArray::duplicate( const QGArray &a ){ if ( a.shd == shd ) { // a.duplicate(a) ! if ( shd->count > 1 ) { shd->count--; register array_data *n = newData(); Q_CHECK_PTR( n ); if ( (n->len=shd->len) ) { n->data = NEW(char,n->len); Q_CHECK_PTR( n->data ); if ( n->data ) memcpy( n->data, shd->data, n->len ); } else { n->data = 0; } shd = n; } return *this; } char *oldptr = 0; if ( shd->count > 1 ) { // disconnect this shd->count--; shd = newData();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -