/* This file is part of the KDE project
Copyright ( C ) 2002 , Dirk Sch <EFBFBD> nberger < dirk . schoenberger @ sz - online . de >
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation ; either
version 2 of the License , or ( at your option ) any later version .
This library 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
Library General Public License for more details .
You should have received a copy of the GNU Library General Public License
along with this library ; see the file COPYING . LIB . If not , write to
the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
*/
# include "aielement.h"
# include <tqglobal.h>
AIElement : : Private : : Private ( )
{
typ = AIElement : : Invalid ;
}
AIElement : : Private : : Private ( Private * d )
{
switch ( d - > typ )
{
case AIElement : : Invalid :
break ;
case AIElement : : String :
case AIElement : : Reference :
case AIElement : : Operator :
value . ptr = new TQString ( * ( ( TQString * ) d - > value . ptr ) ) ;
break ;
case AIElement : : CString :
// TQCString is explicit shared
value . ptr = new TQCString ( * ( ( TQCString * ) d - > value . ptr ) ) ;
break ;
/* case AIElement::List:
value . ptr = new TQValueList < AIElement > ( * ( ( TQValueList < AIElement > * ) d - > value . ptr ) ) ;
break ; */
case AIElement : : ElementArray :
value . ptr = new TQValueVector < AIElement > ( * ( ( TQValueVector < AIElement > * ) d - > value . ptr ) ) ;
break ;
case AIElement : : Block :
value . ptr = new TQValueVector < AIElement > ( * ( ( TQValueVector < AIElement > * ) d - > value . ptr ) ) ;
break ;
case AIElement : : ByteArray :
value . ptr = new TQByteArray ( * ( ( TQByteArray * ) d - > value . ptr ) ) ;
break ;
case AIElement : : Int :
value . i = d - > value . i ;
break ;
case AIElement : : UInt :
value . u = d - > value . u ;
break ;
case AIElement : : Double :
value . d = d - > value . d ;
break ;
case AIElement : : Byte :
value . b = d - > value . b ;
break ;
default :
Q_ASSERT ( 0 ) ;
}
typ = d - > typ ;
}
AIElement : : Private : : ~ Private ( )
{
clear ( ) ;
}
void AIElement : : Private : : clear ( )
{
switch ( typ )
{
case AIElement : : String :
case AIElement : : Operator :
case AIElement : : Reference :
delete ( TQString * ) value . ptr ;
break ;
case AIElement : : CString :
delete ( TQCString * ) value . ptr ;
break ;
/* case AIElement::List:
delete ( TQValueList < AIElement > * ) value . ptr ;
break ; */
case AIElement : : ElementArray :
delete ( TQValueVector < AIElement > * ) value . ptr ;
break ;
case AIElement : : Block :
delete ( TQValueVector < AIElement > * ) value . ptr ;
break ;
case AIElement : : ByteArray :
delete ( TQByteArray * ) value . ptr ;
break ;
case AIElement : : Invalid :
case AIElement : : Int :
case AIElement : : UInt :
case AIElement : : Double :
case AIElement : : Byte :
break ;
}
typ = AIElement : : Invalid ;
}
/*!
Constructs an invalid aielement .
*/
AIElement : : AIElement ( )
{
d = new Private ;
}
/*!
Destroys the AIElement and the contained object .
Note that subclasses that reimplement clear ( ) should reimplement
the destructor to call clear ( ) . This destructor calls clear ( ) , but
because it is the destructor , AIElement : : clear ( ) is called rather than
a subclass ' s clear ( ) .
*/
AIElement : : ~ AIElement ( )
{
if ( d - > deref ( ) )
delete d ;
}
/*!
Constructs a copy of the aielement , \ a p , passed as the argument to this
constructor . Usually this is a deep copy , but a shallow copy is made
if the stored data type is explicitly shared , as e . g . TQImage is .
*/
AIElement : : AIElement ( const AIElement & p )
{
d = new Private ;
* this = p ;
}
/*!
Constructs a new aielement with a string value , \ a val .
*/
AIElement : : AIElement ( const TQString & val , Type type )
{
d = new Private ;
d - > typ = type ;
d - > value . ptr = new TQString ( val ) ;
}
/*!
Constructs a new aielement with a C - string value , \ a val .
If you want to modify the TQCString after you ' ve passed it to this
constructor , we recommend passing a deep copy ( see
TQCString : : copy ( ) ) .
*/
AIElement : : AIElement ( const TQCString & val )
{
d = new Private ;
d - > typ = CString ;
d - > value . ptr = new TQCString ( val ) ;
}
/*!
Constructs a new aielement with a C - string value of \ a val if \ a val
is non - null . The aielement creates a deep copy of \ a val .
If \ a val is null , the resulting aielement has type Invalid .
*/
AIElement : : AIElement ( const char * val )
{
d = new Private ;
if ( val = = 0 )
return ;
d - > typ = CString ;
d - > value . ptr = new TQCString ( val ) ;
}
/*!
Constructs a new aielement with an integer value , \ a val .
*/
AIElement : : AIElement ( int val )
{
d = new Private ;
d - > typ = Int ;
d - > value . i = val ;
}
/*!
Constructs a new aielement with an unsigned integer value , \ a val .
*/
AIElement : : AIElement ( uint val )
{
d = new Private ;
d - > typ = UInt ;
d - > value . u = val ;
}
/*!
Constructs a new aielement with an byte value , \ a val .
*/
AIElement : : AIElement ( uchar val )
{
d = new Private ;
d - > typ = Byte ;
d - > value . b = val ;
}
/*!
Constructs a new aielement with a floating point value , \ a val .
*/
AIElement : : AIElement ( double val )
{
d = new Private ;
d - > typ = Double ;
d - > value . d = val ;
}
/*!
Constructs a new aielement with a list value , \ a val .
*/
/* AIElement::AIElement( const TQValueList<AIElement>& val )
{
d = new Private ;
d - > typ = List ;
d - > value . ptr = new TQValueList < AIElement > ( val ) ;
} */
AIElement : : AIElement ( const TQValueVector < AIElement > & val , Type type )
{
d = new Private ;
d - > typ = type ;
d - > value . ptr = new TQValueVector < AIElement > ( val ) ;
}
AIElement : : AIElement ( const TQByteArray & val )
{
d = new Private ;
d - > typ = ByteArray ;
d - > value . ptr = new TQByteArray ( val ) ;
}
/*!
Assigns the value of the aielement \ a aielement to this aielement .
This is a deep copy of the aielement , but note that if the aielement
holds an explicitly shared type such as TQImage , a shallow copy
is performed .
*/
AIElement & AIElement : : operator = ( const AIElement & aielement )
{
AIElement & other = ( AIElement & ) aielement ;
other . d - > ref ( ) ;
if ( d - > deref ( ) )
delete d ;
d = other . d ;
return * this ;
}
/*!
\ internal
*/
void AIElement : : detach ( )
{
if ( d - > count = = 1 )
return ;
d - > deref ( ) ;
d = new Private ( d ) ;
}
/*!
Returns the name of the type stored in the aielement .
The returned strings describe the C + + datatype used to store the
data : for example , " TQFont " , TQSTRING_OBJECT_NAME_STRING , or " TQValueList<AIElement> " .
An Invalid aielement returns 0.
*/
const char * AIElement : : typeName ( ) const
{
return typeToName ( d - > typ ) ;
}
/*! Convert this aielement to type Invalid and free up any resources
used .
*/
void AIElement : : clear ( )
{
if ( d - > count > 1 )
{
d - > deref ( ) ;
d = new Private ;
return ;
}
d - > clear ( ) ;
}
static const int ntypes = 11 ;
static const char * const type_map [ ntypes ] =
{
0 ,
// "TQValueList<AIElement>",
TQSTRING_OBJECT_NAME_STRING ,
" int " ,
" uint " ,
" double " ,
" TQCString " ,
" Operator " ,
" Reference " ,
" TQValueVector<AIElement> " ,
TQBYTEARRAY_OBJECT_NAME_STRING ,
" uchar " ,
} ;
/*!
Converts the enum representation of the storage type , \ a typ , to its
string representation .
*/
const char * AIElement : : typeToName ( Type typ )
{
if ( typ > = ntypes )
return 0 ;
return type_map [ typ ] ;
}
/*!
Converts the string representation of the storage type gven in \ a
name , to its enum representation .
If the string representation cannot be converted to any enum
representation , the aielement is set to \ c Invalid .
*/
AIElement : : Type AIElement : : nameToType ( const char * name )
{
for ( int i = 0 ; i < ntypes ; i + + ) {
if ( ! qstrcmp ( type_map [ i ] , name ) )
return ( Type ) i ;
}
return Invalid ;
}
/*!
Returns the aielement as a TQString if the aielement has type ( )
String , CString , ByteArray , Int , Uint , Double ,
or TQString ( ) otherwise .
\ sa asString ( )
*/
const TQString AIElement : : toString ( ) const
{
if ( d - > typ = = CString )
return TQString : : fromLatin1 ( toCString ( ) ) ;
if ( d - > typ = = Int )
return TQString : : number ( toInt ( ) ) ;
if ( d - > typ = = UInt )
return TQString : : number ( toUInt ( ) ) ;
if ( d - > typ = = Double )
return TQString : : number ( toDouble ( ) ) ;
if ( d - > typ = = Byte )
return TQString : : number ( toByte ( ) ) ;
if ( d - > typ ! = String )
return TQString ( ) ;
return * ( ( TQString * ) d - > value . ptr ) ;
}
const TQString AIElement : : toReference ( ) const
{
if ( d - > typ ! = Reference )
return TQString ( ) ;
return * ( ( TQString * ) d - > value . ptr ) ;
}
const TQString AIElement : : toOperator ( ) const
{
if ( d - > typ ! = Operator )
return TQString ( ) ;
return * ( ( TQString * ) d - > value . ptr ) ;
}
/*!
Returns the aielement as a TQCString if the aielement has type ( )
CString or String , or a 0 otherwise .
\ sa asCString ( )
*/
const TQCString AIElement : : toCString ( ) const
{
if ( d - > typ = = CString )
return * ( ( TQCString * ) d - > value . ptr ) ;
if ( d - > typ = = String )
return ( ( TQString * ) d - > value . ptr ) - > latin1 ( ) ;
if ( d - > typ = = Operator )
return ( ( TQString * ) d - > value . ptr ) - > latin1 ( ) ;
if ( d - > typ = = Reference )
return ( ( TQString * ) d - > value . ptr ) - > latin1 ( ) ;
return 0 ;
}
/*!
Returns the aielement as an int if the aielement has type ( )
String , CString , Int , UInt , Double , Byte , or 0 otherwise .
If \ a ok is non - null , \ a * ok is set to TRUE if the value could be
converted to an int and FALSE otherwise .
\ sa asInt ( ) canCast ( )
*/
int AIElement : : toInt ( bool * ok ) const
{
if ( d - > typ = = String )
return ( ( TQString * ) d - > value . ptr ) - > toInt ( ok ) ;
if ( d - > typ = = CString )
return ( ( TQCString * ) d - > value . ptr ) - > toInt ( ok ) ;
if ( ok )
* ok = canCast ( UInt ) ;
if ( d - > typ = = Int )
return d - > value . i ;
if ( d - > typ = = UInt )
return ( int ) d - > value . u ;
if ( d - > typ = = Byte )
return ( int ) d - > value . b ;
if ( d - > typ = = Double )
return ( int ) d - > value . d ;
return 0 ;
}
uchar AIElement : : toByte ( bool * ok ) const
{
if ( d - > typ = = String )
return ( ( TQString * ) d - > value . ptr ) - > toShort ( ok ) ;
if ( d - > typ = = CString )
return ( ( TQCString * ) d - > value . ptr ) - > toShort ( ok ) ;
if ( ok )
* ok = canCast ( UInt ) ;
if ( d - > typ = = Byte )
return d - > value . b ;
if ( d - > typ = = Int )
return ( uchar ) d - > value . i ;
if ( d - > typ = = UInt )
return ( uchar ) d - > value . u ;
if ( d - > typ = = Double )
return ( uchar ) d - > value . d ;
return 0 ;
}
/*!
Returns the aielement as an unsigned int if the aielement has type ( )
String , CString , UInt , Int , Double , Byte , or 0 otherwise .
If \ a ok is non - null , \ a * ok is set to TRUE if the value could be
converted to a uint and FALSE otherwise .
\ sa asUInt ( )
*/
uint AIElement : : toUInt ( bool * ok ) const
{
if ( d - > typ = = String )
return ( ( TQString * ) d - > value . ptr ) - > toUInt ( ok ) ;
if ( d - > typ = = CString )
return ( ( TQCString * ) d - > value . ptr ) - > toUInt ( ok ) ;
if ( ok )
* ok = canCast ( UInt ) ;
if ( d - > typ = = Int )
return d - > value . i ;
if ( d - > typ = = UInt )
return ( int ) d - > value . u ;
if ( d - > typ = = Byte )
return ( int ) d - > value . b ;
if ( d - > typ = = Double )
return ( int ) d - > value . d ;
return 0 ;
}
/*!
Returns the aielement as a double if the aielement has type ( )
String , CString , Double , Int , UInt , Byte , or 0.0 otherwise .
If \ a ok is non - null , \ a * ok is set to TRUE if the value could be
converted to a double and FALSE otherwise .
\ sa asDouble ( )
*/
double AIElement : : toDouble ( bool * ok ) const
{
if ( d - > typ = = String )
return ( ( TQString * ) d - > value . ptr ) - > toDouble ( ok ) ;
if ( d - > typ = = CString )
return ( ( TQCString * ) d - > value . ptr ) - > toDouble ( ok ) ;
if ( ok )
* ok = canCast ( Double ) ;
if ( d - > typ = = Double )
return d - > value . d ;
if ( d - > typ = = Int )
return ( double ) d - > value . i ;
if ( d - > typ = = UInt )
return ( double ) d - > value . u ;
if ( d - > typ = = Byte )
return ( double ) d - > value . b ;
return 0.0 ;
}
/*!
Returns the aielement as a TQValueList < AIElement > if the aielement has type ( )
List or StringList , or an empty list otherwise .
Note that if you want to iterate over the list , you should
iterate over a copy , e . g .
\ code
TQValueList < AIElement > list = myAIElement . toList ( ) ;
TQValueList < AIElement > : : Iterator it = list . begin ( ) ;
while ( it ! = list . end ( ) ) {
myProcessing ( * it ) ;
+ + it ;
}
\ endcode
\ sa asList ( )
*/
/* const TQValueList<AIElement> AIElement::toList() const
{
if ( d - > typ = = List )
return * ( ( TQValueList < AIElement > * ) d - > value . ptr ) ;
return TQValueList < AIElement > ( ) ;
} */
const TQValueVector < AIElement > AIElement : : toElementArray ( ) const
{
if ( d - > typ = = ElementArray )
return * ( ( TQValueVector < AIElement > * ) d - > value . ptr ) ;
return TQValueVector < AIElement > ( ) ;
}
const TQValueVector < AIElement > AIElement : : toBlock ( ) const
{
if ( d - > typ = = Block )
return * ( ( TQValueVector < AIElement > * ) d - > value . ptr ) ;
return TQValueVector < AIElement > ( ) ;
}
const TQByteArray AIElement : : toByteArray ( ) const
{
if ( d - > typ = = ByteArray )
return * ( ( TQByteArray * ) d - > value . ptr ) ;
return TQByteArray ( ) ;
}
# define TQ_VARIANT_AS( f ) TQ##f& AIElement::as##f() { \
if ( d - > typ ! = f ) * this = AIElement ( to # # f ( ) ) ; else detach ( ) ; return * ( ( TQ # # f * ) d - > value . ptr ) ; }
TQ_VARIANT_AS ( String )
TQ_VARIANT_AS ( CString )
/*!
Returns the aielement ' s value as int reference .
*/
int & AIElement : : asInt ( )
{
detach ( ) ;
if ( d - > typ ! = Int ) {
int i = toInt ( ) ;
d - > clear ( ) ;
d - > value . i = i ;
d - > typ = Int ;
}
return d - > value . i ;
}
/*!
Returns the aielement ' s value as unsigned int reference .
*/
uint & AIElement : : asUInt ( )
{
detach ( ) ;
if ( d - > typ ! = UInt ) {
uint u = toUInt ( ) ;
d - > clear ( ) ;
d - > value . u = u ;
d - > typ = UInt ;
}
return d - > value . u ;
}
/*!
Returns the aielement ' s value as double reference .
*/
double & AIElement : : asDouble ( )
{
if ( d - > typ ! = Double ) {
double dbl = toDouble ( ) ;
d - > clear ( ) ;
d - > value . d = dbl ;
d - > typ = Double ;
}
return d - > value . d ;
}
/*!
Returns the aielement ' s value as byte reference .
*/
uchar & AIElement : : asByte ( )
{
detach ( ) ;
if ( d - > typ ! = Byte ) {
uchar b = toByte ( ) ;
d - > clear ( ) ;
d - > value . b = b ;
d - > typ = Byte ;
}
return d - > value . b ;
}
/*!
Returns the aielement ' s value as aielement list reference .
Note that if you want to iterate over the list , you should
iterate over a copy , e . g .
\ code
TQValueList < AIElement > list = myAIElement . asList ( ) ;
TQValueList < AIElement > : : Iterator it = list . begin ( ) ;
while ( it ! = list . end ( ) ) {
myProcessing ( * it ) ;
+ + it ;
}
\ endcode
*/
/* TQValueList<AIElement>& AIElement::asList()
{
if ( d - > typ ! = List )
* this = AIElement ( toList ( ) ) ;
return * ( ( TQValueList < AIElement > * ) d - > value . ptr ) ;
} */
TQValueVector < AIElement > & AIElement : : asElementArray ( )
{
if ( d - > typ ! = ElementArray )
* this = AIElement ( toElementArray ( ) ) ;
return * ( ( TQValueVector < AIElement > * ) d - > value . ptr ) ;
}
TQValueVector < AIElement > & AIElement : : asBlock ( )
{
if ( d - > typ ! = Block )
* this = AIElement ( toBlock ( ) ) ;
return * ( ( TQValueVector < AIElement > * ) d - > value . ptr ) ;
}
TQByteArray & AIElement : : asByteArray ( )
{
if ( d - > typ ! = ByteArray )
* this = AIElement ( toByteArray ( ) ) ;
return * ( ( TQByteArray * ) d - > value . ptr ) ;
}
/*!
Returns TRUE if the aielement ' s type can be cast to the requested
type , \ p t . Such casting is done automatically when calling the
toInt ( ) , . . . or asInt ( ) , . . . methods .
The following casts are done automatically :
< ul >
< li > CString = > String
< li > Double = > String , Int , UInt
< li > Int = > String , Double , UInt
< li > String = > CString , Int , Uint , Double
< li > UInt = > String , Double , Int
< / ul >
*/
bool AIElement : : canCast ( Type t ) const
{
if ( d - > typ = = t )
return TRUE ;
if ( t = = Int & & ( d - > typ = = String | | d - > typ = = Double | | d - > typ = = UInt | | d - > typ = = Byte ) )
return TRUE ;
if ( t = = UInt & & ( d - > typ = = String | | d - > typ = = Double | | d - > typ = = Int | | d - > typ = = Byte ) )
return TRUE ;
if ( t = = Double & & ( d - > typ = = String | | d - > typ = = Int | | d - > typ = = UInt | | d - > typ = = Byte ) )
return TRUE ;
if ( t = = CString & & d - > typ = = String )
return TRUE ;
if ( t = = String & & ( d - > typ = = CString | | d - > typ = = Int | | d - > typ = = UInt | | d - > typ = = Double | | d - > typ = = Byte ) )
return TRUE ;
return FALSE ;
}
/*!
\ brief Casts the aielement to the requested type .
If the cast cannot be
done , the aielement is set to the default value of the requested type
( e . g . an empty string if the requested type \ p t is
AIElement : : String , an empty point array if the requested type \ p t is
AIElement : : PointArray , etc ) .
\ returns TRUE if the current type of the
aielement was successfully casted ; otherwise returns FALSE .
\ see canCast ( )
*/
bool AIElement : : cast ( Type t )
{
switch ( t ) {
/* case AIElement::List:
asList ( ) ;
break ; */
case AIElement : : ElementArray :
asElementArray ( ) ;
break ;
case AIElement : : Block :
asBlock ( ) ;
break ;
case AIElement : : String :
asString ( ) ;
break ;
case AIElement : : Int :
asInt ( ) ;
break ;
case AIElement : : UInt :
asUInt ( ) ;
break ;
case AIElement : : Double :
asDouble ( ) ;
break ;
case AIElement : : CString :
asCString ( ) ;
break ;
case AIElement : : Byte :
asByte ( ) ;
break ;
case AIElement : : ByteArray :
asByteArray ( ) ;
break ;
default :
case AIElement : : Invalid :
( * this ) = AIElement ( ) ;
}
return canCast ( t ) ;
}
/*! Compares this AIElement with \a v and returns TRUE if they are
equal ; otherwise returns FALSE .
*/
bool AIElement : : operator = = ( const AIElement & v ) const
{
if ( ! v . canCast ( type ( ) ) )
return FALSE ;
switch ( d - > typ ) {
/* case List:
return v . toList ( ) = = toList ( ) ; */
case ElementArray :
return v . toElementArray ( ) = = toElementArray ( ) ;
case Block :
return v . toBlock ( ) = = toBlock ( ) ;
case ByteArray :
return v . toByteArray ( ) = = toByteArray ( ) ;
case String :
return v . toString ( ) = = toString ( ) ;
case Operator :
return v . toOperator ( ) = = toOperator ( ) ;
case Reference :
return v . toReference ( ) = = toReference ( ) ;
case CString :
return v . toCString ( ) = = toCString ( ) ;
case Int :
return v . toInt ( ) = = toInt ( ) ;
case UInt :
return v . toUInt ( ) = = toUInt ( ) ;
case Byte :
return v . toByte ( ) = = toByte ( ) ;
case Invalid :
break ;
}
return FALSE ;
}
/*! Compares this AIElement with \a v and returns TRUE if they are
not equal ; otherwise returns FALSE .
*/
bool AIElement : : operator ! = ( const AIElement & v ) const
{
return ! ( v = = * this ) ;
}