WebCore/xml/XPathValue.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright 2005 Frerich Raabe <raabe@kde.org>
       
     3  * Copyright (C) 2006 Apple Computer, Inc.
       
     4  *
       
     5  * Redistribution and use in source and binary forms, with or without
       
     6  * modification, are permitted provided that the following conditions
       
     7  * are met:
       
     8  * 
       
     9  * 1. Redistributions of source code must retain the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer.
       
    11  * 2. Redistributions in binary form must reproduce the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer in the
       
    13  *    documentation and/or other materials provided with the distribution.
       
    14  * 
       
    15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
       
    16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
       
    17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
       
    18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
       
    19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
       
    20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    25  */
       
    26 
       
    27 #include "config.h"
       
    28 #include "XPathValue.h"
       
    29 
       
    30 #if ENABLE(XPATH)
       
    31 
       
    32 #include "Node.h"
       
    33 #include "XPathExpressionNode.h"
       
    34 #include "XPathUtil.h"
       
    35 #include <limits>
       
    36 #include <wtf/MathExtras.h>
       
    37 #include <wtf/StdLibExtras.h>
       
    38 
       
    39 using std::numeric_limits;
       
    40 
       
    41 namespace WebCore {
       
    42 namespace XPath {
       
    43 
       
    44 const Value::AdoptTag Value::adopt = {};
       
    45 
       
    46 const NodeSet& Value::toNodeSet() const
       
    47 {
       
    48     if (!isNodeSet())
       
    49         Expression::evaluationContext().hadTypeConversionError = true;
       
    50 
       
    51     if (!m_data) {
       
    52         DEFINE_STATIC_LOCAL(NodeSet, emptyNodeSet, ());
       
    53         return emptyNodeSet;
       
    54     }
       
    55 
       
    56     return m_data->m_nodeSet;
       
    57 }    
       
    58 
       
    59 NodeSet& Value::modifiableNodeSet()
       
    60 {
       
    61     if (!isNodeSet())
       
    62         Expression::evaluationContext().hadTypeConversionError = true;
       
    63 
       
    64     if (!m_data)
       
    65         m_data = ValueData::create();
       
    66     
       
    67     m_type = NodeSetValue;
       
    68     return m_data->m_nodeSet;
       
    69 }
       
    70 
       
    71 bool Value::toBoolean() const
       
    72 {
       
    73     switch (m_type) {
       
    74         case NodeSetValue:
       
    75             return !m_data->m_nodeSet.isEmpty();
       
    76         case BooleanValue:
       
    77             return m_bool;
       
    78         case NumberValue:
       
    79             return m_number != 0 && !isnan(m_number);
       
    80         case StringValue:
       
    81             return !m_data->m_string.isEmpty();
       
    82     }
       
    83     ASSERT_NOT_REACHED();
       
    84     return false;
       
    85 }
       
    86 
       
    87 double Value::toNumber() const
       
    88 {
       
    89     switch (m_type) {
       
    90         case NodeSetValue:
       
    91             return Value(toString()).toNumber();
       
    92         case NumberValue:
       
    93             return m_number;
       
    94         case StringValue: {
       
    95             const String& str = m_data->m_string.simplifyWhiteSpace();
       
    96 
       
    97             // String::toDouble() supports exponential notation, which is not allowed in XPath.
       
    98             unsigned len = str.length();
       
    99             for (unsigned i = 0; i < len; ++i) {
       
   100                 UChar c = str[i];
       
   101                 if (!isASCIIDigit(c) && c != '.'  && c != '-')
       
   102                     return numeric_limits<double>::quiet_NaN();
       
   103             }
       
   104 
       
   105             bool canConvert;
       
   106             double value = str.toDouble(&canConvert);
       
   107             if (canConvert)
       
   108                 return value;
       
   109             return numeric_limits<double>::quiet_NaN();
       
   110         }
       
   111         case BooleanValue:
       
   112             return m_bool;
       
   113     }
       
   114     ASSERT_NOT_REACHED();
       
   115     return 0.0;
       
   116 }
       
   117 
       
   118 String Value::toString() const
       
   119 {
       
   120     switch (m_type) {
       
   121         case NodeSetValue:
       
   122             if (m_data->m_nodeSet.isEmpty()) 
       
   123                 return "";
       
   124             return stringValue(m_data->m_nodeSet.firstNode());
       
   125         case StringValue:
       
   126             return m_data->m_string;
       
   127         case NumberValue:
       
   128             if (isnan(m_number))
       
   129                 return "NaN";
       
   130             if (m_number == 0)
       
   131                 return "0";
       
   132             if (isinf(m_number))
       
   133                 return signbit(m_number) ? "-Infinity" : "Infinity";
       
   134             return String::number(m_number);
       
   135         case BooleanValue:
       
   136             return m_bool ? "true" : "false";
       
   137     }
       
   138     ASSERT_NOT_REACHED();
       
   139     return String();
       
   140 }
       
   141 
       
   142 }
       
   143 }
       
   144 
       
   145 #endif // ENABLE(XPATH)