Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / xslt / xml / txXMLUtils.cpp
blob0688939ccb257c42d609e15a9bb495af540d92b1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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/. */
6 /*
7 * XML utility classes
8 */
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"
19 //------------------------------/
20 //- Implementation of XMLUtils -/
21 //------------------------------/
23 // static
24 nsresult XMLUtils::splitExpatName(const char16_t* aExpatName, nsAtom** aPrefix,
25 nsAtom** aLocalName, int32_t* aNameSpaceID) {
26 /**
27 * Expat can send the following:
28 * localName
29 * namespaceURI<separator>localName
30 * namespaceURI<separator>localName<separator>prefix
33 const char16_t* uriEnd = nullptr;
34 const char16_t* nameEnd = nullptr;
35 const char16_t* pos;
36 for (pos = aExpatName; *pos; ++pos) {
37 if (*pos == kExpatSeparatorChar) {
38 if (uriEnd) {
39 nameEnd = pos;
40 } else {
41 uriEnd = pos;
46 const char16_t* nameStart;
47 if (uriEnd) {
48 *aNameSpaceID = txNamespaceManager::getNamespaceID(
49 nsDependentSubstring(aExpatName, uriEnd));
50 if (*aNameSpaceID == kNameSpaceID_Unknown) {
51 return NS_ERROR_FAILURE;
54 nameStart = (uriEnd + 1);
55 if (nameEnd) {
56 const char16_t* prefixStart = nameEnd + 1;
57 *aPrefix = NS_Atomize(Substring(prefixStart, pos)).take();
58 if (!*aPrefix) {
59 return NS_ERROR_OUT_OF_MEMORY;
61 } else {
62 nameEnd = pos;
63 *aPrefix = nullptr;
65 } else {
66 *aNameSpaceID = kNameSpaceID_None;
67 nameStart = aExpatName;
68 nameEnd = pos;
69 *aPrefix = nullptr;
72 *aLocalName = NS_Atomize(Substring(nameStart, nameEnd)).take();
74 return *aLocalName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
77 nsresult XMLUtils::splitQName(const nsAString& aName, nsAtom** aPrefix,
78 nsAtom** aLocalName) {
79 const char16_t* colon;
80 bool valid = XMLUtils::isValidQName(aName, &colon);
81 if (!valid) {
82 return NS_ERROR_FAILURE;
85 if (colon) {
86 const char16_t* end;
87 aName.EndReading(end);
89 *aPrefix = NS_Atomize(Substring(aName.BeginReading(), colon)).take();
90 *aLocalName = NS_Atomize(Substring(colon + 1, end)).take();
91 } else {
92 *aPrefix = nullptr;
93 *aLocalName = NS_Atomize(aName).take();
96 return NS_OK;
99 /**
100 * Returns true if the given string has only whitespace characters
102 bool XMLUtils::isWhitespace(const nsAString& aText) {
103 nsString::const_char_iterator start, end;
104 aText.BeginReading(start);
105 aText.EndReading(end);
106 for (; start != end; ++start) {
107 if (!isWhitespace(*start)) {
108 return false;
111 return true;
115 * Normalizes the value of a XML processing instruction
117 void XMLUtils::normalizePIValue(nsAString& piValue) {
118 nsAutoString origValue(piValue);
119 uint32_t origLength = origValue.Length();
120 uint32_t conversionLoop = 0;
121 char16_t prevCh = 0;
122 piValue.Truncate();
124 while (conversionLoop < origLength) {
125 char16_t ch = origValue.CharAt(conversionLoop);
126 switch (ch) {
127 case '>': {
128 if (prevCh == '?') {
129 piValue.Append(char16_t(' '));
131 break;
133 default: {
134 break;
137 piValue.Append(ch);
138 prevCh = ch;
139 ++conversionLoop;
143 // static
144 bool XMLUtils::isValidQName(const nsAString& aQName, const char16_t** aColon) {
145 return NS_SUCCEEDED(nsContentUtils::CheckQName(aQName, true, aColon));
148 // static
149 bool XMLUtils::getXMLSpacePreserve(const txXPathNode& aNode) {
150 nsAutoString value;
151 txXPathTreeWalker walker(aNode);
152 do {
153 if (walker.getAttr(nsGkAtoms::space, kNameSpaceID_XML, value)) {
154 if (TX_StringEqualsAtom(value, nsGkAtoms::preserve)) {
155 return true;
157 if (TX_StringEqualsAtom(value, nsGkAtoms::_default)) {
158 return false;
161 } while (walker.moveToParent());
163 return false;