KJS

identifier.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2003 Apple Computer, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21 
22 #include "identifier.h"
23 
24 #include <wtf/FastMalloc.h>
25 #include <wtf/HashSet.h>
26 #include <string.h> // for strlen
27 #include <new> // for placement new
28 
29 namespace KJS
30 {
31 
32 typedef HashSet<UString::Rep *> IdentifierTable;
33 static IdentifierTable *table;
34 
35 static inline IdentifierTable &identifierTable()
36 {
37  if (!table) {
38  table = new IdentifierTable;
39  }
40  return *table;
41 }
42 
43 bool Identifier::equal(const UString::Rep *r, const char *s)
44 {
45  int length = r->len;
46  const UChar *d = r->data();
47  for (int i = 0; i != length; ++i)
48  if (d[i].uc != (unsigned char)s[i]) {
49  return false;
50  }
51  return s[length] == 0;
52 }
53 
54 bool Identifier::equal(const UString::Rep *r, const UChar *s, int length)
55 {
56  if (r->len != length) {
57  return false;
58  }
59  const UChar *d = r->data();
60  for (int i = 0; i != length; ++i)
61  if (d[i].uc != s[i].uc) {
62  return false;
63  }
64  return true;
65 }
66 
67 struct CStringTranslator {
68  static unsigned hash(const char *c)
69  {
70  return UString::Rep::computeHash(c);
71  }
72 
73  static bool equal(UString::Rep *r, const char *s)
74  {
75  return Identifier::equal(r, s);
76  }
77 
78  static void translate(UString::Rep *&location, const char *c, unsigned hash)
79  {
80  size_t length = strlen(c);
81  UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * length));
82  for (size_t i = 0; i != length; i++) {
83  d[i] = c[i];
84  }
85 
86  UString::Rep *r = UString::Rep::create(d, static_cast<int>(length)).releaseRef();
87  r->isIdentifier = 1;
88  r->rc = 0;
89  r->_hash = hash;
90 
91  location = r;
92  }
93 };
94 
95 PassRefPtr<UString::Rep> Identifier::add(const char *c)
96 {
97  if (!c) {
98  UString::Rep::null.hash();
99  return &UString::Rep::null;
100  }
101 
102  if (!c[0]) {
103  UString::Rep::empty.hash();
104  return &UString::Rep::empty;
105  }
106 
107  return *identifierTable().add<const char *, CStringTranslator>(c).first;
108 }
109 
110 struct UCharBuffer {
111  const UChar *s;
112  unsigned int length;
113 };
114 
115 struct UCharBufferTranslator {
116  static unsigned hash(const UCharBuffer &buf)
117  {
118  return UString::Rep::computeHash(buf.s, buf.length);
119  }
120 
121  static bool equal(UString::Rep *str, const UCharBuffer &buf)
122  {
123  return Identifier::equal(str, buf.s, buf.length);
124  }
125 
126  static void translate(UString::Rep *&location, const UCharBuffer &buf, unsigned hash)
127  {
128  UChar *d = static_cast<UChar *>(fastMalloc(sizeof(UChar) * buf.length));
129  for (unsigned i = 0; i != buf.length; i++) {
130  d[i] = buf.s[i];
131  }
132 
133  UString::Rep *r = UString::Rep::create(d, buf.length).releaseRef();
134  r->isIdentifier = 1;
135  r->rc = 0;
136  r->_hash = hash;
137 
138  location = r;
139  }
140 };
141 
142 PassRefPtr<UString::Rep> Identifier::add(const UChar *s, int length)
143 {
144  if (!length) {
145  UString::Rep::empty.hash();
146  return &UString::Rep::empty;
147  }
148 
149  UCharBuffer buf = {s, static_cast<unsigned int>(length)};
150  return *identifierTable().add<UCharBuffer, UCharBufferTranslator>(buf).first;
151 }
152 
153 PassRefPtr<UString::Rep> Identifier::addSlowCase(UString::Rep *r)
154 {
155  assert(!r->isIdentifier);
156 
157  if (r->len == 0) {
158  UString::Rep::empty.hash();
159  return &UString::Rep::empty;
160  }
161 
162  UString::Rep *result = *identifierTable().add(r).first;
163  if (result == r) {
164  r->isIdentifier = true;
165  }
166  return result;
167 }
168 
169 void Identifier::remove(UString::Rep *r)
170 {
171  identifierTable().remove(r);
172 }
173 
174 } // namespace KJS
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Aug 12 2020 22:59:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.