• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2004 Brian Wellington (bwelling@xbill.org)
2 
3 package org.xbill.DNS;
4 
5 import java.util.HashMap;
6 
7 /**
8  * A utility class for converting between numeric codes and mnemonics
9  * for those codes.  Mnemonics are case insensitive.
10  *
11  * @author Brian Wellington
12  */
13 
14 class Mnemonic {
15 
16 private static Integer cachedInts[] = new Integer[64];
17 
18 static {
19 	for (int i = 0; i < cachedInts.length; i++) {
20 		cachedInts[i] = new Integer(i);
21 	}
22 }
23 
24 /* Strings are case-sensitive. */
25 static final int CASE_SENSITIVE = 1;
26 
27 /* Strings will be stored/searched for in uppercase. */
28 static final int CASE_UPPER = 2;
29 
30 /* Strings will be stored/searched for in lowercase. */
31 static final int CASE_LOWER = 3;
32 
33 private HashMap strings;
34 private HashMap values;
35 private String description;
36 private int wordcase;
37 private String prefix;
38 private int max;
39 private boolean numericok;
40 
41 /**
42  * Creates a new Mnemonic table.
43  * @param description A short description of the mnemonic to use when
44  * @param wordcase Whether to convert strings into uppercase, lowercase,
45  * or leave them unchanged.
46  * throwing exceptions.
47  */
48 public
Mnemonic(String description, int wordcase)49 Mnemonic(String description, int wordcase) {
50 	this.description = description;
51 	this.wordcase = wordcase;
52 	strings = new HashMap();
53 	values = new HashMap();
54 	max = Integer.MAX_VALUE;
55 }
56 
57 /** Sets the maximum numeric value */
58 public void
setMaximum(int max)59 setMaximum(int max) {
60 	this.max = max;
61 }
62 
63 /**
64  * Sets the prefix to use when converting to and from values that don't
65  * have mnemonics.
66  */
67 public void
setPrefix(String prefix)68 setPrefix(String prefix) {
69 	this.prefix = sanitize(prefix);
70 }
71 
72 /**
73  * Sets whether numeric values stored in strings are acceptable.
74  */
75 public void
setNumericAllowed(boolean numeric)76 setNumericAllowed(boolean numeric) {
77 	this.numericok = numeric;
78 }
79 
80 /**
81  * Converts an int into a possibly cached Integer.
82  */
83 public static Integer
toInteger(int val)84 toInteger(int val) {
85 	if (val >= 0 && val < cachedInts.length)
86 		return (cachedInts[val]);
87 	return new Integer(val);
88 }
89 
90 /**
91  * Checks that a numeric value is within the range [0..max]
92  */
93 public void
check(int val)94 check(int val) {
95 	if (val < 0 || val > max) {
96 		throw new IllegalArgumentException(description + " " + val +
97 						   "is out of range");
98 	}
99 }
100 
101 /* Converts a String to the correct case. */
102 private String
sanitize(String str)103 sanitize(String str) {
104 	if (wordcase == CASE_UPPER)
105 		return str.toUpperCase();
106 	else if (wordcase == CASE_LOWER)
107 		return str.toLowerCase();
108 	return str;
109 }
110 
111 private int
parseNumeric(String s)112 parseNumeric(String s) {
113 	try {
114 		int val = Integer.parseInt(s);
115 		if (val >= 0 && val <= max)
116 			return val;
117 	}
118 	catch (NumberFormatException e) {
119 	}
120 	return -1;
121 }
122 
123 /**
124  * Defines the text representation of a numeric value.
125  * @param val The numeric value
126  * @param string The text string
127  */
128 public void
add(int val, String str)129 add(int val, String str) {
130 	check(val);
131 	Integer value = toInteger(val);
132 	str = sanitize(str);
133 	strings.put(str, value);
134 	values.put(value, str);
135 }
136 
137 /**
138  * Defines an additional text representation of a numeric value.  This will
139  * be used by getValue(), but not getText().
140  * @param val The numeric value
141  * @param string The text string
142  */
143 public void
addAlias(int val, String str)144 addAlias(int val, String str) {
145 	check(val);
146 	Integer value = toInteger(val);
147 	str = sanitize(str);
148 	strings.put(str, value);
149 }
150 
151 /**
152  * Copies all mnemonics from one table into another.
153  * @param val The numeric value
154  * @param string The text string
155  * @throws IllegalArgumentException The wordcases of the Mnemonics do not
156  * match.
157  */
158 public void
addAll(Mnemonic source)159 addAll(Mnemonic source) {
160 	if (wordcase != source.wordcase)
161 		throw new IllegalArgumentException(source.description +
162 						   ": wordcases do not match");
163 	strings.putAll(source.strings);
164 	values.putAll(source.values);
165 }
166 
167 /**
168  * Gets the text mnemonic corresponding to a numeric value.
169  * @param val The numeric value
170  * @return The corresponding text mnemonic.
171  */
172 public String
getText(int val)173 getText(int val) {
174 	check(val);
175 	String str = (String) values.get(toInteger(val));
176 	if (str != null)
177 		return str;
178 	str = Integer.toString(val);
179 	if (prefix != null)
180 		return prefix + str;
181 	return str;
182 }
183 
184 /**
185  * Gets the numeric value corresponding to a text mnemonic.
186  * @param str The text mnemonic
187  * @return The corresponding numeric value, or -1 if there is none
188  */
189 public int
getValue(String str)190 getValue(String str) {
191 	str = sanitize(str);
192 	Integer value = (Integer) strings.get(str);
193 	if (value != null) {
194 		return value.intValue();
195 	}
196 	if (prefix != null) {
197 		if (str.startsWith(prefix)) {
198 			int val = parseNumeric(str.substring(prefix.length()));
199 			if (val >= 0) {
200 				return val;
201 			}
202 		}
203 	}
204 	if (numericok) {
205 		return parseNumeric(str);
206 	}
207 	return -1;
208 }
209 
210 }
211