2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* 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/. */
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsEntityConverter.h"
|
|
|
|
#include "nsLiteralString.h"
|
|
|
|
#include "nsString.h"
|
2010-05-14 02:24:41 -07:00
|
|
|
#include "mozilla/Services.h"
|
2013-09-27 09:45:04 -07:00
|
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#include "nsCRT.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// implementation methods
|
|
|
|
//
|
2012-08-24 00:49:00 -07:00
|
|
|
nsEntityConverter::nsEntityConverter() :
|
|
|
|
mVersionList(nullptr),
|
|
|
|
mVersionListLength(0)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsEntityConverter::~nsEntityConverter()
|
|
|
|
{
|
2012-08-24 00:49:00 -07:00
|
|
|
if (mVersionList)
|
|
|
|
delete [] mVersionList;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsEntityConverter::LoadVersionPropertyFile()
|
|
|
|
{
|
|
|
|
NS_NAMED_LITERAL_CSTRING(url, "resource://gre/res/entityTables/htmlEntityVersions.properties");
|
|
|
|
|
2010-05-14 02:24:41 -07:00
|
|
|
nsCOMPtr<nsIStringBundleService> bundleService =
|
|
|
|
mozilla::services::GetStringBundleService();
|
|
|
|
if (!bundleService)
|
|
|
|
return NS_ERROR_FAILURE;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIStringBundle> entities;
|
2010-05-14 02:24:41 -07:00
|
|
|
nsresult rv = bundleService->CreateBundle(url.get(), getter_AddRefs(entities));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2012-07-27 06:59:29 -07:00
|
|
|
nsresult result;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsAutoString key;
|
|
|
|
nsXPIDLString value;
|
2013-12-12 17:50:01 -08:00
|
|
|
rv = entities->GetStringFromName(MOZ_UTF16("length"),
|
2007-03-22 10:30:00 -07:00
|
|
|
getter_Copies(value));
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv),"nsEntityConverter: malformed entity table\n");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
mVersionListLength = nsAutoString(value).ToInteger(&result);
|
|
|
|
NS_ASSERTION(32 >= mVersionListLength,"nsEntityConverter: malformed entity table\n");
|
|
|
|
if (32 < mVersionListLength) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
mVersionList = new nsEntityVersionList[mVersionListLength];
|
|
|
|
if (!mVersionList) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
for (uint32_t i = 0; i < mVersionListLength && NS_SUCCEEDED(rv); i++) {
|
2007-03-22 10:30:00 -07:00
|
|
|
key.SetLength(0);
|
|
|
|
key.AppendInt(i+1, 10);
|
|
|
|
rv = entities->GetStringFromName(key.get(), getter_Copies(value));
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t len = value.Length();
|
2007-03-22 10:30:00 -07:00
|
|
|
if (kVERSION_STRING_LEN < len) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
2014-01-04 07:02:17 -08:00
|
|
|
memcpy(mVersionList[i].mEntityListName, value.get(), len*sizeof(char16_t));
|
2007-03-22 10:30:00 -07:00
|
|
|
mVersionList[i].mEntityListName[len] = 0;
|
|
|
|
mVersionList[i].mVersion = (1 << i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsIStringBundle>
|
2012-08-22 08:56:38 -07:00
|
|
|
nsEntityConverter::LoadEntityBundle(uint32_t version)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString url(NS_LITERAL_CSTRING("resource://gre/res/entityTables/"));
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStringBundleService> bundleService =
|
|
|
|
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
2012-08-24 00:49:00 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2014-01-04 07:02:17 -08:00
|
|
|
const char16_t *versionName = GetVersionName(version);
|
2012-08-24 00:49:00 -07:00
|
|
|
NS_ENSURE_TRUE(versionName, nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// all property file names are ASCII, like "html40Latin1" so this is safe
|
|
|
|
LossyAppendUTF16toASCII(versionName, url);
|
2014-05-21 20:48:51 -07:00
|
|
|
url.AppendLiteral(".properties");
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2013-04-28 04:52:10 -07:00
|
|
|
nsCOMPtr<nsIStringBundle> bundle;
|
|
|
|
rv = bundleService->CreateBundle(url.get(), getter_AddRefs(bundle));
|
2012-08-24 00:49:00 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2013-04-28 04:52:10 -07:00
|
|
|
return bundle.forget();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2014-01-04 07:02:17 -08:00
|
|
|
const char16_t*
|
2012-08-22 08:56:38 -07:00
|
|
|
nsEntityConverter:: GetVersionName(uint32_t versionNumber)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-08-22 08:56:38 -07:00
|
|
|
for (uint32_t i = 0; i < mVersionListLength; i++) {
|
2007-03-22 10:30:00 -07:00
|
|
|
if (versionNumber == mVersionList[i].mVersion)
|
|
|
|
return mVersionList[i].mEntityListName;
|
|
|
|
}
|
|
|
|
|
2012-08-24 00:49:00 -07:00
|
|
|
return nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsIStringBundle*
|
2012-08-22 08:56:38 -07:00
|
|
|
nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-08-24 00:49:00 -07:00
|
|
|
if (!mVersionList) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// load the property file which contains available version names
|
|
|
|
// and generate a list of version/name pair
|
2012-08-24 00:49:00 -07:00
|
|
|
if (NS_FAILED(LoadVersionPropertyFile()))
|
|
|
|
return nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t i;
|
2007-03-22 10:30:00 -07:00
|
|
|
for (i = 0; i < mVersionListLength; i++) {
|
|
|
|
if (versionNumber == mVersionList[i].mVersion) {
|
|
|
|
if (!mVersionList[i].mEntities)
|
|
|
|
{ // not loaded
|
|
|
|
// load the property file
|
|
|
|
mVersionList[i].mEntities = LoadEntityBundle(versionNumber);
|
|
|
|
NS_ASSERTION(mVersionList[i].mEntities, "LoadEntityBundle failed");
|
|
|
|
}
|
|
|
|
return mVersionList[i].mEntities.get();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-24 00:49:00 -07:00
|
|
|
return nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// nsISupports methods
|
|
|
|
//
|
2014-04-27 00:06:00 -07:00
|
|
|
NS_IMPL_ISUPPORTS(nsEntityConverter,nsIEntityConverter)
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// nsIEntityConverter
|
|
|
|
//
|
|
|
|
NS_IMETHODIMP
|
2014-01-04 07:02:17 -08:00
|
|
|
nsEntityConverter::ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-08-22 08:56:38 -07:00
|
|
|
return ConvertUTF32ToEntity((uint32_t)character, entityVersion, _retval);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 08:56:38 -07:00
|
|
|
nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ASSERTION(_retval, "null ptr- _retval");
|
2012-07-30 07:20:58 -07:00
|
|
|
if(nullptr == _retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
2012-08-24 00:49:00 -07:00
|
|
|
*_retval = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
|
2007-03-22 10:30:00 -07:00
|
|
|
if (0 == (entityVersion & mask))
|
|
|
|
continue;
|
|
|
|
nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
|
|
|
|
NS_ASSERTION(entities, "Cannot get the property file");
|
|
|
|
|
2012-08-24 00:49:00 -07:00
|
|
|
if (!entities)
|
2007-03-22 10:30:00 -07:00
|
|
|
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);
|
2012-07-30 07:20:58 -07:00
|
|
|
if(nullptr == *_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
else
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-01-04 07:02:17 -08:00
|
|
|
nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-08-24 00:49:00 -07:00
|
|
|
NS_ENSURE_ARG_POINTER(inString);
|
|
|
|
NS_ENSURE_ARG_POINTER(_retval);
|
|
|
|
|
|
|
|
*_retval = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsString outString;
|
|
|
|
|
|
|
|
// per character look for the entity
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t len = NS_strlen(inString);
|
|
|
|
for (uint32_t i = 0; i < len; i++) {
|
2007-03-22 10:30:00 -07:00
|
|
|
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;
|
2014-01-04 07:02:17 -08:00
|
|
|
const char16_t *entity = nullptr;
|
2012-08-24 00:49:00 -07:00
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
|
2007-03-22 10:30:00 -07:00
|
|
|
if (0 == (entityVersion & mask))
|
|
|
|
continue;
|
|
|
|
nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
|
|
|
|
NS_ASSERTION(entities, "Cannot get the property file");
|
|
|
|
|
2012-08-24 00:49:00 -07:00
|
|
|
if (!entities)
|
2007-03-22 10:30:00 -07:00
|
|
|
continue;
|
|
|
|
|
|
|
|
nsresult rv = entities->GetStringFromName(key.get(),
|
|
|
|
getter_Copies(value));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
entity = value.get();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-08-24 00:49:00 -07:00
|
|
|
if (entity) {
|
2007-03-22 10:30:00 -07:00
|
|
|
outString.Append(entity);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
outString.Append(&inString[i], 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*_retval = ToNewUnicode(outString);
|
2012-08-24 00:49:00 -07:00
|
|
|
if (!*_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|