// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org)
package org.xbill.DNS;
import java.util.HashMap;
/**
* A utility class for converting between numeric codes and mnemonics
* for those codes. Mnemonics are case insensitive.
*
* @author Brian Wellington
*/
class Mnemonic {
private static Integer cachedInts[] = new Integer[64];
static {
for (int i = 0; i < cachedInts.length; i++) {
cachedInts[i] = new Integer(i);
}
}
/* Strings are case-sensitive. */
static final int CASE_SENSITIVE = 1;
/* Strings will be stored/searched for in uppercase. */
static final int CASE_UPPER = 2;
/* Strings will be stored/searched for in lowercase. */
static final int CASE_LOWER = 3;
private HashMap strings;
private HashMap values;
private String description;
private int wordcase;
private String prefix;
private int max;
private boolean numericok;
/**
* Creates a new Mnemonic table.
* @param description A short description of the mnemonic to use when
* @param wordcase Whether to convert strings into uppercase, lowercase,
* or leave them unchanged.
* throwing exceptions.
*/
public
Mnemonic(String description, int wordcase) {
this.description = description;
this.wordcase = wordcase;
strings = new HashMap();
values = new HashMap();
max = Integer.MAX_VALUE;
}
/** Sets the maximum numeric value */
public void
setMaximum(int max) {
this.max = max;
}
/**
* Sets the prefix to use when converting to and from values that don't
* have mnemonics.
*/
public void
setPrefix(String prefix) {
this.prefix = sanitize(prefix);
}
/**
* Sets whether numeric values stored in strings are acceptable.
*/
public void
setNumericAllowed(boolean numeric) {
this.numericok = numeric;
}
/**
* Converts an int into a possibly cached Integer.
*/
public static Integer
toInteger(int val) {
if (val >= 0 && val < cachedInts.length)
return (cachedInts[val]);
return new Integer(val);
}
/**
* Checks that a numeric value is within the range [0..max]
*/
public void
check(int val) {
if (val < 0 || val > max) {
throw new IllegalArgumentException(description + " " + val +
"is out of range");
}
}
/* Converts a String to the correct case. */
private String
sanitize(String str) {
if (wordcase == CASE_UPPER)
return str.toUpperCase();
else if (wordcase == CASE_LOWER)
return str.toLowerCase();
return str;
}
private int
parseNumeric(String s) {
try {
int val = Integer.parseInt(s);
if (val >= 0 && val <= max)
return val;
}
catch (NumberFormatException e) {
}
return -1;
}
/**
* Defines the text representation of a numeric value.
* @param val The numeric value
* @param string The text string
*/
public void
add(int val, String str) {
check(val);
Integer value = toInteger(val);
str = sanitize(str);
strings.put(str, value);
values.put(value, str);
}
/**
* Defines an additional text representation of a numeric value. This will
* be used by getValue(), but not getText().
* @param val The numeric value
* @param string The text string
*/
public void
addAlias(int val, String str) {
check(val);
Integer value = toInteger(val);
str = sanitize(str);
strings.put(str, value);
}
/**
* Copies all mnemonics from one table into another.
* @param val The numeric value
* @param string The text string
* @throws IllegalArgumentException The wordcases of the Mnemonics do not
* match.
*/
public void
addAll(Mnemonic source) {
if (wordcase != source.wordcase)
throw new IllegalArgumentException(source.description +
": wordcases do not match");
strings.putAll(source.strings);
values.putAll(source.values);
}
/**
* Gets the text mnemonic corresponding to a numeric value.
* @param val The numeric value
* @return The corresponding text mnemonic.
*/
public String
getText(int val) {
check(val);
String str = (String) values.get(toInteger(val));
if (str != null)
return str;
str = Integer.toString(val);
if (prefix != null)
return prefix + str;
return str;
}
/**
* Gets the numeric value corresponding to a text mnemonic.
* @param str The text mnemonic
* @return The corresponding numeric value, or -1 if there is none
*/
public int
getValue(String str) {
str = sanitize(str);
Integer value = (Integer) strings.get(str);
if (value != null) {
return value.intValue();
}
if (prefix != null) {
if (str.startsWith(prefix)) {
int val = parseNumeric(str.substring(prefix.length()));
if (val >= 0) {
return val;
}
}
}
if (numericok) {
return parseNumeric(str);
}
return -1;
}
}