Reviewed by Anders.
[WebKit-https.git] / WebCore / xpath / impl / XPathValue.cpp
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 XPATH_SUPPORT
31
32 #include "Node.h"
33 #include <wtf/MathExtras.h>
34
35 namespace WebCore {
36 namespace XPath {
37
38 Value::Value()
39     : m_type(BooleanValue), m_bool(false)
40 {
41 }
42
43 Value::Value(Node* value)
44     : m_type(NodeVectorValue)
45 {
46     m_nodeVector.append(value);
47 }
48
49 Value::Value(const NodeVector& value)
50     : m_type(NodeVectorValue), m_nodeVector(value)
51 {
52 }
53
54 Value::Value(bool value)
55     : m_type(BooleanValue), m_bool(value)
56 {
57 }
58
59 Value::Value(unsigned value)
60     : m_type(NumberValue), m_number(value)
61 {
62 }
63
64 Value::Value(unsigned long value)
65     : m_type(NumberValue), m_number(value)
66 {
67 }
68
69 Value::Value(double value)
70     : m_type(NumberValue), m_number(value)
71 {
72 }
73
74 Value::Value(const String& value)
75     : m_type(StringValue), m_string(value)
76 {
77 }
78
79 const NodeVector &Value::toNodeVector() const
80 {
81     return m_nodeVector;    
82 }    
83
84 bool Value::toBoolean() const
85 {
86     switch (m_type) {
87         case NodeVectorValue:
88             return !m_nodeVector.isEmpty();
89         case BooleanValue:
90             return m_bool;
91         case NumberValue:
92             return m_number != 0;
93         case StringValue:
94             return !m_string.isEmpty();
95     }
96     ASSERT_NOT_REACHED();
97     return false;
98 }
99
100 double Value::toNumber() const
101 {
102     switch (m_type) {
103         case NodeVectorValue:
104             return Value(toString()).toNumber();
105         case NumberValue:
106             return m_number;
107         case StringValue: {
108             bool canConvert;
109             double value = m_string.deprecatedString().simplifyWhiteSpace().toDouble(&canConvert);
110             if (canConvert)
111                 return value;
112             return NAN;
113         }
114         case BooleanValue:
115             return m_bool;
116     }
117     ASSERT_NOT_REACHED();
118     return 0.0;
119 }
120
121 String Value::toString() const
122 {
123     switch (m_type) {
124         case NodeVectorValue:
125             if (m_nodeVector.isEmpty()) 
126                 return "";
127             return stringValue(m_nodeVector[0].get());
128         case StringValue:
129             return m_string;
130         case NumberValue:
131             if (isnan(m_number))
132                 return "NaN";
133             if (m_number == 0)
134                 return "0";
135             if (isinf(m_number))
136                 return signbit(m_number) ? "-Infinity" : "Infinity";
137             return String::number(m_number);
138         case BooleanValue:
139             return m_bool ? "true" : "false";
140     }
141     ASSERT_NOT_REACHED();
142     return String();
143 }
144
145 }
146 }
147
148 #endif // XPATH_SUPPORT