summaryrefslogtreecommitdiffstats
path: root/generic/tclOOBasic.c
Commit message (Expand)AuthorAgeFilesLines
* explicitly ignore Tcl_PushCallFrame and TclPushStackFrame return value - it i...Miguel Sofer2015-08-011-5/+1
* added compilation for [nextto]dkf2014-01-191-4/+16
* make function static once more; not needed outside of source filedkf2014-01-071-12/+9
* merge main working branchdkf2013-12-301-34/+37
|\
| * Bump TclOO version to 1.0.1dkf2013-09-181-1/+1
| * Don't allocate memory until you know you're going to use it and arrange fordgp2013-08-211-1/+2
| * Don't use automatic storage to hold the invocation words of oo::define.dgp2013-08-211-5/+8
| * Apply a fix for the bug. Passes the test suite now.bug_3603695dkf2013-02-091-28/+27
* | Working towards a BCCed [next].dkf2012-11-011-7/+5
|/
* merge trunkdgp2012-08-081-40/+60
|\
| * converting to using Tcl_Obj API for error message generation; part donedkf2012-08-031-40/+60
* | Update TclOO package to 0.7, correct copyright dates.dkf2012-07-121-1/+1
|/
* Factor out a number of common patterns of use of Tcl_DStringAppend.dkf2012-07-031-1/+1
* * generic/tclOOBasic.c (TclOO_Class_Constructor): [Bug 2023112]: Cutdkf2012-05-201-68/+70
* Implementation of TIP #380dkf2012-03-261-1/+8
* Implementation of TIP #381: Call Chain Introspection and Controldkf2011-05-251-11/+109
* More generation of error codes (TclOO miscellany).dkf2011-04-041-0/+3
* Adjust ckalloc/ckfree macros to greatly reduce number of explicit casts indkf2011-03-121-1/+1
* Reorganization of call context reference count management so that codedkf2011-03-011-12/+7
* NRE-enabled destructors! Also more generation of errorcodes.dkf2010-02-051-17/+49
* [Bug 2944404] Be careful in case an object deletes itself in its destructor.dkf2010-02-021-3/+6
* Make things compile... D'oh!dkf2010-01-281-3/+5
* Improvements to destructor handling.dkf2010-01-281-2/+16
* [Bug 2903811]: Remove unneeded restrictions on usefully calling thedkf2009-11-271-8/+6
* Let [$obj varname x(y)] work. [Bug 2883857]dkf2009-10-221-2/+25
* Fix [Bug 2704302]dkf2009-03-241-14/+5
* - eliminate some unnessary type castsnijtmans2009-02-101-2/+2
* TIP #336 IMPLEMENTATIONdgp2008-12-021-4/+4
* remove unused variabledkf2008-11-011-2/+1
* Fix [Bug 2200824] and make class constructor error handling much more robust.dkf2008-10-311-1/+70
* Add "const" to many internalnijtmans2008-10-161-2/+2
* Clean up result handling, factor out some duplicated code, share objects.dkf2008-10-041-30/+25
* TIP #323 IMPLEMENTATION (partial)dgp2008-09-261-3/+3
* * generic/tclCmdAH.c: nre-enabling [eval]; eval scripts are nowMiguel Sofer2008-09-011-5/+3
* Dumped tclNRE.h's contents into tclInt.h. The file is now empty andMiguel Sofer2008-07-311-4/+3
* Completely revamped NRE implementation, with (almost) unchanged API.Miguel Sofer2008-07-291-5/+2
* new TclNRAddCallback macro for internal use instead of the publicMiguel Sofer2008-07-181-5/+5
* NRE-enable the TclOO constructor system.dkf2008-07-181-25/+58
* * generic/tcl.decls: Change the public api prefix fromMiguel Sofer2008-07-181-3/+3
* NRE-enable oo::object.evaldkf2008-07-181-13/+28
* Tinkeringdkf2008-07-171-29/+37
* NRE-aware TclOO.dkf2008-07-161-4/+17
* Implementation of TIP #257. Incomplete due to missing Win build support.dkf2008-05-311-0/+925
->len ); } else { shd->data = 0; } shd->len = a.shd->len; if ( oldptr ) DELETE(oldptr); return *this; } /*! \internal Deep copy. Dereferences the current array and obtains a copy of the array data \e 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 ) { memcpy( shd->data, d, len ); // use same buffer return *this; } data = NEW(char,len); CHECK_PTR( data ); memcpy( data, d, len ); } if ( shd->count > 1 ) { // detach shd->count--; shd = newData(); CHECK_PTR( shd ); } else { // just a single reference if ( shd->data ) DELETE(shd->data); } shd->data = data; shd->len = len; return *this; } /*! \internal Resizes this array to \e len bytes and copies the \e len bytes at address \e 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 \internal 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 ) \internal Sets the shared array block to \e 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. */ /*! \internal Sets raw data and returns a reference to the array. Dereferences the current array and sets the new array data to \e d and the new array size to \e 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 set QArray 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; } /*! \internal Resets raw data. The arguments must be the data and length 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(CHECK_STATE) qWarning( "QGArray::resetRawData: Inconsistent arguments" ); #endif return; } shd->data = 0; shd->len = 0; } /*! \internal Finds the first occurrence of \e d in the array from position \e index, where \e sz is the size of the \e d element. Note that \e index is given in units of \e 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(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; } /*! \internal Returns the number of occurrences of \e d in the array, where \e sz is the size of the \e 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 static int cmp_arr( const void *n1, const void *n2 ) { return ( n1 && n2 ) ? memcmp( n1, n2, cmp_item_size ) : (int)((intptr_t)n1 - (intptr_t)n2); // Qt 3.0: Add a virtual compareItems() method and call that instead } #if defined(Q_C_CALLBACKS) } #endif /*! \internal Sort the array. */ void QGArray::sort( uint sz ) { int numItems = size() / sz; if ( numItems < 2 ) return; cmp_item_size = sz; qsort( shd->data, numItems, sz, cmp_arr ); } /*! \internal Binary search; assumes sorted array */ int QGArray::bsearch( const char *d, uint sz ) const { int numItems = size() / sz; if ( !numItems ) return -1; 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 \internal Returns a pointer to the byte at offset \e index in the array. */ /*! \internal Expand the array if necessary, and copies (the first part of) its contents from the \e index*zx bytes at \e 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; } /*! \internal Prints a warning message if at() or [] is given a bad index. */ void QGArray::msg_index( uint index ) { #if defined(CHECK_RANGE) qWarning( "QGArray::at: Absolute index %d out of range", index ); #else Q_UNUSED( index ) #endif } /*! \internal Returns a new shared array block. */ QGArray::array_data * QGArray::newData() { return new array_data; } /*! \internal Deletes the shared array block. */ void QGArray::deleteData( array_data *p ) { delete p; p = 0; }