~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/xml/XPathResult.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
 
3
 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
 
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 "XPathResult.h"
 
29
 
 
30
#include "Document.h"
 
31
#include "Node.h"
 
32
#include "ExceptionCode.h"
 
33
#include "XPathEvaluator.h"
 
34
#include "XPathException.h"
 
35
 
 
36
namespace WebCore {
 
37
 
 
38
using namespace XPath;
 
39
 
 
40
XPathResult::XPathResult(Document* document, const Value& value)
 
41
    : m_value(value)
 
42
    , m_nodeSetPosition(0)
 
43
    , m_domTreeVersion(0)
 
44
{
 
45
    switch (m_value.type()) {
 
46
        case Value::BooleanValue:
 
47
            m_resultType = BOOLEAN_TYPE;
 
48
            return;
 
49
        case Value::NumberValue:
 
50
            m_resultType = NUMBER_TYPE;
 
51
            return;
 
52
        case Value::StringValue:
 
53
            m_resultType = STRING_TYPE;
 
54
            return;
 
55
        case Value::NodeSetValue:
 
56
            m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
 
57
            m_nodeSetPosition = 0;
 
58
            m_nodeSet = m_value.toNodeSet();
 
59
            m_document = document;
 
60
            m_domTreeVersion = document->domTreeVersion();
 
61
            return;
 
62
    }
 
63
    ASSERT_NOT_REACHED();
 
64
}
 
65
 
 
66
XPathResult::~XPathResult()
 
67
{
 
68
}
 
69
 
 
70
void XPathResult::convertTo(unsigned short type, ExceptionCode& ec)
 
71
{
 
72
    switch (type) {
 
73
        case ANY_TYPE:
 
74
            break;
 
75
        case NUMBER_TYPE:
 
76
            m_resultType = type;
 
77
            m_value = m_value.toNumber();
 
78
            break;
 
79
        case STRING_TYPE:
 
80
            m_resultType = type;
 
81
            m_value = m_value.toString();
 
82
            break;
 
83
        case BOOLEAN_TYPE:
 
84
            m_resultType = type;
 
85
            m_value = m_value.toBoolean();
 
86
            break;
 
87
        case UNORDERED_NODE_ITERATOR_TYPE:
 
88
        case UNORDERED_NODE_SNAPSHOT_TYPE:
 
89
        case ANY_UNORDERED_NODE_TYPE:
 
90
        case FIRST_ORDERED_NODE_TYPE: // This is correct - singleNodeValue() will take care of ordering.
 
91
            if (!m_value.isNodeSet()) {
 
92
                ec = XPathException::TYPE_ERR;
 
93
                return;
 
94
            }
 
95
            m_resultType = type;
 
96
            break;
 
97
        case ORDERED_NODE_ITERATOR_TYPE:
 
98
            if (!m_value.isNodeSet()) {
 
99
                ec = XPathException::TYPE_ERR;
 
100
                return;
 
101
            }
 
102
            m_nodeSet.sort();
 
103
            m_resultType = type;
 
104
            break;
 
105
        case ORDERED_NODE_SNAPSHOT_TYPE:
 
106
            if (!m_value.isNodeSet()) {
 
107
                ec = XPathException::TYPE_ERR;
 
108
                return;
 
109
            }
 
110
            m_value.toNodeSet().sort();
 
111
            m_resultType = type;
 
112
            break;
 
113
    }
 
114
}
 
115
 
 
116
unsigned short XPathResult::resultType() const
 
117
{
 
118
    return m_resultType;
 
119
}
 
120
 
 
121
double XPathResult::numberValue(ExceptionCode& ec) const
 
122
{
 
123
    if (resultType() != NUMBER_TYPE) {
 
124
        ec = XPathException::TYPE_ERR;
 
125
        return 0.0;
 
126
    }
 
127
    return m_value.toNumber();
 
128
}
 
129
 
 
130
String XPathResult::stringValue(ExceptionCode& ec) const
 
131
{
 
132
    if (resultType() != STRING_TYPE) {
 
133
        ec = XPathException::TYPE_ERR;
 
134
        return String();
 
135
    }
 
136
    return m_value.toString();
 
137
}
 
138
 
 
139
bool XPathResult::booleanValue(ExceptionCode& ec) const
 
140
{
 
141
    if (resultType() != BOOLEAN_TYPE) {
 
142
        ec = XPathException::TYPE_ERR;
 
143
        return false;
 
144
    }
 
145
    return m_value.toBoolean();
 
146
}
 
147
 
 
148
Node* XPathResult::singleNodeValue(ExceptionCode& ec) const
 
149
{
 
150
    if (resultType() != ANY_UNORDERED_NODE_TYPE && resultType() != FIRST_ORDERED_NODE_TYPE) {
 
151
        ec = XPathException::TYPE_ERR;
 
152
        return 0;
 
153
    }
 
154
  
 
155
    const NodeSet& nodes = m_value.toNodeSet();
 
156
    if (resultType() == FIRST_ORDERED_NODE_TYPE)
 
157
        return nodes.firstNode();
 
158
    else
 
159
        return nodes.anyNode();
 
160
}
 
161
 
 
162
bool XPathResult::invalidIteratorState() const
 
163
{
 
164
    if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE)
 
165
        return false;
 
166
 
 
167
    ASSERT(m_document);
 
168
    return m_document->domTreeVersion() != m_domTreeVersion;
 
169
}
 
170
 
 
171
unsigned long XPathResult::snapshotLength(ExceptionCode& ec) const
 
172
{
 
173
    if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE && resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
 
174
        ec = XPathException::TYPE_ERR;
 
175
        return 0;
 
176
    }
 
177
 
 
178
    return m_value.toNodeSet().size();
 
179
}
 
180
 
 
181
Node* XPathResult::iterateNext(ExceptionCode& ec)
 
182
{
 
183
    if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE) {
 
184
        ec = XPathException::TYPE_ERR;
 
185
        return 0;
 
186
    }
 
187
    
 
188
    if (invalidIteratorState()) {
 
189
        ec = INVALID_STATE_ERR;
 
190
        return 0;
 
191
    }
 
192
    
 
193
    if (m_nodeSetPosition + 1 > m_nodeSet.size())
 
194
        return 0;
 
195
 
 
196
    Node* node = m_nodeSet[m_nodeSetPosition];
 
197
    
 
198
    m_nodeSetPosition++;
 
199
 
 
200
    return node;
 
201
}
 
202
 
 
203
Node* XPathResult::snapshotItem(unsigned long index, ExceptionCode& ec)
 
204
{
 
205
    if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE && resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
 
206
        ec = XPathException::TYPE_ERR;
 
207
        return 0;
 
208
    }
 
209
    
 
210
    const NodeSet& nodes = m_value.toNodeSet();
 
211
    if (index >= nodes.size())
 
212
        return 0;
 
213
    
 
214
    return nodes[index];
 
215
}
 
216
 
 
217
}