intl/uconv/src/nsCharsetConverterManager.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 #include "nsCOMPtr.h"
michael@0 7 #include "nsString.h"
michael@0 8 #include "nsUnicharUtils.h"
michael@0 9 #include "nsCharsetAlias.h"
michael@0 10 #include "nsICategoryManager.h"
michael@0 11 #include "nsICharsetConverterManager.h"
michael@0 12 #include "nsEncoderDecoderUtils.h"
michael@0 13 #include "nsIStringBundle.h"
michael@0 14 #include "nsTArray.h"
michael@0 15 #include "nsStringEnumerator.h"
michael@0 16 #include "mozilla/Services.h"
michael@0 17
michael@0 18 #include "nsComponentManagerUtils.h"
michael@0 19 #include "nsISupportsPrimitives.h"
michael@0 20 #include "nsServiceManagerUtils.h"
michael@0 21
michael@0 22 // just for CONTRACTIDs
michael@0 23 #include "nsCharsetConverterManager.h"
michael@0 24
michael@0 25 static nsIStringBundle * sDataBundle;
michael@0 26 static nsIStringBundle * sTitleBundle;
michael@0 27
michael@0 28 // Class nsCharsetConverterManager [implementation]
michael@0 29
michael@0 30 NS_IMPL_ISUPPORTS(nsCharsetConverterManager, nsICharsetConverterManager)
michael@0 31
michael@0 32 nsCharsetConverterManager::nsCharsetConverterManager()
michael@0 33 {
michael@0 34 }
michael@0 35
michael@0 36 nsCharsetConverterManager::~nsCharsetConverterManager()
michael@0 37 {
michael@0 38 }
michael@0 39
michael@0 40 //static
michael@0 41 void nsCharsetConverterManager::Shutdown()
michael@0 42 {
michael@0 43 NS_IF_RELEASE(sDataBundle);
michael@0 44 NS_IF_RELEASE(sTitleBundle);
michael@0 45 }
michael@0 46
michael@0 47 static
michael@0 48 nsresult LoadExtensibleBundle(const char* aCategory,
michael@0 49 nsIStringBundle ** aResult)
michael@0 50 {
michael@0 51 nsCOMPtr<nsIStringBundleService> sbServ =
michael@0 52 mozilla::services::GetStringBundleService();
michael@0 53 if (!sbServ)
michael@0 54 return NS_ERROR_FAILURE;
michael@0 55
michael@0 56 return sbServ->CreateExtensibleBundle(aCategory, aResult);
michael@0 57 }
michael@0 58
michael@0 59 static
michael@0 60 nsresult GetBundleValue(nsIStringBundle * aBundle,
michael@0 61 const char * aName,
michael@0 62 const nsAFlatString& aProp,
michael@0 63 char16_t ** aResult)
michael@0 64 {
michael@0 65 nsAutoString key;
michael@0 66
michael@0 67 key.AssignWithConversion(aName);
michael@0 68 ToLowerCase(key); // we lowercase the main comparison key
michael@0 69 key.Append(aProp);
michael@0 70
michael@0 71 return aBundle->GetStringFromName(key.get(), aResult);
michael@0 72 }
michael@0 73
michael@0 74 static
michael@0 75 nsresult GetBundleValue(nsIStringBundle * aBundle,
michael@0 76 const char * aName,
michael@0 77 const nsAFlatString& aProp,
michael@0 78 nsAString& aResult)
michael@0 79 {
michael@0 80 nsresult rv = NS_OK;
michael@0 81
michael@0 82 nsXPIDLString value;
michael@0 83 rv = GetBundleValue(aBundle, aName, aProp, getter_Copies(value));
michael@0 84 if (NS_FAILED(rv))
michael@0 85 return rv;
michael@0 86
michael@0 87 aResult = value;
michael@0 88
michael@0 89 return NS_OK;
michael@0 90 }
michael@0 91
michael@0 92 static
michael@0 93 nsresult GetCharsetDataImpl(const char * aCharset, const char16_t * aProp,
michael@0 94 nsAString& aResult)
michael@0 95 {
michael@0 96 NS_ENSURE_ARG_POINTER(aCharset);
michael@0 97 // aProp can be nullptr
michael@0 98
michael@0 99 if (!sDataBundle) {
michael@0 100 nsresult rv = LoadExtensibleBundle(NS_DATA_BUNDLE_CATEGORY, &sDataBundle);
michael@0 101 if (NS_FAILED(rv))
michael@0 102 return rv;
michael@0 103 }
michael@0 104
michael@0 105 return GetBundleValue(sDataBundle, aCharset, nsDependentString(aProp), aResult);
michael@0 106 }
michael@0 107
michael@0 108 //static
michael@0 109 bool nsCharsetConverterManager::IsInternal(const nsACString& aCharset)
michael@0 110 {
michael@0 111 nsAutoString str;
michael@0 112 // fully qualify to possibly avoid vtable call
michael@0 113 nsresult rv = GetCharsetDataImpl(PromiseFlatCString(aCharset).get(),
michael@0 114 MOZ_UTF16(".isInternal"),
michael@0 115 str);
michael@0 116
michael@0 117 return NS_SUCCEEDED(rv);
michael@0 118 }
michael@0 119
michael@0 120
michael@0 121 //----------------------------------------------------------------------------//----------------------------------------------------------------------------
michael@0 122 // Interface nsICharsetConverterManager [implementation]
michael@0 123
michael@0 124 NS_IMETHODIMP
michael@0 125 nsCharsetConverterManager::GetUnicodeEncoder(const char * aDest,
michael@0 126 nsIUnicodeEncoder ** aResult)
michael@0 127 {
michael@0 128 // resolve the charset first
michael@0 129 nsAutoCString charset;
michael@0 130
michael@0 131 // fully qualify to possibly avoid vtable call
michael@0 132 nsCharsetConverterManager::GetCharsetAlias(aDest, charset);
michael@0 133
michael@0 134 return nsCharsetConverterManager::GetUnicodeEncoderRaw(charset.get(),
michael@0 135 aResult);
michael@0 136 }
michael@0 137
michael@0 138
michael@0 139 NS_IMETHODIMP
michael@0 140 nsCharsetConverterManager::GetUnicodeEncoderRaw(const char * aDest,
michael@0 141 nsIUnicodeEncoder ** aResult)
michael@0 142 {
michael@0 143 *aResult= nullptr;
michael@0 144 nsCOMPtr<nsIUnicodeEncoder> encoder;
michael@0 145
michael@0 146 nsresult rv = NS_OK;
michael@0 147
michael@0 148 nsAutoCString
michael@0 149 contractid(NS_LITERAL_CSTRING(NS_UNICODEENCODER_CONTRACTID_BASE) +
michael@0 150 nsDependentCString(aDest));
michael@0 151
michael@0 152 // Always create an instance since encoders hold state.
michael@0 153 encoder = do_CreateInstance(contractid.get(), &rv);
michael@0 154
michael@0 155 if (NS_FAILED(rv))
michael@0 156 rv = NS_ERROR_UCONV_NOCONV;
michael@0 157 else
michael@0 158 {
michael@0 159 *aResult = encoder.get();
michael@0 160 NS_ADDREF(*aResult);
michael@0 161 }
michael@0 162 return rv;
michael@0 163 }
michael@0 164
michael@0 165 NS_IMETHODIMP
michael@0 166 nsCharsetConverterManager::GetUnicodeDecoder(const char * aSrc,
michael@0 167 nsIUnicodeDecoder ** aResult)
michael@0 168 {
michael@0 169 // resolve the charset first
michael@0 170 nsAutoCString charset;
michael@0 171
michael@0 172 // fully qualify to possibly avoid vtable call
michael@0 173 if (NS_FAILED(nsCharsetConverterManager::GetCharsetAlias(aSrc, charset)))
michael@0 174 return NS_ERROR_UCONV_NOCONV;
michael@0 175
michael@0 176 return nsCharsetConverterManager::GetUnicodeDecoderRaw(charset.get(),
michael@0 177 aResult);
michael@0 178 }
michael@0 179
michael@0 180 NS_IMETHODIMP
michael@0 181 nsCharsetConverterManager::GetUnicodeDecoderInternal(const char * aSrc,
michael@0 182 nsIUnicodeDecoder ** aResult)
michael@0 183 {
michael@0 184 // resolve the charset first
michael@0 185 nsAutoCString charset;
michael@0 186
michael@0 187 nsresult rv = nsCharsetAlias::GetPreferredInternal(nsDependentCString(aSrc),
michael@0 188 charset);
michael@0 189 NS_ENSURE_SUCCESS(rv, rv);
michael@0 190
michael@0 191 return nsCharsetConverterManager::GetUnicodeDecoderRaw(charset.get(),
michael@0 192 aResult);
michael@0 193 }
michael@0 194
michael@0 195 NS_IMETHODIMP
michael@0 196 nsCharsetConverterManager::GetUnicodeDecoderRaw(const char * aSrc,
michael@0 197 nsIUnicodeDecoder ** aResult)
michael@0 198 {
michael@0 199 *aResult= nullptr;
michael@0 200 nsCOMPtr<nsIUnicodeDecoder> decoder;
michael@0 201
michael@0 202 nsresult rv = NS_OK;
michael@0 203
michael@0 204 NS_NAMED_LITERAL_CSTRING(contractbase, NS_UNICODEDECODER_CONTRACTID_BASE);
michael@0 205 nsDependentCString src(aSrc);
michael@0 206
michael@0 207 decoder = do_CreateInstance(PromiseFlatCString(contractbase + src).get(),
michael@0 208 &rv);
michael@0 209 NS_ENSURE_SUCCESS(rv, NS_ERROR_UCONV_NOCONV);
michael@0 210
michael@0 211 decoder.forget(aResult);
michael@0 212 return rv;
michael@0 213 }
michael@0 214
michael@0 215 static
michael@0 216 nsresult GetList(const nsACString& aCategory,
michael@0 217 const nsACString& aPrefix,
michael@0 218 nsIUTF8StringEnumerator** aResult)
michael@0 219 {
michael@0 220 NS_ENSURE_ARG_POINTER(aResult);
michael@0 221 *aResult = nullptr;
michael@0 222
michael@0 223 nsresult rv;
michael@0 224
michael@0 225 nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
michael@0 226 if (NS_FAILED(rv))
michael@0 227 return rv;
michael@0 228
michael@0 229 nsTArray<nsCString>* array = new nsTArray<nsCString>;
michael@0 230 if (!array)
michael@0 231 return NS_ERROR_OUT_OF_MEMORY;
michael@0 232
michael@0 233 nsCOMPtr<nsISimpleEnumerator> enumerator;
michael@0 234 catman->EnumerateCategory(PromiseFlatCString(aCategory).get(),
michael@0 235 getter_AddRefs(enumerator));
michael@0 236
michael@0 237 bool hasMore;
michael@0 238 while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
michael@0 239 nsCOMPtr<nsISupports> supports;
michael@0 240 if (NS_FAILED(enumerator->GetNext(getter_AddRefs(supports))))
michael@0 241 continue;
michael@0 242
michael@0 243 nsCOMPtr<nsISupportsCString> supStr = do_QueryInterface(supports);
michael@0 244 if (!supStr)
michael@0 245 continue;
michael@0 246
michael@0 247 nsAutoCString name;
michael@0 248 if (NS_FAILED(supStr->GetData(name)))
michael@0 249 continue;
michael@0 250
michael@0 251 nsAutoCString fullName(aPrefix);
michael@0 252 fullName.Append(name);
michael@0 253 NS_ENSURE_TRUE(array->AppendElement(fullName), NS_ERROR_OUT_OF_MEMORY);
michael@0 254 }
michael@0 255
michael@0 256 return NS_NewAdoptingUTF8StringEnumerator(aResult, array);
michael@0 257 }
michael@0 258
michael@0 259 // we should change the interface so that we can just pass back a enumerator!
michael@0 260 NS_IMETHODIMP
michael@0 261 nsCharsetConverterManager::GetDecoderList(nsIUTF8StringEnumerator ** aResult)
michael@0 262 {
michael@0 263 return GetList(NS_LITERAL_CSTRING(NS_UNICODEDECODER_NAME),
michael@0 264 EmptyCString(), aResult);
michael@0 265 }
michael@0 266
michael@0 267 NS_IMETHODIMP
michael@0 268 nsCharsetConverterManager::GetEncoderList(nsIUTF8StringEnumerator ** aResult)
michael@0 269 {
michael@0 270 return GetList(NS_LITERAL_CSTRING(NS_UNICODEENCODER_NAME),
michael@0 271 EmptyCString(), aResult);
michael@0 272 }
michael@0 273
michael@0 274 NS_IMETHODIMP
michael@0 275 nsCharsetConverterManager::GetCharsetDetectorList(nsIUTF8StringEnumerator** aResult)
michael@0 276 {
michael@0 277 return GetList(NS_LITERAL_CSTRING("charset-detectors"),
michael@0 278 NS_LITERAL_CSTRING("chardet."), aResult);
michael@0 279 }
michael@0 280
michael@0 281 // XXX Improve the implementation of this method. Right now, it is build on
michael@0 282 // top of the nsCharsetAlias service. We can make the nsCharsetAlias
michael@0 283 // better, with its own hash table (not the StringBundle anymore) and
michael@0 284 // a nicer file format.
michael@0 285 NS_IMETHODIMP
michael@0 286 nsCharsetConverterManager::GetCharsetAlias(const char * aCharset,
michael@0 287 nsACString& aResult)
michael@0 288 {
michael@0 289 NS_ENSURE_ARG_POINTER(aCharset);
michael@0 290
michael@0 291 // We try to obtain the preferred name for this charset from the charset
michael@0 292 // aliases.
michael@0 293 nsresult rv;
michael@0 294
michael@0 295 rv = nsCharsetAlias::GetPreferred(nsDependentCString(aCharset), aResult);
michael@0 296 NS_ENSURE_SUCCESS(rv, rv);
michael@0 297
michael@0 298 return NS_OK;
michael@0 299 }
michael@0 300
michael@0 301
michael@0 302 NS_IMETHODIMP
michael@0 303 nsCharsetConverterManager::GetCharsetTitle(const char * aCharset,
michael@0 304 nsAString& aResult)
michael@0 305 {
michael@0 306 NS_ENSURE_ARG_POINTER(aCharset);
michael@0 307
michael@0 308 if (!sTitleBundle) {
michael@0 309 nsresult rv = LoadExtensibleBundle(NS_TITLE_BUNDLE_CATEGORY, &sTitleBundle);
michael@0 310 NS_ENSURE_SUCCESS(rv, rv);
michael@0 311 }
michael@0 312
michael@0 313 return GetBundleValue(sTitleBundle, aCharset, NS_LITERAL_STRING(".title"), aResult);
michael@0 314 }
michael@0 315
michael@0 316 NS_IMETHODIMP
michael@0 317 nsCharsetConverterManager::GetCharsetData(const char * aCharset,
michael@0 318 const char16_t * aProp,
michael@0 319 nsAString& aResult)
michael@0 320 {
michael@0 321 return GetCharsetDataImpl(aCharset, aProp, aResult);
michael@0 322 }
michael@0 323
michael@0 324 NS_IMETHODIMP
michael@0 325 nsCharsetConverterManager::GetCharsetLangGroup(const char * aCharset,
michael@0 326 nsIAtom** aResult)
michael@0 327 {
michael@0 328 // resolve the charset first
michael@0 329 nsAutoCString charset;
michael@0 330
michael@0 331 nsresult rv = GetCharsetAlias(aCharset, charset);
michael@0 332 NS_ENSURE_SUCCESS(rv, rv);
michael@0 333
michael@0 334 // fully qualify to possibly avoid vtable call
michael@0 335 return nsCharsetConverterManager::GetCharsetLangGroupRaw(charset.get(),
michael@0 336 aResult);
michael@0 337 }
michael@0 338
michael@0 339 NS_IMETHODIMP
michael@0 340 nsCharsetConverterManager::GetCharsetLangGroupRaw(const char * aCharset,
michael@0 341 nsIAtom** aResult)
michael@0 342 {
michael@0 343
michael@0 344 *aResult = nullptr;
michael@0 345 nsAutoString langGroup;
michael@0 346 // fully qualify to possibly avoid vtable call
michael@0 347 nsresult rv = nsCharsetConverterManager::GetCharsetData(
michael@0 348 aCharset, MOZ_UTF16(".LangGroup"), langGroup);
michael@0 349
michael@0 350 if (NS_SUCCEEDED(rv)) {
michael@0 351 ToLowerCase(langGroup); // use lowercase for all language atoms
michael@0 352 *aResult = NS_NewAtom(langGroup).take();
michael@0 353 }
michael@0 354
michael@0 355 return rv;
michael@0 356 }

mercurial