• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KHTML

expression.cpp

Go to the documentation of this file.
00001 /*
00002  * expression.cc - Copyright 2005 Frerich Raabe <raabe@kde.org>
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  *
00014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024  */
00025 #include "expression.h"
00026 #include "xml/dom_nodeimpl.h"
00027 #include "xml/dom_nodelistimpl.h"
00028 #include "dom/dom_exception.h"
00029 #include "dom/dom3_xpath.h"
00030 //#include "xml/dom_stringimpl.h"
00031 
00032 #include <cmath>
00033 
00034 using namespace DOM;
00035 using namespace khtml;
00036 using namespace khtml::XPath;
00037 using namespace std;
00038 
00039 // Use KJS's numeric FP stuff
00040 #include "kjs/JSImmediate.h"
00041 #include "kjs/operations.h"
00042 
00043 Value::Value():
00044     m_type  ( Number ),
00045     m_number( KJS::NaN )
00046 {
00047     // ### remove eventually
00048 }
00049 
00050 Value::Value( NodeImpl *value )
00051     : m_type( Nodeset )
00052 {
00053     m_nodeset = new StaticNodeListImpl;
00054     m_nodeset->append( value );
00055 }
00056 
00057 Value::Value( const DomNodeList &value )
00058     : m_type( Nodeset ),
00059     m_nodeset( value )
00060 {
00061 }
00062 
00063 Value::Value( bool value )
00064     : m_type( Boolean ),
00065     m_bool( value )
00066 {
00067 }
00068 
00069 Value::Value( double value )
00070     : m_type( Number ),
00071     m_number( value )
00072 {
00073 }
00074 
00075 Value::Value( const DOMString &value )
00076     : m_type( String ),
00077     m_string( value )
00078 {
00079 }
00080 
00081 Value::Type Value::type() const
00082 {
00083     return m_type;
00084 }
00085 
00086 bool Value::isNodeset() const
00087 {
00088     return m_type == Nodeset;
00089 }
00090 
00091 bool Value::isBoolean() const
00092 {
00093     return m_type == Boolean;
00094 }
00095 
00096 bool Value::isNumber() const
00097 {
00098     return m_type == Number;
00099 }
00100 
00101 bool Value::isString() const
00102 {
00103     return m_type == String;
00104 }
00105 
00106 DomNodeList &Value::toNodeset()
00107 {
00108     if ( m_type != Nodeset ) {
00109         kWarning(6011) << "Cannot convert anything to a nodeset.";
00110     }
00111     return m_nodeset;
00112 }
00113 
00114 const DomNodeList &Value::toNodeset() const
00115 {
00116     if ( m_type != Nodeset ) {
00117         kWarning(6011) << "Cannot convert anything to a nodeset.";
00118     }
00119     return m_nodeset;
00120 }
00121 
00122 bool Value::toBoolean() const
00123 {
00124     switch ( m_type ) {
00125         case Nodeset:
00126             return m_nodeset && m_nodeset->length() != 0;
00127         case Boolean:
00128             return m_bool;
00129         case Number:
00130             return m_number != 0;
00131         case String:
00132             return !m_string.isEmpty();
00133     }
00134     return bool();
00135 }
00136 
00137 double Value::toNumber() const
00138 {
00139     switch ( m_type ) {
00140         case Nodeset:
00141             return Value( toString() ).toNumber();
00142         case Number:
00143             return m_number;
00144         case String: {
00145             bool canConvert;
00146             QString s = m_string.string().simplified();
00147             double value = s.toDouble( &canConvert );
00148             if ( canConvert ) {
00149                 return value;
00150             } else {
00151                 return KJS::NaN;
00152             }
00153         }
00154         case Boolean:
00155             return m_bool ? 1 : 0;
00156     }
00157     return double();
00158 }
00159 
00160 DOMString Value::toString() const
00161 {
00162     switch ( m_type ) {
00163         case Nodeset:
00164             if ( m_nodeset && m_nodeset->length() == 0 ) {
00165                 return DOMString( "" );
00166             }
00167             m_nodeset->normalizeUpto( StaticNodeListImpl::AxisOrder );
00168             return stringValue( m_nodeset->item(0) );
00169         case String:
00170             return m_string;
00171         case Number:
00172             if ( KJS::isNaN( m_number ) ) {
00173                 return DOMString( "NaN" );
00174             } else if ( m_number == 0 ) {
00175                 return DOMString( "0" );
00176             } else if ( KJS::isInf( m_number ) ) {
00177                 if ( signbit( m_number ) == 0 ) {
00178                     return DOMString( "Infinity" );
00179                 } else {
00180                     return DOMString( "-Infinity" );
00181                 }
00182             }
00183             return QString::number( m_number );
00184         case Boolean:
00185             return m_bool ? DOMString( "true" )
00186                           : DOMString( "false" );
00187     }
00188     return DOMString();
00189 }
00190 
00191 QString Value::dump() const
00192 {
00193     QString s = "<value type=\"";
00194     switch ( m_type ) {
00195         case Nodeset:
00196             s += "nodeset";
00197             break;
00198         case String:
00199             s += "string";
00200             break;
00201         case Number:
00202             s += "number";
00203             break;
00204         case Boolean:
00205             s += "boolean";
00206             break;
00207     };
00208     s += "\">" + toString().string() + "</value>";
00209     return s;
00210 }
00211 
00212 EvaluationContext &Expression::evaluationContext()
00213 {
00214     static EvaluationContext evaluationContext;
00215     return evaluationContext;
00216 }
00217 
00218 Expression::Expression()
00219     : m_constantValue( 0 )
00220 {
00221 }
00222 
00223 Expression::~Expression()
00224 {
00225     qDeleteAll( m_subExpressions );
00226     delete m_constantValue;
00227 }
00228 
00229 Value Expression::evaluate() const
00230 {
00231     if ( m_constantValue ) {
00232         return *m_constantValue;
00233     }
00234     return doEvaluate();
00235 }
00236 
00237 void Expression::addSubExpression( Expression *expr )
00238 {
00239     m_subExpressions.append( expr );
00240 }
00241 
00242 void Expression::optimize()
00243 {
00244     bool allSubExpressionsConstant = true;
00245     foreach( Expression *expr, m_subExpressions ) {
00246         if ( expr->isConstant() ) {
00247             expr->optimize();
00248         } else {
00249             allSubExpressionsConstant = false;
00250         }
00251     }
00252 
00253     if ( allSubExpressionsConstant ) {
00254         m_constantValue = new Value( doEvaluate() );
00255 
00256         qDeleteAll( m_subExpressions );
00257         m_subExpressions.clear();
00258     }
00259 }
00260 
00261 unsigned int Expression::subExprCount() const
00262 {
00263     return m_subExpressions.count();
00264 }
00265 
00266 Expression *Expression::subExpr( unsigned int i )
00267 {
00268     Q_ASSERT( i < subExprCount() );
00269     return m_subExpressions.at( i );
00270 }
00271 
00272 const Expression *Expression::subExpr( unsigned int i ) const
00273 {
00274     Q_ASSERT( i < subExprCount() );
00275     return m_subExpressions.at( i );
00276 }
00277 
00278 bool Expression::isConstant() const
00279 {
00280     foreach( Expression *expr, m_subExpressions ) {
00281         if ( !expr->isConstant() ) {
00282             return false;
00283         }
00284     }
00285     return true;
00286 }
00287 
00288 void Expression::reportInvalidExpressionErr()
00289 {
00290     Expression::evaluationContext().reportException(XPathException::toCode(INVALID_EXPRESSION_ERR));
00291 }
00292 
00293 void Expression::reportNamespaceErr()
00294 {
00295     Expression::evaluationContext().reportException(DOMException::NAMESPACE_ERR);
00296 }
00297 
00298 // kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal