1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
\* */
// $Id$
package scalac.util;
import java.util.HashMap;
/** Instances of this class represent term names. */
public final class TermName extends Name {
//########################################################################
// Private Variables
/** Hashtable from string representation to term names. */
private static HashMap/*<String,TermName>*/ strings = new HashMap();
/** Hashtable from ASCII representation to term names. */
private static TermName[] asciis = new TermName[0x00008000];
//########################################################################
// Private Fields
/** The string representation */
private final String string;
/** The ASCII representation (null if not yet computed) */
private byte[] ascii;
/** The next name stored in the same bucket of the ASCII table */
private TermName next;
//########################################################################
// Private Constructors
/** Initializes this instance. */
private TermName(String string) {
super(2 * strings.size(), null);
this.string = string;
strings.put(string, this);
}
//########################################################################
// Public Factories
/** Returns the term name with given ASCII representation. */
public static TermName fromAscii(byte[] bytes, int start, int count) {
int index = hashValue(bytes, start, count) & (asciis.length - 1);
for (TermName name = asciis[index]; name != null; name = name.next)
if (name.equals(bytes, start, count)) return name;
TermName name = fromString(toString(bytes, start, count));
assert name.ascii == null: name;
byte[] ascii = name.ascii = new byte[count];
for (int i = 0; i < ascii.length; i++) ascii[i] = bytes[start + i];
name.next = asciis[index];
asciis[index] = name;
return name;
}
/** Returns the term name with given string representation. */
public static TermName fromString(String string) {
Object value = strings.get(string);
return value != null ? (TermName)value : new TermName(string);
}
//########################################################################
// Public Methods
/** Returns the string representation of this name. */
public String toString() {
return string;
}
//########################################################################
// Private Methods & Functions
/** Is this name's ASCII representations equal to given one? */
private boolean equals(byte[] bytes, int start, int count) {
if (ascii.length != count) return false;
for (int i = 0; i < count; i++)
if (ascii[i] != bytes[start + i]) return false;
return true;
}
/** Returns the hash code of the ASCII representation. */
private static int hashValue(byte[] bytes, int start, int count) {
if (count <= 0) return 0;
return count * (41 * 41 * 41)
+ bytes[start] * (41 * 41)
+ bytes[start + count - 1] * 41
+ bytes[start + (count >> 1)];
}
/** Turns the ASCII representation into a string. */
private static String toString(byte[] bytes, int start, int count) {
return SourceRepresentation.ascii2string(bytes, start, count);
}
//########################################################################
}
|