filters
aielement.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "aielement.h"
00021 #include <qglobal.h>
00022
00023 AIElement::Private::Private()
00024 {
00025 typ = AIElement::Invalid;
00026 }
00027
00028 AIElement::Private::Private( Private* d )
00029 {
00030 switch( d->typ )
00031 {
00032 case AIElement::Invalid:
00033 break;
00034 case AIElement::String:
00035 case AIElement::Reference:
00036 case AIElement::Operator:
00037 value.ptr = new QString( *((QString*)d->value.ptr) );
00038 break;
00039 case AIElement::CString:
00040
00041 value.ptr = new QCString( *((QCString*)d->value.ptr) );
00042 break;
00043
00044
00045
00046 case AIElement::ElementArray:
00047 value.ptr = new QValueVector<AIElement>( *((QValueVector<AIElement>*)d->value.ptr) );
00048 break;
00049 case AIElement::Block:
00050 value.ptr = new QValueVector<AIElement>( *((QValueVector<AIElement>*)d->value.ptr) );
00051 break;
00052 case AIElement::ByteArray:
00053 value.ptr = new QByteArray( *((QByteArray*)d->value.ptr) );
00054 break;
00055 case AIElement::Int:
00056 value.i = d->value.i;
00057 break;
00058 case AIElement::UInt:
00059 value.u = d->value.u;
00060 break;
00061 case AIElement::Double:
00062 value.d = d->value.d;
00063 break;
00064 case AIElement::Byte:
00065 value.b = d->value.b;
00066 break;
00067 default:
00068 Q_ASSERT( 0 );
00069 }
00070
00071 typ = d->typ;
00072 }
00073
00074 AIElement::Private::~Private()
00075 {
00076 clear();
00077 }
00078
00079 void AIElement::Private::clear()
00080 {
00081 switch( typ )
00082 {
00083 case AIElement::String:
00084 case AIElement::Operator:
00085 case AIElement::Reference:
00086 delete (QString*)value.ptr;
00087 break;
00088 case AIElement::CString:
00089 delete (QCString*)value.ptr;
00090 break;
00091
00092
00093
00094 case AIElement::ElementArray:
00095 delete (QValueVector<AIElement>*)value.ptr;
00096 break;
00097 case AIElement::Block:
00098 delete (QValueVector<AIElement>*)value.ptr;
00099 break;
00100 case AIElement::ByteArray:
00101 delete (QByteArray*)value.ptr;
00102 break;
00103 case AIElement::Invalid:
00104 case AIElement::Int:
00105 case AIElement::UInt:
00106 case AIElement::Double:
00107 case AIElement::Byte:
00108 break;
00109 }
00110
00111 typ = AIElement::Invalid;
00112 }
00113
00117 AIElement::AIElement()
00118 {
00119 d = new Private;
00120 }
00121
00130 AIElement::~AIElement()
00131 {
00132 if ( d->deref() )
00133 delete d;
00134 }
00135
00141 AIElement::AIElement( const AIElement& p )
00142 {
00143 d = new Private;
00144 *this = p;
00145 }
00146
00150 AIElement::AIElement( const QString& val, Type type )
00151 {
00152 d = new Private;
00153 d->typ = type;
00154 d->value.ptr = new QString( val );
00155 }
00156
00164 AIElement::AIElement( const QCString& val )
00165 {
00166 d = new Private;
00167 d->typ = CString;
00168 d->value.ptr = new QCString( val );
00169 }
00170
00177 AIElement::AIElement( const char* val )
00178 {
00179 d = new Private;
00180 if ( val == 0 )
00181 return;
00182 d->typ = CString;
00183 d->value.ptr = new QCString( val );
00184 }
00185
00189 AIElement::AIElement( int val )
00190 {
00191 d = new Private;
00192 d->typ = Int;
00193 d->value.i = val;
00194 }
00195
00199 AIElement::AIElement( uint val )
00200 {
00201 d = new Private;
00202 d->typ = UInt;
00203 d->value.u = val;
00204 }
00205
00209 AIElement::AIElement( uchar val )
00210 {
00211 d = new Private;
00212 d->typ = Byte;
00213 d->value.b = val;
00214 }
00215
00216
00220 AIElement::AIElement( double val )
00221 {
00222 d = new Private;
00223 d->typ = Double;
00224 d->value.d = val;
00225 }
00226
00230
00231
00232
00233
00234
00235
00236
00237 AIElement::AIElement( const QValueVector<AIElement>& val, Type type )
00238 {
00239 d = new Private;
00240 d->typ = type;
00241 d->value.ptr = new QValueVector<AIElement>( val );
00242 }
00243
00244 AIElement::AIElement( const QByteArray& val )
00245 {
00246 d = new Private;
00247 d->typ = ByteArray;
00248 d->value.ptr = new QByteArray( val );
00249 }
00250
00258 AIElement& AIElement::operator= ( const AIElement& aielement )
00259 {
00260 AIElement& other = (AIElement&)aielement;
00261
00262 other.d->ref();
00263 if ( d->deref() )
00264 delete d;
00265
00266 d = other.d;
00267
00268 return *this;
00269 }
00270
00274 void AIElement::detach()
00275 {
00276 if ( d->count == 1 )
00277 return;
00278
00279 d->deref();
00280 d = new Private( d );
00281 }
00282
00289 const char* AIElement::typeName() const
00290 {
00291 return typeToName( d->typ );
00292 }
00293
00297 void AIElement::clear()
00298 {
00299 if ( d->count > 1 )
00300 {
00301 d->deref();
00302 d = new Private;
00303 return;
00304 }
00305
00306 d->clear();
00307 }
00308
00309 static const int ntypes = 11;
00310 static const char* const type_map[ntypes] =
00311 {
00312 0,
00313
00314 "QString",
00315 "int",
00316 "uint",
00317 "double",
00318 "QCString",
00319 "Operator",
00320 "Reference",
00321 "QValueVector<AIElement>",
00322 "QByteArray",
00323 "uchar",
00324 };
00325
00330 const char* AIElement::typeToName( Type typ )
00331 {
00332 if ( typ >= ntypes )
00333 return 0;
00334 return type_map[typ];
00335 }
00336
00344 AIElement::Type AIElement::nameToType( const char* name )
00345 {
00346 for ( int i = 0; i < ntypes; i++ ) {
00347 if ( !qstrcmp( type_map[i], name ) )
00348 return (Type) i;
00349 }
00350 return Invalid;
00351 }
00352
00360 const QString AIElement::toString() const
00361 {
00362 if ( d->typ == CString )
00363 return QString::fromLatin1( toCString() );
00364 if ( d->typ == Int )
00365 return QString::number( toInt() );
00366 if ( d->typ == UInt )
00367 return QString::number( toUInt() );
00368 if ( d->typ == Double )
00369 return QString::number( toDouble() );
00370 if ( d->typ == Byte )
00371 return QString::number( toByte() );
00372 if ( d->typ != String )
00373 return QString::null;
00374 return *((QString*)d->value.ptr);
00375 }
00376
00377 const QString AIElement::toReference() const
00378 {
00379 if ( d->typ != Reference )
00380 return QString::null;
00381 return *((QString*)d->value.ptr);
00382 }
00383
00384 const QString AIElement::toOperator() const
00385 {
00386 if ( d->typ != Operator )
00387 return QString::null;
00388 return *((QString*)d->value.ptr);
00389 }
00390
00397 const QCString AIElement::toCString() const
00398 {
00399 if ( d->typ == CString )
00400 return *((QCString*)d->value.ptr);
00401 if ( d->typ == String )
00402 return ((QString*)d->value.ptr)->latin1();
00403 if ( d->typ == Operator )
00404 return ((QString*)d->value.ptr)->latin1();
00405 if ( d->typ == Reference )
00406 return ((QString*)d->value.ptr)->latin1();
00407
00408 return 0;
00409 }
00410
00411
00421 int AIElement::toInt( bool * ok ) const
00422 {
00423 if( d->typ == String )
00424 return ((QString*)d->value.ptr)->toInt( ok );
00425 if ( d->typ == CString )
00426 return ((QCString*)d->value.ptr)->toInt( ok );
00427 if ( ok )
00428 *ok = canCast( UInt );
00429 if( d->typ == Int )
00430 return d->value.i;
00431 if( d->typ == UInt )
00432 return (int)d->value.u;
00433 if( d->typ == Byte )
00434 return (int)d->value.b;
00435 if ( d->typ == Double )
00436 return (int)d->value.d;
00437 return 0;
00438 }
00439
00440 uchar AIElement::toByte( bool * ok ) const
00441 {
00442 if( d->typ == String )
00443 return ((QString*)d->value.ptr)->toShort( ok );
00444 if ( d->typ == CString )
00445 return ((QCString*)d->value.ptr)->toShort( ok );
00446 if ( ok )
00447 *ok = canCast( UInt );
00448 if( d->typ == Byte )
00449 return d->value.b;
00450 if( d->typ == Int )
00451 return (uchar)d->value.i;
00452 if( d->typ == UInt )
00453 return (uchar)d->value.u;
00454 if ( d->typ == Double )
00455 return (uchar)d->value.d;
00456 return 0;
00457 }
00458
00459
00469 uint AIElement::toUInt( bool * ok ) const
00470 {
00471 if( d->typ == String )
00472 return ((QString*)d->value.ptr)->toUInt( ok );
00473 if ( d->typ == CString )
00474 return ((QCString*)d->value.ptr)->toUInt( ok );
00475 if ( ok )
00476 *ok = canCast( UInt );
00477 if( d->typ == Int )
00478 return d->value.i;
00479 if( d->typ == UInt )
00480 return (int)d->value.u;
00481 if( d->typ == Byte )
00482 return (int)d->value.b;
00483 if ( d->typ == Double )
00484 return (int)d->value.d;
00485
00486 return 0;
00487 }
00488
00498 double AIElement::toDouble( bool * ok ) const
00499 {
00500 if( d->typ == String )
00501 return ((QString*)d->value.ptr)->toDouble( ok );
00502 if ( d->typ == CString )
00503 return ((QCString*)d->value.ptr)->toDouble( ok );
00504 if ( ok )
00505 *ok = canCast( Double );
00506 if ( d->typ == Double )
00507 return d->value.d;
00508 if ( d->typ == Int )
00509 return (double)d->value.i;
00510 if ( d->typ == UInt )
00511 return (double)d->value.u;
00512 if ( d->typ == Byte )
00513 return (double)d->value.b;
00514 return 0.0;
00515 }
00516
00534
00535
00536
00537
00538
00539
00540
00541 const QValueVector<AIElement> AIElement::toElementArray() const
00542 {
00543 if ( d->typ == ElementArray )
00544 return *((QValueVector<AIElement>*)d->value.ptr);
00545 return QValueVector<AIElement>();
00546 }
00547
00548 const QValueVector<AIElement> AIElement::toBlock() const
00549 {
00550 if ( d->typ == Block )
00551 return *((QValueVector<AIElement>*)d->value.ptr);
00552 return QValueVector<AIElement>();
00553 }
00554
00555
00556 const QByteArray AIElement::toByteArray() const
00557 {
00558 if ( d->typ == ByteArray )
00559 return *((QByteArray*)d->value.ptr);
00560 return QByteArray();
00561 }
00562
00563 #define Q_VARIANT_AS( f ) Q##f& AIElement::as##f() { \
00564 if ( d->typ != f ) *this = AIElement( to##f() ); else detach(); return *((Q##f*)d->value.ptr);}
00565
00566 Q_VARIANT_AS(String)
00567 Q_VARIANT_AS(CString)
00568
00572 int& AIElement::asInt()
00573 {
00574 detach();
00575 if ( d->typ != Int ) {
00576 int i = toInt();
00577 d->clear();
00578 d->value.i = i;
00579 d->typ = Int;
00580 }
00581 return d->value.i;
00582 }
00583
00587 uint& AIElement::asUInt()
00588 {
00589 detach();
00590 if ( d->typ != UInt ) {
00591 uint u = toUInt();
00592 d->clear();
00593 d->value.u = u;
00594 d->typ = UInt;
00595 }
00596 return d->value.u;
00597 }
00598
00602 double& AIElement::asDouble()
00603 {
00604 if ( d->typ != Double ) {
00605 double dbl = toDouble();
00606 d->clear();
00607 d->value.d = dbl;
00608 d->typ = Double;
00609 }
00610 return d->value.d;
00611 }
00612
00616 uchar& AIElement::asByte()
00617 {
00618 detach();
00619 if ( d->typ != Byte ) {
00620 uchar b = toByte();
00621 d->clear();
00622 d->value.b = b;
00623 d->typ = Byte;
00624 }
00625 return d->value.b;
00626 }
00627
00628
00643
00644
00645
00646
00647
00648
00649
00650 QValueVector<AIElement>& AIElement::asElementArray()
00651 {
00652 if ( d->typ != ElementArray )
00653 *this = AIElement( toElementArray() );
00654 return *((QValueVector<AIElement>*)d->value.ptr);
00655 }
00656
00657 QValueVector<AIElement>& AIElement::asBlock()
00658 {
00659 if ( d->typ != Block )
00660 *this = AIElement( toBlock() );
00661 return *((QValueVector<AIElement>*)d->value.ptr);
00662 }
00663
00664
00665 QByteArray& AIElement::asByteArray()
00666 {
00667 if ( d->typ != ByteArray )
00668 *this = AIElement( toByteArray() );
00669 return *((QByteArray*)d->value.ptr);
00670 }
00671
00686 bool AIElement::canCast( Type t ) const
00687 {
00688 if ( d->typ == t )
00689 return TRUE;
00690 if ( t == Int && ( d->typ == String || d->typ == Double || d->typ == UInt || d->typ == Byte) )
00691 return TRUE;
00692 if ( t == UInt && ( d->typ == String || d->typ == Double || d->typ == Int || d->typ == Byte) )
00693 return TRUE;
00694 if ( t == Double && ( d->typ == String || d->typ == Int || d->typ == UInt || d->typ == Byte) )
00695 return TRUE;
00696 if ( t == CString && d->typ == String )
00697 return TRUE;
00698 if ( t == String && ( d->typ == CString || d->typ == Int || d->typ == UInt || d->typ == Double || d->typ == Byte) )
00699 return TRUE;
00700
00701 return FALSE;
00702 }
00703
00719 bool AIElement::cast( Type t )
00720 {
00721 switch ( t ) {
00722
00723
00724
00725 case AIElement::ElementArray:
00726 asElementArray();
00727 break;
00728 case AIElement::Block:
00729 asBlock();
00730 break;
00731 case AIElement::String:
00732 asString();
00733 break;
00734 case AIElement::Int:
00735 asInt();
00736 break;
00737 case AIElement::UInt:
00738 asUInt();
00739 break;
00740 case AIElement::Double:
00741 asDouble();
00742 break;
00743 case AIElement::CString:
00744 asCString();
00745 break;
00746 case AIElement::Byte:
00747 asByte();
00748 break;
00749 case AIElement::ByteArray:
00750 asByteArray();
00751 break;
00752 default:
00753 case AIElement::Invalid:
00754 (*this) = AIElement();
00755 }
00756 return canCast( t );
00757 }
00758
00763 bool AIElement::operator==( const AIElement &v ) const
00764 {
00765 if ( !v.canCast( type() ) )
00766 return FALSE;
00767 switch( d->typ ) {
00768
00769
00770 case ElementArray:
00771 return v.toElementArray() == toElementArray();
00772 case Block:
00773 return v.toBlock() == toBlock();
00774 case ByteArray:
00775 return v.toByteArray() == toByteArray();
00776
00777 case String:
00778 return v.toString() == toString();
00779 case Operator:
00780 return v.toOperator() == toOperator();
00781 case Reference:
00782 return v.toReference() == toReference();
00783 case CString:
00784 return v.toCString() == toCString();
00785 case Int:
00786 return v.toInt() == toInt();
00787 case UInt:
00788 return v.toUInt() == toUInt();
00789 case Byte:
00790 return v.toByte() == toByte();
00791 case Invalid:
00792 break;
00793 }
00794 return FALSE;
00795 }
00796
00801 bool AIElement::operator!=( const AIElement &v ) const
00802 {
00803 return !( v == *this );
00804 }
|