Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/xslt/xml/txXMLUtils.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
/*
7
 * XML utility classes
8
 */
9
10
#include "txXMLUtils.h"
11
#include "nsString.h"
12
#include "nsReadableUtils.h"
13
#include "nsGkAtoms.h"
14
#include "txStringUtils.h"
15
#include "txNamespaceMap.h"
16
#include "txXPathTreeWalker.h"
17
#include "nsContentUtils.h"
18
19
//------------------------------/
20
//- Implementation of XMLUtils -/
21
//------------------------------/
22
23
// static
24
nsresult
25
XMLUtils::splitExpatName(const char16_t *aExpatName, nsAtom **aPrefix,
26
                         nsAtom **aLocalName, int32_t* aNameSpaceID)
27
0
{
28
0
    /**
29
0
     *  Expat can send the following:
30
0
     *    localName
31
0
     *    namespaceURI<separator>localName
32
0
     *    namespaceURI<separator>localName<separator>prefix
33
0
     */
34
0
35
0
    const char16_t *uriEnd = nullptr;
36
0
    const char16_t *nameEnd = nullptr;
37
0
    const char16_t *pos;
38
0
    for (pos = aExpatName; *pos; ++pos) {
39
0
        if (*pos == kExpatSeparatorChar) {
40
0
            if (uriEnd) {
41
0
                nameEnd = pos;
42
0
            }
43
0
            else {
44
0
                uriEnd = pos;
45
0
            }
46
0
        }
47
0
    }
48
0
49
0
    const char16_t *nameStart;
50
0
    if (uriEnd) {
51
0
        *aNameSpaceID =
52
0
            txNamespaceManager::getNamespaceID(nsDependentSubstring(aExpatName,
53
0
                                                                    uriEnd));
54
0
        if (*aNameSpaceID == kNameSpaceID_Unknown) {
55
0
            return NS_ERROR_FAILURE;
56
0
        }
57
0
58
0
        nameStart = (uriEnd + 1);
59
0
        if (nameEnd)  {
60
0
            const char16_t *prefixStart = nameEnd + 1;
61
0
            *aPrefix = NS_Atomize(Substring(prefixStart, pos)).take();
62
0
            if (!*aPrefix) {
63
0
                return NS_ERROR_OUT_OF_MEMORY;
64
0
            }
65
0
        }
66
0
        else {
67
0
            nameEnd = pos;
68
0
            *aPrefix = nullptr;
69
0
        }
70
0
    }
71
0
    else {
72
0
        *aNameSpaceID = kNameSpaceID_None;
73
0
        nameStart = aExpatName;
74
0
        nameEnd = pos;
75
0
        *aPrefix = nullptr;
76
0
    }
77
0
78
0
    *aLocalName = NS_Atomize(Substring(nameStart, nameEnd)).take();
79
0
80
0
    return *aLocalName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
81
0
}
82
83
nsresult
84
XMLUtils::splitQName(const nsAString& aName, nsAtom** aPrefix,
85
                     nsAtom** aLocalName)
86
0
{
87
0
    const char16_t* colon;
88
0
    bool valid = XMLUtils::isValidQName(aName, &colon);
89
0
    if (!valid) {
90
0
        return NS_ERROR_FAILURE;
91
0
    }
92
0
93
0
    if (colon) {
94
0
        const char16_t *end;
95
0
        aName.EndReading(end);
96
0
97
0
        *aPrefix = NS_Atomize(Substring(aName.BeginReading(), colon)).take();
98
0
        *aLocalName = NS_Atomize(Substring(colon + 1, end)).take();
99
0
    }
100
0
    else {
101
0
        *aPrefix = nullptr;
102
0
        *aLocalName = NS_Atomize(aName).take();
103
0
    }
104
0
105
0
    return NS_OK;
106
0
}
107
108
/**
109
 * Returns true if the given string has only whitespace characters
110
 */
111
bool XMLUtils::isWhitespace(const nsAString& aText)
112
0
{
113
0
    nsString::const_char_iterator start, end;
114
0
    aText.BeginReading(start);
115
0
    aText.EndReading(end);
116
0
    for ( ; start != end; ++start) {
117
0
        if (!isWhitespace(*start)) {
118
0
            return false;
119
0
        }
120
0
    }
121
0
    return true;
122
0
}
123
124
/**
125
 * Normalizes the value of a XML processing instruction
126
**/
127
void XMLUtils::normalizePIValue(nsAString& piValue)
128
0
{
129
0
    nsAutoString origValue(piValue);
130
0
    uint32_t origLength = origValue.Length();
131
0
    uint32_t conversionLoop = 0;
132
0
    char16_t prevCh = 0;
133
0
    piValue.Truncate();
134
0
135
0
    while (conversionLoop < origLength) {
136
0
        char16_t ch = origValue.CharAt(conversionLoop);
137
0
        switch (ch) {
138
0
            case '>':
139
0
            {
140
0
                if (prevCh == '?') {
141
0
                    piValue.Append(char16_t(' '));
142
0
                }
143
0
                break;
144
0
            }
145
0
            default:
146
0
            {
147
0
                break;
148
0
            }
149
0
        }
150
0
        piValue.Append(ch);
151
0
        prevCh = ch;
152
0
        ++conversionLoop;
153
0
    }
154
0
}
155
156
//static
157
bool XMLUtils::isValidQName(const nsAString& aQName, const char16_t** aColon)
158
0
{
159
0
  return NS_SUCCEEDED(nsContentUtils::CheckQName(aQName, true, aColon));
160
0
}
161
162
//static
163
bool XMLUtils::getXMLSpacePreserve(const txXPathNode& aNode)
164
0
{
165
0
    nsAutoString value;
166
0
    txXPathTreeWalker walker(aNode);
167
0
    do {
168
0
        if (walker.getAttr(nsGkAtoms::space, kNameSpaceID_XML, value)) {
169
0
            if (TX_StringEqualsAtom(value, nsGkAtoms::preserve)) {
170
0
                return true;
171
0
            }
172
0
            if (TX_StringEqualsAtom(value, nsGkAtoms::_default)) {
173
0
                return false;
174
0
            }
175
0
        }
176
0
    } while (walker.moveToParent());
177
0
178
0
    return false;
179
0
}