filters

aielement.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002, Dirk Schönberger <dirk.schoenberger@sz-online.de>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
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         // QCString is explicit shared
00041         value.ptr = new QCString( *((QCString*)d->value.ptr) );
00042         break;
00043 /*      case AIElement::List:
00044         value.ptr = new QValueList<AIElement>( *((QValueList<AIElement>*)d->value.ptr) );
00045         break; */
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 /*      case AIElement::List:
00092         delete (QValueList<AIElement>*)value.ptr;
00093         break; */
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 /* AIElement::AIElement( const QValueList<AIElement>& val )
00231 {
00232   d = new Private;
00233   d->typ = List;
00234   d->value.ptr = new QValueList<AIElement>( val );
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 //  "QValueList<AIElement>",
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 /* const QValueList<AIElement> AIElement::toList() const
00535 {
00536   if ( d->typ == List )
00537       return *((QValueList<AIElement>*)d->value.ptr);
00538   return QValueList<AIElement>();
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 /* QValueList<AIElement>& AIElement::asList()
00644 {
00645   if ( d->typ != List )
00646       *this = AIElement( toList() );
00647   return *((QValueList<AIElement>*)d->value.ptr);
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 /*    case AIElement::List:
00723         asList();
00724         break; */
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 /*    case List:
00769          return v.toList() == toList(); */
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 }
KDE Home | KDE Accessibility Home | Description of Access Keys