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 "mozilla/ArrayUtils.h"
7 :
8 : #include "nsHTMLEntities.h"
9 :
10 : #include "nsString.h"
11 : #include "nsCRT.h"
12 : #include "PLDHashTable.h"
13 :
14 : using namespace mozilla;
15 :
16 : struct EntityNode {
17 : const char* mStr; // never owns buffer
18 : int32_t mUnicode;
19 : };
20 :
21 : struct EntityNodeEntry : public PLDHashEntryHdr
22 : {
23 : const EntityNode* node;
24 : };
25 :
26 12 : static bool matchNodeUnicode(const PLDHashEntryHdr* aHdr, const void* key)
27 : {
28 12 : const EntityNodeEntry* entry = static_cast<const EntityNodeEntry*>(aHdr);
29 12 : const int32_t ucode = NS_PTR_TO_INT32(key);
30 12 : return (entry->node->mUnicode == ucode);
31 : }
32 :
33 518 : static PLDHashNumber hashUnicodeValue(const void* key)
34 : {
35 : // key is actually the unicode value
36 518 : return PLDHashNumber(NS_PTR_TO_INT32(key));
37 : }
38 :
39 : static const PLDHashTableOps UnicodeToEntityOps = {
40 : hashUnicodeValue,
41 : matchNodeUnicode,
42 : PLDHashTable::MoveEntryStub,
43 : PLDHashTable::ClearEntryStub,
44 : nullptr,
45 : };
46 :
47 : static PLDHashTable* gUnicodeToEntity;
48 : static nsrefcnt gTableRefCnt = 0;
49 :
50 : #define HTML_ENTITY(_name, _value) { #_name, _value },
51 : static const EntityNode gEntityArray[] = {
52 : #include "nsHTMLEntityList.h"
53 : };
54 : #undef HTML_ENTITY
55 :
56 : #define NS_HTML_ENTITY_COUNT ((int32_t)ArrayLength(gEntityArray))
57 :
58 : nsresult
59 2 : nsHTMLEntities::AddRefTable(void)
60 : {
61 2 : if (!gTableRefCnt) {
62 2 : gUnicodeToEntity = new PLDHashTable(&UnicodeToEntityOps,
63 : sizeof(EntityNodeEntry),
64 4 : NS_HTML_ENTITY_COUNT);
65 520 : for (const EntityNode *node = gEntityArray,
66 2 : *node_end = ArrayEnd(gEntityArray);
67 520 : node < node_end; ++node) {
68 :
69 : // add to Unicode->Entity table
70 : auto entry =
71 : static_cast<EntityNodeEntry*>
72 518 : (gUnicodeToEntity->Add(NS_INT32_TO_PTR(node->mUnicode), fallible));
73 518 : NS_ASSERTION(entry, "Error adding an entry");
74 : // Prefer earlier entries when we have duplication.
75 518 : if (!entry->node)
76 506 : entry->node = node;
77 : }
78 : #ifdef DEBUG
79 2 : gUnicodeToEntity->MarkImmutable();
80 : #endif
81 : }
82 2 : ++gTableRefCnt;
83 2 : return NS_OK;
84 : }
85 :
86 : void
87 0 : nsHTMLEntities::ReleaseTable(void)
88 : {
89 0 : if (--gTableRefCnt != 0) {
90 0 : return;
91 : }
92 :
93 0 : delete gUnicodeToEntity;
94 0 : gUnicodeToEntity = nullptr;
95 : }
96 :
97 : const char*
98 0 : nsHTMLEntities::UnicodeToEntity(int32_t aUnicode)
99 : {
100 0 : NS_ASSERTION(gUnicodeToEntity, "no lookup table, needs addref");
101 : auto entry =
102 : static_cast<EntityNodeEntry*>
103 0 : (gUnicodeToEntity->Search(NS_INT32_TO_PTR(aUnicode)));
104 :
105 0 : return entry ? entry->node->mStr : nullptr;
106 : }
107 :
|