intl/unicharutil/src/nsEntityConverter.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 #include "nsEntityConverter.h"
michael@0 7 #include "nsLiteralString.h"
michael@0 8 #include "nsString.h"
michael@0 9 #include "mozilla/Services.h"
michael@0 10 #include "nsServiceManagerUtils.h"
michael@0 11 #include "nsCRT.h"
michael@0 12
michael@0 13 //
michael@0 14 // implementation methods
michael@0 15 //
michael@0 16 nsEntityConverter::nsEntityConverter() :
michael@0 17 mVersionList(nullptr),
michael@0 18 mVersionListLength(0)
michael@0 19 {
michael@0 20 }
michael@0 21
michael@0 22 nsEntityConverter::~nsEntityConverter()
michael@0 23 {
michael@0 24 if (mVersionList)
michael@0 25 delete [] mVersionList;
michael@0 26 }
michael@0 27
michael@0 28 NS_IMETHODIMP
michael@0 29 nsEntityConverter::LoadVersionPropertyFile()
michael@0 30 {
michael@0 31 NS_NAMED_LITERAL_CSTRING(url, "resource://gre/res/entityTables/htmlEntityVersions.properties");
michael@0 32
michael@0 33 nsCOMPtr<nsIStringBundleService> bundleService =
michael@0 34 mozilla::services::GetStringBundleService();
michael@0 35 if (!bundleService)
michael@0 36 return NS_ERROR_FAILURE;
michael@0 37
michael@0 38 nsCOMPtr<nsIStringBundle> entities;
michael@0 39 nsresult rv = bundleService->CreateBundle(url.get(), getter_AddRefs(entities));
michael@0 40 if (NS_FAILED(rv)) return rv;
michael@0 41
michael@0 42 nsresult result;
michael@0 43
michael@0 44 nsAutoString key;
michael@0 45 nsXPIDLString value;
michael@0 46 rv = entities->GetStringFromName(MOZ_UTF16("length"),
michael@0 47 getter_Copies(value));
michael@0 48 NS_ASSERTION(NS_SUCCEEDED(rv),"nsEntityConverter: malformed entity table\n");
michael@0 49 if (NS_FAILED(rv)) return rv;
michael@0 50
michael@0 51 mVersionListLength = nsAutoString(value).ToInteger(&result);
michael@0 52 NS_ASSERTION(32 >= mVersionListLength,"nsEntityConverter: malformed entity table\n");
michael@0 53 if (32 < mVersionListLength) return NS_ERROR_FAILURE;
michael@0 54
michael@0 55 mVersionList = new nsEntityVersionList[mVersionListLength];
michael@0 56 if (!mVersionList) return NS_ERROR_OUT_OF_MEMORY;
michael@0 57
michael@0 58 for (uint32_t i = 0; i < mVersionListLength && NS_SUCCEEDED(rv); i++) {
michael@0 59 key.SetLength(0);
michael@0 60 key.AppendInt(i+1, 10);
michael@0 61 rv = entities->GetStringFromName(key.get(), getter_Copies(value));
michael@0 62 uint32_t len = value.Length();
michael@0 63 if (kVERSION_STRING_LEN < len) return NS_ERROR_UNEXPECTED;
michael@0 64
michael@0 65 memcpy(mVersionList[i].mEntityListName, value.get(), len*sizeof(char16_t));
michael@0 66 mVersionList[i].mEntityListName[len] = 0;
michael@0 67 mVersionList[i].mVersion = (1 << i);
michael@0 68 }
michael@0 69
michael@0 70 return NS_OK;
michael@0 71 }
michael@0 72
michael@0 73 already_AddRefed<nsIStringBundle>
michael@0 74 nsEntityConverter::LoadEntityBundle(uint32_t version)
michael@0 75 {
michael@0 76 nsAutoCString url(NS_LITERAL_CSTRING("resource://gre/res/entityTables/"));
michael@0 77 nsresult rv;
michael@0 78
michael@0 79 nsCOMPtr<nsIStringBundleService> bundleService =
michael@0 80 do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
michael@0 81 NS_ENSURE_SUCCESS(rv, nullptr);
michael@0 82
michael@0 83 const char16_t *versionName = GetVersionName(version);
michael@0 84 NS_ENSURE_TRUE(versionName, nullptr);
michael@0 85
michael@0 86 // all property file names are ASCII, like "html40Latin1" so this is safe
michael@0 87 LossyAppendUTF16toASCII(versionName, url);
michael@0 88 url.Append(".properties");
michael@0 89
michael@0 90 nsCOMPtr<nsIStringBundle> bundle;
michael@0 91 rv = bundleService->CreateBundle(url.get(), getter_AddRefs(bundle));
michael@0 92 NS_ENSURE_SUCCESS(rv, nullptr);
michael@0 93
michael@0 94 return bundle.forget();
michael@0 95 }
michael@0 96
michael@0 97 const char16_t*
michael@0 98 nsEntityConverter:: GetVersionName(uint32_t versionNumber)
michael@0 99 {
michael@0 100 for (uint32_t i = 0; i < mVersionListLength; i++) {
michael@0 101 if (versionNumber == mVersionList[i].mVersion)
michael@0 102 return mVersionList[i].mEntityListName;
michael@0 103 }
michael@0 104
michael@0 105 return nullptr;
michael@0 106 }
michael@0 107
michael@0 108 nsIStringBundle*
michael@0 109 nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
michael@0 110 {
michael@0 111 if (!mVersionList) {
michael@0 112 // load the property file which contains available version names
michael@0 113 // and generate a list of version/name pair
michael@0 114 if (NS_FAILED(LoadVersionPropertyFile()))
michael@0 115 return nullptr;
michael@0 116 }
michael@0 117
michael@0 118 uint32_t i;
michael@0 119 for (i = 0; i < mVersionListLength; i++) {
michael@0 120 if (versionNumber == mVersionList[i].mVersion) {
michael@0 121 if (!mVersionList[i].mEntities)
michael@0 122 { // not loaded
michael@0 123 // load the property file
michael@0 124 mVersionList[i].mEntities = LoadEntityBundle(versionNumber);
michael@0 125 NS_ASSERTION(mVersionList[i].mEntities, "LoadEntityBundle failed");
michael@0 126 }
michael@0 127 return mVersionList[i].mEntities.get();
michael@0 128 }
michael@0 129 }
michael@0 130
michael@0 131 return nullptr;
michael@0 132 }
michael@0 133
michael@0 134
michael@0 135 //
michael@0 136 // nsISupports methods
michael@0 137 //
michael@0 138 NS_IMPL_ISUPPORTS(nsEntityConverter,nsIEntityConverter)
michael@0 139
michael@0 140
michael@0 141 //
michael@0 142 // nsIEntityConverter
michael@0 143 //
michael@0 144 NS_IMETHODIMP
michael@0 145 nsEntityConverter::ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval)
michael@0 146 {
michael@0 147 return ConvertUTF32ToEntity((uint32_t)character, entityVersion, _retval);
michael@0 148 }
michael@0 149
michael@0 150 NS_IMETHODIMP
michael@0 151 nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval)
michael@0 152 {
michael@0 153 NS_ASSERTION(_retval, "null ptr- _retval");
michael@0 154 if(nullptr == _retval)
michael@0 155 return NS_ERROR_NULL_POINTER;
michael@0 156 *_retval = nullptr;
michael@0 157
michael@0 158 for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
michael@0 159 if (0 == (entityVersion & mask))
michael@0 160 continue;
michael@0 161 nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
michael@0 162 NS_ASSERTION(entities, "Cannot get the property file");
michael@0 163
michael@0 164 if (!entities)
michael@0 165 continue;
michael@0 166
michael@0 167 nsAutoString key(NS_LITERAL_STRING("entity."));
michael@0 168 key.AppendInt(character,10);
michael@0 169
michael@0 170 nsXPIDLString value;
michael@0 171 nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
michael@0 172 if (NS_SUCCEEDED(rv)) {
michael@0 173 *_retval = ToNewCString(value);
michael@0 174 if(nullptr == *_retval)
michael@0 175 return NS_ERROR_OUT_OF_MEMORY;
michael@0 176 else
michael@0 177 return NS_OK;
michael@0 178 }
michael@0 179 }
michael@0 180 return NS_ERROR_ILLEGAL_VALUE;
michael@0 181 }
michael@0 182
michael@0 183 NS_IMETHODIMP
michael@0 184 nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval)
michael@0 185 {
michael@0 186 NS_ENSURE_ARG_POINTER(inString);
michael@0 187 NS_ENSURE_ARG_POINTER(_retval);
michael@0 188
michael@0 189 *_retval = nullptr;
michael@0 190
michael@0 191 nsString outString;
michael@0 192
michael@0 193 // per character look for the entity
michael@0 194 uint32_t len = NS_strlen(inString);
michael@0 195 for (uint32_t i = 0; i < len; i++) {
michael@0 196 nsAutoString key(NS_LITERAL_STRING("entity."));
michael@0 197 if (NS_IS_HIGH_SURROGATE(inString[i]) &&
michael@0 198 i + 2 < len &&
michael@0 199 NS_IS_LOW_SURROGATE(inString[i + 1])) {
michael@0 200 key.AppendInt(SURROGATE_TO_UCS4(inString[i], inString[i+1]), 10);
michael@0 201 ++i;
michael@0 202 }
michael@0 203 else {
michael@0 204 key.AppendInt(inString[i],10);
michael@0 205 }
michael@0 206
michael@0 207 nsXPIDLString value;
michael@0 208 const char16_t *entity = nullptr;
michael@0 209
michael@0 210 for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
michael@0 211 if (0 == (entityVersion & mask))
michael@0 212 continue;
michael@0 213 nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
michael@0 214 NS_ASSERTION(entities, "Cannot get the property file");
michael@0 215
michael@0 216 if (!entities)
michael@0 217 continue;
michael@0 218
michael@0 219 nsresult rv = entities->GetStringFromName(key.get(),
michael@0 220 getter_Copies(value));
michael@0 221 if (NS_SUCCEEDED(rv)) {
michael@0 222 entity = value.get();
michael@0 223 break;
michael@0 224 }
michael@0 225 }
michael@0 226 if (entity) {
michael@0 227 outString.Append(entity);
michael@0 228 }
michael@0 229 else {
michael@0 230 outString.Append(&inString[i], 1);
michael@0 231 }
michael@0 232 }
michael@0 233
michael@0 234 *_retval = ToNewUnicode(outString);
michael@0 235 if (!*_retval)
michael@0 236 return NS_ERROR_OUT_OF_MEMORY;
michael@0 237
michael@0 238 return NS_OK;
michael@0 239 }

mercurial