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

mercurial