LCOV - code coverage report
Current view: top level - intl/strres - nsStringBundleTextOverride.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 10 85 11.8 %
Date: 2017-07-14 16:53:18 Functions: 3 24 12.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "nsStringBundleTextOverride.h"
       8             : #include "nsString.h"
       9             : 
      10             : #include "nsNetUtil.h"
      11             : #include "nsAppDirectoryServiceDefs.h"
      12             : #include "nsContentUtils.h"
      13             : #include "nsDirectoryServiceUtils.h"
      14             : 
      15             : // first we need a simple class which wraps a nsIPropertyElement and
      16             : // cuts out the leading URL from the key
      17             : class URLPropertyElement : public nsIPropertyElement
      18             : {
      19             : public:
      20           0 :     URLPropertyElement(nsIPropertyElement *aRealElement, uint32_t aURLLength) :
      21             :         mRealElement(aRealElement),
      22           0 :         mURLLength(aURLLength)
      23           0 :     { }
      24             : 
      25             :     NS_DECL_ISUPPORTS
      26             :     NS_DECL_NSIPROPERTYELEMENT
      27             : 
      28             : private:
      29             :     nsCOMPtr<nsIPropertyElement> mRealElement;
      30             :     uint32_t mURLLength;
      31             : 
      32           0 :     virtual ~URLPropertyElement() {}
      33             : };
      34             : 
      35           0 : NS_IMPL_ISUPPORTS(URLPropertyElement, nsIPropertyElement)
      36             : 
      37             : // we'll tweak the key on the way through, and remove the url prefix
      38             : NS_IMETHODIMP
      39           0 : URLPropertyElement::GetKey(nsACString& aKey)
      40             : {
      41           0 :     nsresult rv =  mRealElement->GetKey(aKey);
      42           0 :     if (NS_FAILED(rv)) return rv;
      43             : 
      44             :     // chop off the url
      45           0 :     aKey.Cut(0, mURLLength);
      46             : 
      47           0 :     return NS_OK;
      48             : }
      49             : 
      50             : // values are unaffected
      51             : NS_IMETHODIMP
      52           0 : URLPropertyElement::GetValue(nsAString& aValue)
      53             : {
      54           0 :     return mRealElement->GetValue(aValue);
      55             : }
      56             : 
      57             : // setters are kind of strange, hopefully we'll never be called
      58             : NS_IMETHODIMP
      59           0 : URLPropertyElement::SetKey(const nsACString& aKey)
      60             : {
      61             :     // this is just wrong - ideally you'd take the key, append it to
      62             :     // the url, and set that as the key. However, that would require
      63             :     // us to hold onto a copy of the string, and that's a waste,
      64             :     // considering nobody should ever be calling this.
      65           0 :     NS_ERROR("This makes no sense!");
      66           0 :     return NS_ERROR_NOT_IMPLEMENTED;
      67             : }
      68             : 
      69             : NS_IMETHODIMP
      70           0 : URLPropertyElement::SetValue(const nsAString& aValue)
      71             : {
      72           0 :     return mRealElement->SetValue(aValue);
      73             : }
      74             : 
      75             : 
      76             : // this is a special enumerator which returns only the elements which
      77             : // are prefixed with a particular url
      78             : class nsPropertyEnumeratorByURL : public nsISimpleEnumerator
      79             : {
      80             : public:
      81           0 :     nsPropertyEnumeratorByURL(const nsACString& aURL,
      82           0 :                               nsISimpleEnumerator* aOuter) :
      83             :         mOuter(aOuter),
      84           0 :         mURL(aURL)
      85             :     {
      86             :         // prepare the url once so we can use its value later
      87             :         // persistent properties uses ":" as a delimiter, so escape
      88             :         // that character
      89           0 :         mURL.ReplaceSubstring(":", "%3A");
      90             :         // there is always a # between the url and the real key
      91           0 :         mURL.Append('#');
      92           0 :     }
      93             : 
      94             :     NS_DECL_ISUPPORTS
      95             :     NS_DECL_NSISIMPLEENUMERATOR
      96             : 
      97             : private:
      98             : 
      99             :     // actual enumerator of all strings from nsIProperties
     100             :     nsCOMPtr<nsISimpleEnumerator> mOuter;
     101             : 
     102             :     // the current element that is valid for this url
     103             :     nsCOMPtr<nsIPropertyElement> mCurrent;
     104             : 
     105             :     // the url in question, pre-escaped and with the # already in it
     106             :     nsCString mURL;
     107             : 
     108           0 :     virtual ~nsPropertyEnumeratorByURL() {}
     109             : };
     110             : 
     111             : //
     112             : // nsStringBundleTextOverride implementation
     113             : //
     114           6 : NS_IMPL_ISUPPORTS(nsStringBundleTextOverride,
     115             :                   nsIStringBundleOverride)
     116             : 
     117             : nsresult
     118           3 : nsStringBundleTextOverride::Init()
     119             : {
     120             :     nsresult rv;
     121             : 
     122             :     // check for existence of custom-strings.txt
     123             : 
     124           6 :     nsCOMPtr<nsIFile> customStringsFile;
     125           3 :     rv = NS_GetSpecialDirectory(NS_APP_CHROME_DIR,
     126           6 :                                 getter_AddRefs(customStringsFile));
     127             : 
     128           3 :     if (NS_FAILED(rv)) return rv;
     129             : 
     130             :     // bail if not found - this will cause the service creation to
     131             :     // bail as well, and cause this object to go away
     132             : 
     133           3 :     customStringsFile->AppendNative(NS_LITERAL_CSTRING("custom-strings.txt"));
     134             : 
     135             :     bool exists;
     136           3 :     rv = customStringsFile->Exists(&exists);
     137           3 :     if (NS_FAILED(rv) || !exists)
     138           3 :         return NS_ERROR_FAILURE;
     139             : 
     140           0 :     NS_WARNING("Using custom-strings.txt to override string bundles.");
     141             :     // read in the custom bundle. Keys are in the form
     142             :     // chrome://package/locale/foo.properties:keyname
     143             : 
     144           0 :     nsAutoCString customStringsURLSpec;
     145           0 :     rv = NS_GetURLSpecFromFile(customStringsFile, customStringsURLSpec);
     146           0 :     if (NS_FAILED(rv)) return rv;
     147             : 
     148           0 :     nsCOMPtr<nsIURI> uri;
     149           0 :     rv = NS_NewURI(getter_AddRefs(uri), customStringsURLSpec);
     150           0 :     NS_ENSURE_SUCCESS(rv, rv);
     151             : 
     152           0 :     nsCOMPtr<nsIChannel> channel;
     153           0 :     rv = NS_NewChannel(getter_AddRefs(channel),
     154             :                        uri,
     155             :                        nsContentUtils::GetSystemPrincipal(),
     156             :                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
     157             :                        nsIContentPolicy::TYPE_OTHER);
     158             : 
     159           0 :     NS_ENSURE_SUCCESS(rv, rv);
     160           0 :     nsCOMPtr<nsIInputStream> in;
     161           0 :     rv = channel->Open2(getter_AddRefs(in));
     162           0 :     NS_ENSURE_SUCCESS(rv, rv);
     163             : 
     164             :     static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
     165           0 :     mValues = do_CreateInstance(kPersistentPropertiesCID, &rv);
     166           0 :     if (NS_FAILED(rv)) return rv;
     167             : 
     168           0 :     rv = mValues->Load(in);
     169             : 
     170             :     // turn this on to see the contents of custom-strings.txt
     171             : #ifdef DEBUG_alecf
     172             :     nsCOMPtr<nsISimpleEnumerator> enumerator;
     173             :     mValues->Enumerate(getter_AddRefs(enumerator));
     174             :     NS_ASSERTION(enumerator, "no enumerator!\n");
     175             : 
     176             :     printf("custom-strings.txt contains:\n");
     177             :     printf("----------------------------\n");
     178             : 
     179             :     bool hasMore;
     180             :     enumerator->HasMoreElements(&hasMore);
     181             :     do {
     182             :         nsCOMPtr<nsISupports> sup;
     183             :         enumerator->GetNext(getter_AddRefs(sup));
     184             : 
     185             :         nsCOMPtr<nsIPropertyElement> prop = do_QueryInterface(sup);
     186             : 
     187             :         nsAutoCString key;
     188             :         nsAutoString value;
     189             :         prop->GetKey(key);
     190             :         prop->GetValue(value);
     191             : 
     192             :         printf("%s = '%s'\n", key.get(), NS_ConvertUTF16toUTF8(value).get());
     193             : 
     194             :         enumerator->HasMoreElements(&hasMore);
     195             :     } while (hasMore);
     196             : #endif
     197             : 
     198           0 :     return rv;
     199             : }
     200             : 
     201             : NS_IMETHODIMP
     202           0 : nsStringBundleTextOverride::GetStringFromName(const nsACString& aURL,
     203             :                                               const nsACString& key,
     204             :                                               nsAString& aResult)
     205             : {
     206             :     // concatenate url#key to get the key to read
     207           0 :     nsAutoCString combinedURL(aURL + NS_LITERAL_CSTRING("#") + key);
     208             : 
     209             :     // persistent properties uses ":" as a delimiter, so escape that character
     210           0 :     combinedURL.ReplaceSubstring(":", "%3A");
     211             : 
     212           0 :     return mValues->GetStringProperty(combinedURL, aResult);
     213             : }
     214             : 
     215             : NS_IMETHODIMP
     216           0 : nsStringBundleTextOverride::EnumerateKeysInBundle(const nsACString& aURL,
     217             :                                                   nsISimpleEnumerator** aResult)
     218             : {
     219             :     // enumerate all strings, and let the enumerator know
     220           0 :     nsCOMPtr<nsISimpleEnumerator> enumerator;
     221           0 :     mValues->Enumerate(getter_AddRefs(enumerator));
     222             : 
     223             :     // make the enumerator wrapper and pass it off
     224             :     nsPropertyEnumeratorByURL* propEnum =
     225           0 :         new nsPropertyEnumeratorByURL(aURL, enumerator);
     226             : 
     227           0 :     if (!propEnum) return NS_ERROR_OUT_OF_MEMORY;
     228             : 
     229           0 :     NS_ADDREF(*aResult = propEnum);
     230             : 
     231           0 :     return NS_OK;
     232             : }
     233             : 
     234             : 
     235             : //
     236             : // nsPropertyEnumeratorByURL implementation
     237             : //
     238             : 
     239             : 
     240           0 : NS_IMPL_ISUPPORTS(nsPropertyEnumeratorByURL, nsISimpleEnumerator)
     241             : 
     242             : NS_IMETHODIMP
     243           0 : nsPropertyEnumeratorByURL::GetNext(nsISupports **aResult)
     244             : {
     245           0 :     if (!mCurrent) return NS_ERROR_UNEXPECTED;
     246             : 
     247             :     // wrap mCurrent instead of returning it
     248           0 :     *aResult = new URLPropertyElement(mCurrent, mURL.Length());
     249           0 :     NS_ADDREF(*aResult);
     250             : 
     251             :     // release it so we don't return it twice
     252           0 :     mCurrent = nullptr;
     253             : 
     254           0 :     return NS_OK;
     255             : }
     256             : 
     257             : NS_IMETHODIMP
     258           0 : nsPropertyEnumeratorByURL::HasMoreElements(bool * aResult)
     259             : {
     260             :     bool hasMore;
     261           0 :     mOuter->HasMoreElements(&hasMore);
     262           0 :     while (hasMore) {
     263             : 
     264           0 :         nsCOMPtr<nsISupports> supports;
     265           0 :         mOuter->GetNext(getter_AddRefs(supports));
     266             : 
     267           0 :         mCurrent = do_QueryInterface(supports);
     268             : 
     269           0 :         if (mCurrent) {
     270           0 :             nsAutoCString curKey;
     271           0 :             mCurrent->GetKey(curKey);
     272             : 
     273           0 :             if (StringBeginsWith(curKey, mURL))
     274           0 :                 break;
     275             :         }
     276             : 
     277           0 :         mOuter->HasMoreElements(&hasMore);
     278             :     }
     279             : 
     280           0 :     if (!hasMore)
     281           0 :         mCurrent = nullptr;
     282             : 
     283           0 :     *aResult = mCurrent ? true : false;
     284             : 
     285           0 :     return NS_OK;
     286             : }

Generated by: LCOV version 1.13