summaryrefslogtreecommitdiffstats
path: root/filters/karbon/ai/aielement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'filters/karbon/ai/aielement.cpp')
-rw-r--r--filters/karbon/ai/aielement.cpp804
1 files changed, 804 insertions, 0 deletions
diff --git a/filters/karbon/ai/aielement.cpp b/filters/karbon/ai/aielement.cpp
new file mode 100644
index 000000000..2f514d06c
--- /dev/null
+++ b/filters/karbon/ai/aielement.cpp
@@ -0,0 +1,804 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, Dirk Schö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 );
+}