1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/xslt/xml/txXMLUtils.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,211 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * XML utility classes 1.11 + */ 1.12 + 1.13 +#include "txXMLUtils.h" 1.14 +#include "nsString.h" 1.15 +#include "nsReadableUtils.h" 1.16 +#include "nsGkAtoms.h" 1.17 +#include "txStringUtils.h" 1.18 +#include "txNamespaceMap.h" 1.19 +#include "txXPathTreeWalker.h" 1.20 +#include "nsContentUtils.h" 1.21 + 1.22 +nsresult 1.23 +txExpandedName::init(const nsAString& aQName, txNamespaceMap* aResolver, 1.24 + bool aUseDefault) 1.25 +{ 1.26 + const nsAFlatString& qName = PromiseFlatString(aQName); 1.27 + const char16_t* colon; 1.28 + bool valid = XMLUtils::isValidQName(qName, &colon); 1.29 + if (!valid) { 1.30 + return NS_ERROR_FAILURE; 1.31 + } 1.32 + 1.33 + if (colon) { 1.34 + nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon)); 1.35 + int32_t namespaceID = aResolver->lookupNamespace(prefix); 1.36 + if (namespaceID == kNameSpaceID_Unknown) 1.37 + return NS_ERROR_FAILURE; 1.38 + mNamespaceID = namespaceID; 1.39 + 1.40 + const char16_t *end; 1.41 + qName.EndReading(end); 1.42 + mLocalName = do_GetAtom(Substring(colon + 1, end)); 1.43 + } 1.44 + else { 1.45 + mNamespaceID = aUseDefault ? aResolver->lookupNamespace(nullptr) : 1.46 + kNameSpaceID_None; 1.47 + mLocalName = do_GetAtom(aQName); 1.48 + } 1.49 + return NS_OK; 1.50 +} 1.51 + 1.52 + //------------------------------/ 1.53 + //- Implementation of XMLUtils -/ 1.54 +//------------------------------/ 1.55 + 1.56 +// static 1.57 +nsresult 1.58 +XMLUtils::splitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix, 1.59 + nsIAtom **aLocalName, int32_t* aNameSpaceID) 1.60 +{ 1.61 + /** 1.62 + * Expat can send the following: 1.63 + * localName 1.64 + * namespaceURI<separator>localName 1.65 + * namespaceURI<separator>localName<separator>prefix 1.66 + */ 1.67 + 1.68 + const char16_t *uriEnd = nullptr; 1.69 + const char16_t *nameEnd = nullptr; 1.70 + const char16_t *pos; 1.71 + for (pos = aExpatName; *pos; ++pos) { 1.72 + if (*pos == kExpatSeparatorChar) { 1.73 + if (uriEnd) { 1.74 + nameEnd = pos; 1.75 + } 1.76 + else { 1.77 + uriEnd = pos; 1.78 + } 1.79 + } 1.80 + } 1.81 + 1.82 + const char16_t *nameStart; 1.83 + if (uriEnd) { 1.84 + *aNameSpaceID = 1.85 + txNamespaceManager::getNamespaceID(nsDependentSubstring(aExpatName, 1.86 + uriEnd)); 1.87 + if (*aNameSpaceID == kNameSpaceID_Unknown) { 1.88 + return NS_ERROR_FAILURE; 1.89 + } 1.90 + 1.91 + nameStart = (uriEnd + 1); 1.92 + if (nameEnd) { 1.93 + const char16_t *prefixStart = nameEnd + 1; 1.94 + *aPrefix = NS_NewAtom(Substring(prefixStart, pos)).take(); 1.95 + if (!*aPrefix) { 1.96 + return NS_ERROR_OUT_OF_MEMORY; 1.97 + } 1.98 + } 1.99 + else { 1.100 + nameEnd = pos; 1.101 + *aPrefix = nullptr; 1.102 + } 1.103 + } 1.104 + else { 1.105 + *aNameSpaceID = kNameSpaceID_None; 1.106 + nameStart = aExpatName; 1.107 + nameEnd = pos; 1.108 + *aPrefix = nullptr; 1.109 + } 1.110 + 1.111 + *aLocalName = NS_NewAtom(Substring(nameStart, nameEnd)).take(); 1.112 + 1.113 + return *aLocalName ? NS_OK : NS_ERROR_OUT_OF_MEMORY; 1.114 +} 1.115 + 1.116 +nsresult 1.117 +XMLUtils::splitQName(const nsAString& aName, nsIAtom** aPrefix, 1.118 + nsIAtom** aLocalName) 1.119 +{ 1.120 + const nsAFlatString& qName = PromiseFlatString(aName); 1.121 + const char16_t* colon; 1.122 + bool valid = XMLUtils::isValidQName(qName, &colon); 1.123 + if (!valid) { 1.124 + return NS_ERROR_FAILURE; 1.125 + } 1.126 + 1.127 + if (colon) { 1.128 + const char16_t *end; 1.129 + qName.EndReading(end); 1.130 + 1.131 + *aPrefix = NS_NewAtom(Substring(qName.get(), colon)).take(); 1.132 + *aLocalName = NS_NewAtom(Substring(colon + 1, end)).take(); 1.133 + } 1.134 + else { 1.135 + *aPrefix = nullptr; 1.136 + *aLocalName = NS_NewAtom(aName).take(); 1.137 + } 1.138 + 1.139 + return NS_OK; 1.140 +} 1.141 + 1.142 +/** 1.143 + * Returns true if the given string has only whitespace characters 1.144 + */ 1.145 +bool XMLUtils::isWhitespace(const nsAFlatString& aText) 1.146 +{ 1.147 + nsAFlatString::const_char_iterator start, end; 1.148 + aText.BeginReading(start); 1.149 + aText.EndReading(end); 1.150 + for ( ; start != end; ++start) { 1.151 + if (!isWhitespace(*start)) { 1.152 + return false; 1.153 + } 1.154 + } 1.155 + return true; 1.156 +} 1.157 + 1.158 +/** 1.159 + * Normalizes the value of a XML processing instruction 1.160 +**/ 1.161 +void XMLUtils::normalizePIValue(nsAString& piValue) 1.162 +{ 1.163 + nsAutoString origValue(piValue); 1.164 + uint32_t origLength = origValue.Length(); 1.165 + uint32_t conversionLoop = 0; 1.166 + char16_t prevCh = 0; 1.167 + piValue.Truncate(); 1.168 + 1.169 + while (conversionLoop < origLength) { 1.170 + char16_t ch = origValue.CharAt(conversionLoop); 1.171 + switch (ch) { 1.172 + case '>': 1.173 + { 1.174 + if (prevCh == '?') { 1.175 + piValue.Append(char16_t(' ')); 1.176 + } 1.177 + break; 1.178 + } 1.179 + default: 1.180 + { 1.181 + break; 1.182 + } 1.183 + } 1.184 + piValue.Append(ch); 1.185 + prevCh = ch; 1.186 + ++conversionLoop; 1.187 + } 1.188 +} 1.189 + 1.190 +//static 1.191 +bool XMLUtils::isValidQName(const nsAFlatString& aQName, 1.192 + const char16_t** aColon) 1.193 +{ 1.194 + return NS_SUCCEEDED(nsContentUtils::CheckQName(aQName, true, aColon)); 1.195 +} 1.196 + 1.197 +//static 1.198 +bool XMLUtils::getXMLSpacePreserve(const txXPathNode& aNode) 1.199 +{ 1.200 + nsAutoString value; 1.201 + txXPathTreeWalker walker(aNode); 1.202 + do { 1.203 + if (walker.getAttr(nsGkAtoms::space, kNameSpaceID_XML, value)) { 1.204 + if (TX_StringEqualsAtom(value, nsGkAtoms::preserve)) { 1.205 + return true; 1.206 + } 1.207 + if (TX_StringEqualsAtom(value, nsGkAtoms::_default)) { 1.208 + return false; 1.209 + } 1.210 + } 1.211 + } while (walker.moveToParent()); 1.212 + 1.213 + return false; 1.214 +}