summaryrefslogtreecommitdiffstats
path: root/intl/unicharutil/nsEntityConverter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'intl/unicharutil/nsEntityConverter.cpp')
-rw-r--r--intl/unicharutil/nsEntityConverter.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/intl/unicharutil/nsEntityConverter.cpp b/intl/unicharutil/nsEntityConverter.cpp
new file mode 100644
index 000000000..94853df74
--- /dev/null
+++ b/intl/unicharutil/nsEntityConverter.cpp
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsEntityConverter.h"
+#include "nsLiteralString.h"
+#include "nsString.h"
+#include "mozilla/Services.h"
+#include "nsServiceManagerUtils.h"
+#include "nsCRT.h"
+
+//
+// implementation methods
+//
+nsEntityConverter::nsEntityConverter() { }
+
+nsEntityConverter::~nsEntityConverter() { }
+
+nsIStringBundle*
+nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
+{
+ switch(versionNumber){
+ case nsIEntityConverter::html40Latin1:
+ if (!mHTML40Latin1Bundle) {
+ mHTML40Latin1Bundle = LoadEntityBundle(kHTML40LATIN1);
+ MOZ_ASSERT(mHTML40Latin1Bundle, "LoadEntityBundle failed");
+ }
+ return mHTML40Latin1Bundle;
+ case nsIEntityConverter::html40Symbols:
+ if (!mHTML40SymbolsBundle) {
+ mHTML40SymbolsBundle = LoadEntityBundle(kHTML40SYMBOLS);
+ MOZ_ASSERT(mHTML40SymbolsBundle, "LoadEntityBundle failed");
+ }
+ return mHTML40SymbolsBundle;
+ case nsIEntityConverter::html40Special:
+ if (!mHTML40SpecialBundle) {
+ mHTML40SpecialBundle = LoadEntityBundle(kHTML40SPECIAL);
+ MOZ_ASSERT(mHTML40SpecialBundle, "LoadEntityBundle failed");
+ }
+ return mHTML40SpecialBundle;
+ case nsIEntityConverter::mathml20:
+ if (!mMathML20Bundle) {
+ mMathML20Bundle = LoadEntityBundle(kMATHML20);
+ MOZ_ASSERT(mMathML20Bundle, "LoadEntityBundle failed");
+ }
+ return mMathML20Bundle;
+ default:
+ return nullptr;
+ }
+}
+
+already_AddRefed<nsIStringBundle>
+nsEntityConverter:: LoadEntityBundle(const char *fileName)
+{
+ NS_ENSURE_TRUE(fileName, nullptr);
+
+ nsAutoCString url("resource://gre/res/entityTables/");
+ nsresult rv;
+
+ nsCOMPtr<nsIStringBundleService> bundleService =
+ do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ url.Append(fileName);
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ rv = bundleService->CreateBundle(url.get(), getter_AddRefs(bundle));
+ NS_ENSURE_SUCCESS(rv, nullptr);
+
+ return bundle.forget();
+}
+
+//
+// nsISupports methods
+//
+NS_IMPL_ISUPPORTS(nsEntityConverter,nsIEntityConverter)
+
+//
+// nsIEntityConverter
+//
+NS_IMETHODIMP
+nsEntityConverter::ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval)
+{
+ return ConvertUTF32ToEntity((uint32_t)character, entityVersion, _retval);
+}
+
+NS_IMETHODIMP
+nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval)
+{
+ NS_ASSERTION(_retval, "null ptr- _retval");
+ if (nullptr == _retval) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *_retval = nullptr;
+
+ for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
+ if (0 == (entityVersion & mask)) {
+ continue;
+ }
+
+ nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
+ NS_ASSERTION(entities, "Cannot get the entity");
+
+ if (!entities) {
+ continue;
+ }
+
+ nsAutoString key(NS_LITERAL_STRING("entity."));
+ key.AppendInt(character,10);
+
+ nsXPIDLString value;
+ nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
+ if (NS_SUCCEEDED(rv)) {
+ *_retval = ToNewCString(value);
+ return NS_OK;
+ }
+ }
+ return NS_ERROR_ILLEGAL_VALUE;
+}
+
+NS_IMETHODIMP
+nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval)
+{
+ NS_ENSURE_ARG_POINTER(inString);
+ NS_ENSURE_ARG_POINTER(_retval);
+
+ *_retval = nullptr;
+
+ nsString outString;
+
+ // per character look for the entity
+ uint32_t len = NS_strlen(inString);
+ for (uint32_t i = 0; i < len; i++) {
+ nsAutoString key(NS_LITERAL_STRING("entity."));
+ if (NS_IS_HIGH_SURROGATE(inString[i]) && i + 2 < len && NS_IS_LOW_SURROGATE(inString[i + 1])) {
+ key.AppendInt(SURROGATE_TO_UCS4(inString[i], inString[i+1]), 10);
+ ++i;
+ } else {
+ key.AppendInt(inString[i],10);
+ }
+
+ nsXPIDLString value;
+ const char16_t *entity = nullptr;
+
+ for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
+ if (0 == (entityVersion & mask)) {
+ continue;
+ }
+ nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
+ NS_ASSERTION(entities, "Cannot get the property file");
+
+ if (!entities) {
+ continue;
+ }
+
+ nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
+ if (NS_SUCCEEDED(rv)) {
+ entity = value.get();
+ break;
+ }
+ }
+ if (entity) {
+ outString.Append(entity);
+ } else {
+ outString.Append(&inString[i], 1);
+ }
+ }
+
+ *_retval = ToNewUnicode(outString);
+
+ return NS_OK;
+}