dom/xslt/xml/txXMLUtils.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     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 nsresult
    20 txExpandedName::init(const nsAString& aQName, txNamespaceMap* aResolver,
    21                      bool aUseDefault)
    22 {
    23     const nsAFlatString& qName = PromiseFlatString(aQName);
    24     const char16_t* colon;
    25     bool valid = XMLUtils::isValidQName(qName, &colon);
    26     if (!valid) {
    27         return NS_ERROR_FAILURE;
    28     }
    30     if (colon) {
    31         nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon));
    32         int32_t namespaceID = aResolver->lookupNamespace(prefix);
    33         if (namespaceID == kNameSpaceID_Unknown)
    34             return NS_ERROR_FAILURE;
    35         mNamespaceID = namespaceID;
    37         const char16_t *end;
    38         qName.EndReading(end);
    39         mLocalName = do_GetAtom(Substring(colon + 1, end));
    40     }
    41     else {
    42         mNamespaceID = aUseDefault ? aResolver->lookupNamespace(nullptr) :
    43                                      kNameSpaceID_None;
    44         mLocalName = do_GetAtom(aQName);
    45     }
    46     return NS_OK;
    47 }
    49   //------------------------------/
    50  //- Implementation of XMLUtils -/
    51 //------------------------------/
    53 // static
    54 nsresult
    55 XMLUtils::splitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix,
    56                          nsIAtom **aLocalName, int32_t* aNameSpaceID)
    57 {
    58     /**
    59      *  Expat can send the following:
    60      *    localName
    61      *    namespaceURI<separator>localName
    62      *    namespaceURI<separator>localName<separator>prefix
    63      */
    65     const char16_t *uriEnd = nullptr;
    66     const char16_t *nameEnd = nullptr;
    67     const char16_t *pos;
    68     for (pos = aExpatName; *pos; ++pos) {
    69         if (*pos == kExpatSeparatorChar) {
    70             if (uriEnd) {
    71                 nameEnd = pos;
    72             }
    73             else {
    74                 uriEnd = pos;
    75             }
    76         }
    77     }
    79     const char16_t *nameStart;
    80     if (uriEnd) {
    81         *aNameSpaceID =
    82             txNamespaceManager::getNamespaceID(nsDependentSubstring(aExpatName,
    83                                                                     uriEnd));
    84         if (*aNameSpaceID == kNameSpaceID_Unknown) {
    85             return NS_ERROR_FAILURE;
    86         }
    88         nameStart = (uriEnd + 1);
    89         if (nameEnd)  {
    90             const char16_t *prefixStart = nameEnd + 1;
    91             *aPrefix = NS_NewAtom(Substring(prefixStart, pos)).take();
    92             if (!*aPrefix) {
    93                 return NS_ERROR_OUT_OF_MEMORY;
    94             }
    95         }
    96         else {
    97             nameEnd = pos;
    98             *aPrefix = nullptr;
    99         }
   100     }
   101     else {
   102         *aNameSpaceID = kNameSpaceID_None;
   103         nameStart = aExpatName;
   104         nameEnd = pos;
   105         *aPrefix = nullptr;
   106     }
   108     *aLocalName = NS_NewAtom(Substring(nameStart, nameEnd)).take();
   110     return *aLocalName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   111 }
   113 nsresult
   114 XMLUtils::splitQName(const nsAString& aName, nsIAtom** aPrefix,
   115                      nsIAtom** aLocalName)
   116 {
   117     const nsAFlatString& qName = PromiseFlatString(aName);
   118     const char16_t* colon;
   119     bool valid = XMLUtils::isValidQName(qName, &colon);
   120     if (!valid) {
   121         return NS_ERROR_FAILURE;
   122     }
   124     if (colon) {
   125         const char16_t *end;
   126         qName.EndReading(end);
   128         *aPrefix = NS_NewAtom(Substring(qName.get(), colon)).take();
   129         *aLocalName = NS_NewAtom(Substring(colon + 1, end)).take();
   130     }
   131     else {
   132         *aPrefix = nullptr;
   133         *aLocalName = NS_NewAtom(aName).take();
   134     }
   136     return NS_OK;
   137 }
   139 /**
   140  * Returns true if the given string has only whitespace characters
   141  */
   142 bool XMLUtils::isWhitespace(const nsAFlatString& aText)
   143 {
   144     nsAFlatString::const_char_iterator start, end;
   145     aText.BeginReading(start);
   146     aText.EndReading(end);
   147     for ( ; start != end; ++start) {
   148         if (!isWhitespace(*start)) {
   149             return false;
   150         }
   151     }
   152     return true;
   153 }
   155 /**
   156  * Normalizes the value of a XML processing instruction
   157 **/
   158 void XMLUtils::normalizePIValue(nsAString& piValue)
   159 {
   160     nsAutoString origValue(piValue);
   161     uint32_t origLength = origValue.Length();
   162     uint32_t conversionLoop = 0;
   163     char16_t prevCh = 0;
   164     piValue.Truncate();
   166     while (conversionLoop < origLength) {
   167         char16_t ch = origValue.CharAt(conversionLoop);
   168         switch (ch) {
   169             case '>':
   170             {
   171                 if (prevCh == '?') {
   172                     piValue.Append(char16_t(' '));
   173                 }
   174                 break;
   175             }
   176             default:
   177             {
   178                 break;
   179             }
   180         }
   181         piValue.Append(ch);
   182         prevCh = ch;
   183         ++conversionLoop;
   184     }
   185 }
   187 //static
   188 bool XMLUtils::isValidQName(const nsAFlatString& aQName,
   189                             const char16_t** aColon)
   190 {
   191   return NS_SUCCEEDED(nsContentUtils::CheckQName(aQName, true, aColon));
   192 }
   194 //static
   195 bool XMLUtils::getXMLSpacePreserve(const txXPathNode& aNode)
   196 {
   197     nsAutoString value;
   198     txXPathTreeWalker walker(aNode);
   199     do {
   200         if (walker.getAttr(nsGkAtoms::space, kNameSpaceID_XML, value)) {
   201             if (TX_StringEqualsAtom(value, nsGkAtoms::preserve)) {
   202                 return true;
   203             }
   204             if (TX_StringEqualsAtom(value, nsGkAtoms::_default)) {
   205                 return false;
   206             }
   207         }
   208     } while (walker.moveToParent());
   210     return false;
   211 }

mercurial