2006-05-08 Anders Carlsson <acarlsson@apple.com>
[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 #include "config.h"
27
28 #if XPATH_SUPPORT
29
30 #include "XPathValue.h"
31 #include "Logging.h"
32
33 namespace WebCore {
34 namespace XPath {
35
36 Value::Value()
37 {
38 }
39
40 Value::Value(Node* value)
41     : m_type(NodeVector_)
42 {
43     m_nodevector.append(value);
44 }
45
46 Value::Value(const NodeVector& value)
47     : m_type(NodeVector_)
48     , m_nodevector(value)
49 {
50 }
51
52 Value::Value(bool value)
53     : m_type(Boolean),
54     m_bool(value)
55 {
56 }
57
58 Value::Value(double value)
59     : m_type(Number),
60     m_number(value)
61 {
62 }
63
64 Value::Value(const String& value)
65     : m_type(String_),
66     m_string(value)
67 {
68 }
69
70 Value::Type Value::type() const
71 {
72     return m_type;
73 }
74
75 bool Value::isNodeVector() const
76 {
77     return m_type == NodeVector_;
78 }
79
80 bool Value::isBoolean() const
81 {
82     return m_type == Boolean;
83 }
84
85 bool Value::isNumber() const
86 {
87     return m_type == Number;
88 }
89
90 bool Value::isString() const
91 {
92     return m_type == String_;
93 }
94
95 NodeVector& Value::toNodeVector()
96 {
97     if (m_type != NodeVector_) {
98         LOG(XPath, "Cannot convert anything to a nodevector.");
99     }
100     return m_nodevector;
101 }
102
103 const NodeVector &Value::toNodeVector() const
104 {
105     if (m_type != NodeVector_) {
106         LOG(XPath, "Cannot convert anything to a nodevector.");
107     }
108     
109     return m_nodevector;    
110 }    
111
112 bool Value::toBoolean() const
113 {
114     switch (m_type) {
115         case NodeVector_:
116             return !m_nodevector.isEmpty();
117         case Boolean:
118             return m_bool;
119         case Number:
120             return m_number != 0;
121         case String_:
122             return !m_string.isEmpty();
123     }
124     return false;
125 }
126
127 double Value::toNumber() const
128 {
129     switch (m_type) {
130         case NodeVector_:
131             return Value(toString()).toNumber();
132         case Number:
133             return m_number;
134         case String_: {
135             bool canConvert;
136             DeprecatedString s = m_string.deprecatedString().simplifyWhiteSpace();
137             
138             double value = s.toDouble(&canConvert);
139             if (canConvert)
140                 return value;
141
142             return NAN;
143         }
144         case Boolean:
145             return m_bool;
146     }
147     return 0.0;
148 }
149
150 String Value::toString() const
151 {
152     switch (m_type) {
153         case NodeVector_:
154             if (m_nodevector.isEmpty()) 
155                 return "";
156
157             return stringValue(m_nodevector[0].get());
158         case String_:
159             return m_string;
160         case Number:
161             if (isnan(m_number))
162                 return "NaN";
163             else if (m_number == 0)
164                 return "0";
165             else if (isinf(m_number)) {
166                 if (signbit(m_number) == 0)
167                     return "Infinity";
168                 else
169                     return "-Infinity";
170             }
171             return DeprecatedString::number(m_number);
172         case Boolean:
173             return m_bool ? "true" : "false";
174     }
175     
176     return String();
177 }
178
179
180 }
181 }
182
183 #endif // XPATH_SUPPORT