📄 qgarray.cpp
字号:
Q_CHECK_PTR( shd ); } else { // delete after copy was made oldptr = shd->data; } if ( a.shd->len ) { // duplicate data shd->data = NEW(char,a.shd->len); Q_CHECK_PTR( shd->data ); if ( shd->data ) memcpy( shd->data, a.shd->data, a.shd->len ); } else { shd->data = 0; } shd->len =#ifdef QT_QGARRAY_SPEED_OPTIM shd->maxl =#endif a.shd->len; if ( oldptr ) DELETE(oldptr); return *this;}/*! \overload Deep copy. Dereferences the current array and obtains a copy of \a len characters from array data \a d instead. Returns a reference to this array. \sa assign(), operator=()*/QGArray &QGArray::duplicate( const char *d, uint len ){ char *data; if ( d == 0 || len == 0 ) { data = 0; len = 0; } else { if ( shd->count == 1 && shd->len == len ) { if ( shd->data != d ) // avoid self-assignment memcpy( shd->data, d, len ); // use same buffer return *this; } data = NEW(char,len); Q_CHECK_PTR( data ); memcpy( data, d, len ); } if ( shd->count > 1 ) { // detach shd->count--; shd = newData(); Q_CHECK_PTR( shd ); } else { // just a single reference if ( shd->data ) DELETE(shd->data); } shd->data = data; shd->len =#ifdef QT_QGARRAY_SPEED_OPTIM shd->maxl =#endif len; return *this;}/*! Resizes this array to \a len bytes and copies the \a len bytes at address \a d into it. \warning This function disregards the reference count mechanism. If other QGArrays reference the same data as this, all will be updated.*/void QGArray::store( const char *d, uint len ){ // store, but not deref resize( len ); memcpy( shd->data, d, len );}/*! \fn array_data *QGArray::sharedBlock() const Returns a pointer to the shared array block. \warning Do not use this function. Using it is begging for trouble. We dare not remove it, for fear of breaking code, but we \e strongly discourage new use of it.*//*! \fn void QGArray::setSharedBlock( array_data *p ) Sets the shared array block to \a p. \warning Do not use this function. Using it is begging for trouble. We dare not remove it, for fear of breaking code, but we \e strongly discourage new use of it.*//*! Sets raw data and returns a reference to the array. Dereferences the current array and sets the new array data to \a d and the new array size to \a len. Do not attempt to resize or re-assign the array data when raw data has been set. Call resetRawData(d,len) to reset the array. Setting raw data is useful because it sets QMemArray data without allocating memory or copying data. Example of intended use: \code static uchar bindata[] = { 231, 1, 44, ... }; QByteArray a; a.setRawData( bindata, sizeof(bindata) ); // a points to bindata QDataStream s( a, IO_ReadOnly ); // open on a's data s >> <something>; // read raw bindata s.close(); a.resetRawData( bindata, sizeof(bindata) ); // finished \endcode Example of misuse (do not do this): \code static uchar bindata[] = { 231, 1, 44, ... }; QByteArray a, b; a.setRawData( bindata, sizeof(bindata) ); // a points to bindata a.resize( 8 ); // will crash b = a; // will crash a[2] = 123; // might crash // forget to resetRawData - will crash \endcode \warning If you do not call resetRawData(), QGArray will attempt to deallocate or reallocate the raw data, which might not be too good. Be careful.*/QGArray &QGArray::setRawData( const char *d, uint len ){ duplicate( 0, 0 ); // set null data shd->data = (char *)d; shd->len = len; return *this;}/*! Resets raw data. The arguments must be the data, \a d, and length \a len, that were passed to setRawData(). This is for consistency checking.*/void QGArray::resetRawData( const char *d, uint len ){ if ( d != shd->data || len != shd->len ) {#if defined(QT_CHECK_STATE) qWarning( "QGArray::resetRawData: Inconsistent arguments" );#endif return; } shd->data = 0; shd->len = 0;}/*! Finds the first occurrence of \a d in the array from position \a index, where \a sz is the size of the \a d element. Note that \a index is given in units of \a sz, not bytes. This function only compares whole cells, not bytes.*/int QGArray::find( const char *d, uint index, uint sz ) const{ index *= sz; if ( index >= shd->len ) {#if defined(QT_CHECK_RANGE) qWarning( "QGArray::find: Index %d out of range", index/sz );#endif return -1; } register uint i; uint ii; switch ( sz ) { case 1: { // 8 bit elements register char *x = data() + index; char v = *d; for ( i=index; i<shd->len; i++ ) { if ( *x++ == v ) break; } ii = i; } break; case 2: { // 16 bit elements register Q_INT16 *x = (Q_INT16*)(data() + index); Q_INT16 v = *((Q_INT16*)d); for ( i=index; i<shd->len; i+=2 ) { if ( *x++ == v ) break; } ii = i/2; } break; case 4: { // 32 bit elements register Q_INT32 *x = (Q_INT32*)(data() + index); Q_INT32 v = *((Q_INT32*)d); for ( i=index; i<shd->len; i+=4 ) { if ( *x++ == v ) break; } ii = i/4; } break; default: { // any size elements for ( i=index; i<shd->len; i+=sz ) { if ( memcmp( d, &shd->data[i], sz ) == 0 ) break; } ii = i/sz; } break; } return i<shd->len ? (int)ii : -1;}/*! Returns the number of occurrences of \a d in the array, where \a sz is the size of the \a d element. This function only compares whole cells, not bytes.*/int QGArray::contains( const char *d, uint sz ) const{ register uint i = shd->len; int count = 0; switch ( sz ) { case 1: { // 8 bit elements register char *x = data(); char v = *d; while ( i-- ) { if ( *x++ == v ) count++; } } break; case 2: { // 16 bit elements register Q_INT16 *x = (Q_INT16*)data(); Q_INT16 v = *((Q_INT16*)d); i /= 2; while ( i-- ) { if ( *x++ == v ) count++; } } break; case 4: { // 32 bit elements register Q_INT32 *x = (Q_INT32*)data(); Q_INT32 v = *((Q_INT32*)d); i /= 4; while ( i-- ) { if ( *x++ == v ) count++; } } break; default: { // any size elements for ( i=0; i<shd->len; i+=sz ) { if ( memcmp(d, &shd->data[i], sz) == 0 ) count++; } } break; } return count;}static int cmp_item_size = 0;#if defined(Q_C_CALLBACKS)extern "C" {#endif#ifdef Q_OS_TEMPstatic int __cdecl cmp_arr( const void *n1, const void *n2 )#elsestatic int cmp_arr( const void *n1, const void *n2 )#endif{ return ( n1 && n2 ) ? memcmp( n1, n2, cmp_item_size ) : ( n1 ? 1 : ( n2 ? -1 : 0 ) ); // ### Qt 3.0: Add a virtual compareItems() method and call that instead}#if defined(Q_C_CALLBACKS)}#endif/*! Sorts the first \a sz items of the array.*/void QGArray::sort( uint sz ){ int numItems = size() / sz; if ( numItems < 2 ) return;#ifdef QT_THREAD_SUPPORT QMutexLocker locker( qt_global_mutexpool ? qt_global_mutexpool->get( &cmp_item_size ) : 0 );#endif // QT_THREAD_SUPPORT cmp_item_size = sz; qsort( shd->data, numItems, sz, cmp_arr );}/*! Binary search; assumes that \a d is a sorted array of size \a sz.*/int QGArray::bsearch( const char *d, uint sz ) const{ int numItems = size() / sz; if ( !numItems ) return -1;#ifdef QT_THREAD_SUPPORT QMutexLocker locker( qt_global_mutexpool ? qt_global_mutexpool->get( &cmp_item_size ) : 0 );#endif // QT_THREAD_SUPPORT cmp_item_size = sz; char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr ); if ( !r ) return -1; while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) ) r -= sz; // search to first of equal elements; bsearch is undef return (int)(( r - shd->data ) / sz);}/*! \fn char *QGArray::at( uint index ) const Returns a pointer to the byte at offset \a index in the array.*//*! Expand the array if necessary, and copies (the first part of) its contents from the \a index * \a sz bytes at \a d. Returns TRUE if the operation succeeds, FALSE if it runs out of memory. \warning This function disregards the reference count mechanism. If other QGArrays reference the same data as this, all will be changed.*/bool QGArray::setExpand( uint index, const char *d, uint sz ){ index *= sz; if ( index >= shd->len ) { if ( !resize( index+sz ) ) // no memory return FALSE; } memcpy( data() + index, d, sz ); return TRUE;}/*! Prints a warning message if at() or [] is given a bad index.*/void QGArray::msg_index( uint index ){#if defined(QT_CHECK_RANGE) qWarning( "QGArray::at: Absolute index %d out of range", index );#else Q_UNUSED( index )#endif}/*! Returns a new shared array block.*/QGArray::array_data * QGArray::newData(){ return new array_data;}/*! Deletes the shared array block \a p.*/void QGArray::deleteData( array_data *p ){ delete p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -