Back to index

lightning-sunbird  0.9+nobinonly
nsP3PUtils.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Platform for Privacy Preferences.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s): Harish Dhurvasula <harishd@netscape.com>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsP3PUtils.h"
00039 #include "nsIDOMAttr.h"
00040 #include "nsIDOMNamedNodeMap.h"
00041 #include "nsIDOMNodeList.h"
00042 #include "nsReadableUtils.h"
00043 
00044 nsresult
00045 nsP3PUtils::GetAttributeValue(nsIDOMNode* aNode, 
00046                               char* aAttrName, 
00047                               nsAString& aAttrValue) 
00048 {
00049   NS_ENSURE_ARG_POINTER(aNode);
00050   NS_ENSURE_ARG_POINTER(aAttrName);
00051 
00052   aAttrValue.Truncate();
00053 
00054   nsCOMPtr<nsIDOMNamedNodeMap> attributeNodes;
00055   aNode->GetAttributes(getter_AddRefs(attributeNodes));
00056   NS_ENSURE_TRUE(attributeNodes, NS_ERROR_UNEXPECTED);
00057 
00058   nsCOMPtr<nsIDOMNode> attributeNode;
00059   nsCOMPtr<nsIDOMAttr> domAttr;
00060   PRUint32             attrCount;
00061   nsAutoString         name;
00062 
00063   attributeNodes->GetLength(&attrCount);
00064   
00065   PRUint32 i;
00066   for (i = 0; i < attrCount; i++) {
00067     attributeNodes->Item(i, getter_AddRefs(attributeNode));
00068     NS_ENSURE_TRUE(attributeNode, NS_ERROR_UNEXPECTED);
00069          
00070     attributeNode->GetLocalName(name);
00071     if (!name.IsEmpty() && name.EqualsIgnoreCase(aAttrName)) {
00072       domAttr = do_QueryInterface(attributeNode);
00073       NS_ENSURE_TRUE(domAttr, NS_ERROR_UNEXPECTED);
00074       return domAttr->GetValue(aAttrValue);
00075     }
00076   }
00077 
00078   return NS_OK;
00079 }
00080 
00081 static PRBool
00082 IsCharInSet(const char* aSet,
00083             const PRUnichar aChar)
00084 {
00085   PRUnichar ch;
00086   while ((ch = *aSet)) {
00087     if (aChar == PRUnichar(ch)) {
00088       return PR_TRUE;
00089     }
00090     ++aSet;
00091   }
00092   return PR_FALSE;
00093 }
00094 
00098 const nsDependentSubstring
00099 nsP3PUtils::TrimCharsInSet(const char* aSet,
00100                            const nsAString& aValue)
00101 {
00102   nsAString::const_iterator valueCurrent, valueEnd;
00103 
00104   aValue.BeginReading(valueCurrent);
00105   aValue.EndReading(valueEnd);
00106 
00107   // Skip charaters in the beginning
00108   while (valueCurrent != valueEnd) {
00109     if (!IsCharInSet(aSet, *valueCurrent)) {
00110       break;
00111     }
00112     ++valueCurrent;
00113   }
00114 
00115   if (valueCurrent != valueEnd) {
00116     for (;;) {
00117       --valueEnd;
00118       if (!IsCharInSet(aSet, *valueEnd)) {
00119         break;
00120       }
00121     }
00122     ++valueEnd; // Step beyond the last character we want in the value.
00123   }
00124 
00125   // valueEnd should point to the char after the last to copy
00126   return Substring(valueCurrent, valueEnd);
00127 }
00128 
00146 PRBool 
00147 nsP3PUtils::IsPathIncluded(const nsAString& aLhs, 
00148                            const nsAString& aRhs) 
00149 {
00150   nsAString::const_iterator lhs_begin, lhs_end;
00151   nsAString::const_iterator rhs_begin, rhs_end;
00152  
00153   aLhs.BeginReading(lhs_begin);
00154   aLhs.EndReading(lhs_end);
00155   aRhs.BeginReading(rhs_begin);
00156   aRhs.EndReading(rhs_end);
00157 
00158   nsAutoString pattern;
00159   PRBool pattern_before_asterisk = PR_TRUE; 
00160   nsAString::const_iterator curr_posn = lhs_begin;
00161   while (curr_posn != lhs_end) {
00162     if (*lhs_begin == '*') {
00163       pattern_before_asterisk = PR_FALSE;
00164       ++lhs_begin; // Do this to not include '*' when pattern matching.
00165     }
00166     else if (pattern_before_asterisk) {
00167       // Match character by character to see if lhs and rhs are identical
00168       if (*curr_posn != *rhs_begin) {
00169         return PR_FALSE;
00170       }
00171       ++lhs_begin;
00172       ++curr_posn;
00173       ++rhs_begin;
00174       if (rhs_begin == rhs_end &&
00175           curr_posn == lhs_end) {
00176         return PR_TRUE; // lhs and rhs matched perfectly
00177       }
00178     }
00179     else if (++curr_posn == lhs_end) {
00180       if (curr_posn != lhs_begin) {
00181         // Here we're matching the last few characters to make sure
00182         // that lhs is actually equal to rhs. Ex. "a*c" != "abcd"
00183         PRBool done;
00184         for (;;) {
00185           --curr_posn;
00186           done = (--rhs_end == rhs_begin) || (curr_posn == lhs_begin);
00187           if (*rhs_end != *curr_posn) {
00188             return PR_FALSE;
00189           }
00190           if (done) {
00191             return PR_TRUE;
00192           }
00193         }
00194       }
00195       // No discrepency between lhs and rhs
00196       return PR_TRUE;
00197     }
00198     else if (*curr_posn == '*') {
00199       // Matching pattern between asterisks. That is, in "h*ll*" we
00200       // check to see if "ll" exists in the rhs string.
00201       nsAString::const_iterator tmp_end = rhs_end;
00202       CopyUnicodeTo(lhs_begin, curr_posn, pattern);
00203       if (!FindInReadable(pattern, rhs_begin, rhs_end)) 
00204          return PR_FALSE;
00205       rhs_begin = rhs_end;
00206       rhs_end   = tmp_end;
00207       lhs_begin = curr_posn;
00208     }
00209   }
00210 
00211   return PR_FALSE;
00212 }
00213 
00214 nsresult
00215 nsP3PUtils::DeterminePolicyScope(const nsVoidArray& aNodeList, 
00216                                  const char* aPath, 
00217                                  PRBool* aOut)
00218 {
00219 
00220   NS_ENSURE_ARG_POINTER(aPath);
00221   NS_ENSURE_ARG_POINTER(aOut);
00222 
00223   *aOut = PR_FALSE;
00224   PRInt32 count = aNodeList.Count();
00225 
00226   nsAutoString value;
00227   nsCOMPtr<nsIDOMNode> node, child;
00228   PRInt32 i;
00229   for (i = 0; i < count && !(*aOut); i++) {
00230     nsIDOMNode* node = NS_REINTERPRET_CAST(nsIDOMNode*, aNodeList.ElementAt(i));
00231     NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
00232 
00233     node->GetFirstChild(getter_AddRefs(child));
00234     NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED);
00235 
00236     child->GetNodeValue(value);
00237     static const char* kWhitespace = " \n\r\t\b";
00238     value = TrimCharsInSet(kWhitespace, value);
00239     *aOut = IsPathIncluded(value, NS_ConvertUTF8toUCS2(aPath));
00240   }
00241 
00242   return NS_OK;
00243 }
00244 
00249 nsresult 
00250 nsP3PUtils::GetElementsByTagName(nsIDOMNode* aNode, 
00251                                  const nsAString& aTagName, 
00252                                  nsVoidArray& aReturn)
00253 {
00254   NS_ENSURE_ARG_POINTER(aNode);
00255     
00256   CleanArray(aReturn);
00257   
00258   nsCOMPtr<nsIDOMNodeList> children;
00259   aNode->GetChildNodes(getter_AddRefs(children));
00260   NS_ENSURE_TRUE(children, NS_ERROR_UNEXPECTED);
00261 
00262   PRUint32 count;
00263   children->GetLength(&count);
00264 
00265   nsAutoString name;
00266   nsIDOMNode* node;
00267   PRUint32 i;
00268   for (i = 0; i < count; i++) {
00269     children->Item(i, &node);
00270     NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
00271     
00272     PRUint16 type;
00273     node->GetNodeType(&type);
00274 
00275     if (type == nsIDOMNode::ELEMENT_NODE) {
00276       node->GetNodeName(name);
00277       if (aTagName.Equals(name)) {
00278         NS_IF_ADDREF(node);
00279         aReturn.AppendElement((void*)node);
00280       }
00281     }
00282   }
00283 
00284   return NS_OK;
00285 }
00286 
00287 void
00288 nsP3PUtils::CleanArray(nsVoidArray& aArray)
00289 {
00290   PRInt32 count = aArray.Count();
00291   nsCOMPtr<nsIDOMNode> node;
00292   while (count) {
00293     nsIDOMNode* node =
00294       NS_REINTERPRET_CAST(nsIDOMNode*, aArray.ElementAt(--count));
00295     aArray.RemoveElementAt(count);
00296     NS_IF_RELEASE(node);
00297   }
00298 }