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.

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

mercurial