Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "nsEntityConverter.h"
7 : #include "nsLiteralString.h"
8 : #include "nsString.h"
9 : #include "mozilla/Services.h"
10 : #include "nsServiceManagerUtils.h"
11 : #include "nsCRT.h"
12 :
13 : //
14 : // implementation methods
15 : //
16 0 : nsEntityConverter::nsEntityConverter() { }
17 :
18 0 : nsEntityConverter::~nsEntityConverter() { }
19 :
20 : nsIStringBundle*
21 0 : nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
22 : {
23 0 : switch(versionNumber){
24 : case nsIEntityConverter::html40Latin1:
25 0 : if (!mHTML40Latin1Bundle) {
26 0 : mHTML40Latin1Bundle = LoadEntityBundle(kHTML40LATIN1);
27 0 : MOZ_ASSERT(mHTML40Latin1Bundle, "LoadEntityBundle failed");
28 : }
29 0 : return mHTML40Latin1Bundle;
30 : case nsIEntityConverter::html40Symbols:
31 0 : if (!mHTML40SymbolsBundle) {
32 0 : mHTML40SymbolsBundle = LoadEntityBundle(kHTML40SYMBOLS);
33 0 : MOZ_ASSERT(mHTML40SymbolsBundle, "LoadEntityBundle failed");
34 : }
35 0 : return mHTML40SymbolsBundle;
36 : case nsIEntityConverter::html40Special:
37 0 : if (!mHTML40SpecialBundle) {
38 0 : mHTML40SpecialBundle = LoadEntityBundle(kHTML40SPECIAL);
39 0 : MOZ_ASSERT(mHTML40SpecialBundle, "LoadEntityBundle failed");
40 : }
41 0 : return mHTML40SpecialBundle;
42 : case nsIEntityConverter::mathml20:
43 0 : if (!mMathML20Bundle) {
44 0 : mMathML20Bundle = LoadEntityBundle(kMATHML20);
45 0 : MOZ_ASSERT(mMathML20Bundle, "LoadEntityBundle failed");
46 : }
47 0 : return mMathML20Bundle;
48 : default:
49 0 : return nullptr;
50 : }
51 : }
52 :
53 : already_AddRefed<nsIStringBundle>
54 0 : nsEntityConverter:: LoadEntityBundle(const char *fileName)
55 : {
56 0 : NS_ENSURE_TRUE(fileName, nullptr);
57 :
58 0 : nsAutoCString url("resource://gre/res/entityTables/");
59 : nsresult rv;
60 :
61 : nsCOMPtr<nsIStringBundleService> bundleService =
62 0 : do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
63 0 : NS_ENSURE_SUCCESS(rv, nullptr);
64 :
65 0 : url.Append(fileName);
66 :
67 0 : nsCOMPtr<nsIStringBundle> bundle;
68 0 : rv = bundleService->CreateBundle(url.get(), getter_AddRefs(bundle));
69 0 : NS_ENSURE_SUCCESS(rv, nullptr);
70 :
71 0 : return bundle.forget();
72 : }
73 :
74 : //
75 : // nsISupports methods
76 : //
77 0 : NS_IMPL_ISUPPORTS(nsEntityConverter,nsIEntityConverter)
78 :
79 : //
80 : // nsIEntityConverter
81 : //
82 : NS_IMETHODIMP
83 0 : nsEntityConverter::ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval)
84 : {
85 0 : return ConvertUTF32ToEntity((uint32_t)character, entityVersion, _retval);
86 : }
87 :
88 : NS_IMETHODIMP
89 0 : nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval)
90 : {
91 0 : NS_ASSERTION(_retval, "null ptr- _retval");
92 0 : if (nullptr == _retval) {
93 0 : return NS_ERROR_NULL_POINTER;
94 : }
95 0 : *_retval = nullptr;
96 :
97 0 : for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
98 0 : if (0 == (entityVersion & mask)) {
99 0 : continue;
100 : }
101 :
102 0 : nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
103 0 : NS_ASSERTION(entities, "Cannot get the entity");
104 :
105 0 : if (!entities) {
106 0 : continue;
107 : }
108 :
109 0 : nsAutoString key(NS_LITERAL_STRING("entity."));
110 0 : key.AppendInt(character,10);
111 :
112 0 : nsXPIDLString value;
113 0 : nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
114 0 : if (NS_SUCCEEDED(rv)) {
115 0 : *_retval = ToNewCString(value);
116 0 : return NS_OK;
117 : }
118 : }
119 0 : return NS_ERROR_ILLEGAL_VALUE;
120 : }
121 :
122 : NS_IMETHODIMP
123 0 : nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval)
124 : {
125 0 : NS_ENSURE_ARG_POINTER(inString);
126 0 : NS_ENSURE_ARG_POINTER(_retval);
127 :
128 0 : *_retval = nullptr;
129 :
130 0 : nsString outString;
131 :
132 : // per character look for the entity
133 0 : uint32_t len = NS_strlen(inString);
134 0 : for (uint32_t i = 0; i < len; i++) {
135 0 : nsAutoString key(NS_LITERAL_STRING("entity."));
136 0 : if (NS_IS_HIGH_SURROGATE(inString[i]) && i + 2 < len && NS_IS_LOW_SURROGATE(inString[i + 1])) {
137 0 : key.AppendInt(SURROGATE_TO_UCS4(inString[i], inString[i+1]), 10);
138 0 : ++i;
139 : } else {
140 0 : key.AppendInt(inString[i],10);
141 : }
142 :
143 0 : nsXPIDLString value;
144 0 : const char16_t *entity = nullptr;
145 :
146 0 : for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
147 0 : if (0 == (entityVersion & mask)) {
148 0 : continue;
149 : }
150 0 : nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
151 0 : NS_ASSERTION(entities, "Cannot get the property file");
152 :
153 0 : if (!entities) {
154 0 : continue;
155 : }
156 :
157 0 : nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
158 0 : if (NS_SUCCEEDED(rv)) {
159 0 : entity = value.get();
160 0 : break;
161 : }
162 : }
163 0 : if (entity) {
164 0 : outString.Append(entity);
165 : } else {
166 0 : outString.Append(&inString[i], 1);
167 : }
168 : }
169 :
170 0 : *_retval = ToNewUnicode(outString);
171 :
172 0 : return NS_OK;
173 : }
|