Improved memory/gc usage, replaced generic hashmaps with implementation
specific versions.
This commit is contained in:
parent
4d87ba10c1
commit
dc54c9b226
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
package dorkbox.network.dns;
|
package dorkbox.network.dns;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import com.esotericsoftware.kryo.util.IntMap;
|
||||||
|
|
||||||
|
import dorkbox.util.collections.ObjectIntMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A utility class for converting between numeric codes and mnemonics
|
* A utility class for converting between numeric codes and mnemonics
|
||||||
@ -13,29 +15,21 @@ import java.util.HashMap;
|
|||||||
public
|
public
|
||||||
class Mnemonic {
|
class Mnemonic {
|
||||||
|
|
||||||
private static Integer cachedInts[] = new Integer[64];
|
|
||||||
/* Strings are case-sensitive. */
|
/* Strings are case-sensitive. */
|
||||||
public static final int CASE_SENSITIVE = 1;
|
public static final int CASE_SENSITIVE = 1;
|
||||||
/* Strings will be stored/searched for in uppercase. */
|
/* Strings will be stored/searched for in uppercase. */
|
||||||
public static final int CASE_UPPER = 2;
|
public static final int CASE_UPPER = 2;
|
||||||
/* Strings will be stored/searched for in lowercase. */
|
/* Strings will be stored/searched for in lowercase. */
|
||||||
public static final int CASE_LOWER = 3;
|
public static final int CASE_LOWER = 3;
|
||||||
|
private static final int INVALID_VALUE = -1;
|
||||||
|
private ObjectIntMap<String> strings;
|
||||||
private HashMap<String, Integer> strings;
|
private IntMap<String> values;
|
||||||
private HashMap<Integer, String> values;
|
|
||||||
private String description;
|
private String description;
|
||||||
private int wordcase;
|
private int wordcase;
|
||||||
private String prefix;
|
private String prefix;
|
||||||
private int max;
|
private int max;
|
||||||
private boolean numericok;
|
private boolean numericok;
|
||||||
|
|
||||||
static {
|
|
||||||
for (int i = 0; i < cachedInts.length; i++) {
|
|
||||||
cachedInts[i] = new Integer(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Mnemonic table.
|
* Creates a new Mnemonic table.
|
||||||
*
|
*
|
||||||
@ -48,8 +42,8 @@ class Mnemonic {
|
|||||||
Mnemonic(String description, int wordcase) {
|
Mnemonic(String description, int wordcase) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.wordcase = wordcase;
|
this.wordcase = wordcase;
|
||||||
strings = new HashMap();
|
strings = new ObjectIntMap<String>();
|
||||||
values = new HashMap();
|
values = new IntMap<String>();
|
||||||
max = Integer.MAX_VALUE;
|
max = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,29 +87,17 @@ class Mnemonic {
|
|||||||
/**
|
/**
|
||||||
* Defines the text representation of a numeric value.
|
* Defines the text representation of a numeric value.
|
||||||
*
|
*
|
||||||
* @param val The numeric value
|
* @param value The numeric value
|
||||||
* @param string The text string
|
* @param string The text string
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void add(int val, String string) {
|
void add(int value, String string) {
|
||||||
check(val);
|
check(value);
|
||||||
Integer value = toInteger(val);
|
|
||||||
string = sanitize(string);
|
string = sanitize(string);
|
||||||
strings.put(string, value);
|
strings.put(string, value);
|
||||||
values.put(value, string);
|
values.put(value, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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]
|
* Checks that a numeric value is within the range [0..max]
|
||||||
*/
|
*/
|
||||||
@ -130,13 +112,12 @@ class Mnemonic {
|
|||||||
* Defines an additional text representation of a numeric value. This will
|
* Defines an additional text representation of a numeric value. This will
|
||||||
* be used by getValue(), but not getText().
|
* be used by getValue(), but not getText().
|
||||||
*
|
*
|
||||||
* @param val The numeric value
|
* @param value The numeric value
|
||||||
* @param string The text string
|
* @param string The text string
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
void addAlias(int val, String string) {
|
void addAlias(int value, String string) {
|
||||||
check(val);
|
check(value);
|
||||||
Integer value = toInteger(val);
|
|
||||||
string = sanitize(string);
|
string = sanitize(string);
|
||||||
strings.put(string, value);
|
strings.put(string, value);
|
||||||
}
|
}
|
||||||
@ -154,6 +135,7 @@ class Mnemonic {
|
|||||||
if (wordcase != source.wordcase) {
|
if (wordcase != source.wordcase) {
|
||||||
throw new IllegalArgumentException(source.description + ": wordcases do not match");
|
throw new IllegalArgumentException(source.description + ": wordcases do not match");
|
||||||
}
|
}
|
||||||
|
|
||||||
strings.putAll(source.strings);
|
strings.putAll(source.strings);
|
||||||
values.putAll(source.values);
|
values.putAll(source.values);
|
||||||
}
|
}
|
||||||
@ -161,18 +143,19 @@ class Mnemonic {
|
|||||||
/**
|
/**
|
||||||
* Gets the text mnemonic corresponding to a numeric value.
|
* Gets the text mnemonic corresponding to a numeric value.
|
||||||
*
|
*
|
||||||
* @param val The numeric value
|
* @param value The numeric value
|
||||||
*
|
*
|
||||||
* @return The corresponding text mnemonic.
|
* @return The corresponding text mnemonic.
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
String getText(int val) {
|
String getText(int value) {
|
||||||
check(val);
|
check(value);
|
||||||
String str = (String) values.get(toInteger(val));
|
String str = values.get(value);
|
||||||
if (str != null) {
|
if (str != null) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
str = Integer.toString(val);
|
|
||||||
|
str = Integer.toString(value);
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
return prefix + str;
|
return prefix + str;
|
||||||
}
|
}
|
||||||
@ -189,9 +172,10 @@ class Mnemonic {
|
|||||||
public
|
public
|
||||||
int getValue(String str) {
|
int getValue(String str) {
|
||||||
str = sanitize(str);
|
str = sanitize(str);
|
||||||
Integer value = (Integer) strings.get(str);
|
int value = strings.get(str, INVALID_VALUE);
|
||||||
if (value != null) {
|
|
||||||
return value.intValue();
|
if (value != INVALID_VALUE) {
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
if (str.startsWith(prefix)) {
|
if (str.startsWith(prefix)) {
|
||||||
@ -204,7 +188,8 @@ class Mnemonic {
|
|||||||
if (numericok) {
|
if (numericok) {
|
||||||
return parseNumeric(str);
|
return parseNumeric(str);
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
return INVALID_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -214,9 +199,9 @@ class Mnemonic {
|
|||||||
if (val >= 0 && val <= max) {
|
if (val >= 0 && val <= max) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException ignored) {
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return INVALID_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
package dorkbox.network.dns.constants;
|
package dorkbox.network.dns.constants;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import dorkbox.network.dns.Mnemonic;
|
import dorkbox.network.dns.Mnemonic;
|
||||||
import dorkbox.network.dns.exceptions.InvalidTypeException;
|
import dorkbox.network.dns.exceptions.InvalidTypeException;
|
||||||
import dorkbox.network.dns.records.DnsRecord;
|
import dorkbox.network.dns.records.DnsRecord;
|
||||||
import dorkbox.network.dns.records.DnsTypeProtoAssignment;
|
import dorkbox.network.dns.records.DnsTypeProtoAssignment;
|
||||||
|
import dorkbox.util.collections.IntMap;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -449,25 +448,26 @@ class DnsRecordType {
|
|||||||
|
|
||||||
public static
|
public static
|
||||||
class TypeMnemonic extends Mnemonic {
|
class TypeMnemonic extends Mnemonic {
|
||||||
private HashMap objects;
|
private IntMap<DnsRecord> objects;
|
||||||
|
|
||||||
public
|
public
|
||||||
TypeMnemonic() {
|
TypeMnemonic() {
|
||||||
super("DnsRecordType", CASE_UPPER);
|
super("DnsRecordType", CASE_UPPER);
|
||||||
setPrefix("TYPE");
|
setPrefix("TYPE");
|
||||||
objects = new HashMap();
|
objects = new IntMap<DnsRecord>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
void add(int val, String str, DnsRecord proto) {
|
void add(int value, String str, DnsRecord proto) {
|
||||||
super.add(val, str);
|
super.add(value, str);
|
||||||
objects.put(Mnemonic.toInteger(val), proto);
|
objects.put(value, proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public
|
public
|
||||||
<T extends DnsRecord> T getProto(int val) {
|
<T extends DnsRecord> T getProto(int value) {
|
||||||
check(val);
|
check(value);
|
||||||
return (T) objects.get(toInteger(val));
|
return (T) objects.get(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,16 +5,14 @@ package dorkbox.network.dns.records;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
import com.esotericsoftware.kryo.util.ObjectMap;
|
||||||
|
|
||||||
import dorkbox.network.dns.DnsOutput;
|
import dorkbox.network.dns.DnsOutput;
|
||||||
import dorkbox.network.dns.Name;
|
import dorkbox.network.dns.Name;
|
||||||
import dorkbox.network.dns.constants.DnsClass;
|
import dorkbox.network.dns.constants.DnsClass;
|
||||||
@ -32,6 +30,7 @@ import dorkbox.util.Base64Fast;
|
|||||||
* @see TSIGRecord
|
* @see TSIGRecord
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
public
|
public
|
||||||
class TSIG {
|
class TSIG {
|
||||||
|
|
||||||
@ -72,9 +71,10 @@ class TSIG {
|
|||||||
*/
|
*/
|
||||||
public static final Name HMAC_SHA512 = Name.fromConstantString("hmac-sha512.");
|
public static final Name HMAC_SHA512 = Name.fromConstantString("hmac-sha512.");
|
||||||
|
|
||||||
private static Map algMap;
|
private static final ObjectMap<Name, String> algMap = new ObjectMap<Name, String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default fudge value for outgoing packets. Can be overriden by the
|
* The default fudge value for outgoing packets. Can be overridden by the
|
||||||
* tsigfudge option.
|
* tsigfudge option.
|
||||||
*/
|
*/
|
||||||
public static final short FUDGE = 300;
|
public static final short FUDGE = 300;
|
||||||
@ -82,14 +82,12 @@ class TSIG {
|
|||||||
private Mac hmac;
|
private Mac hmac;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Map out = new HashMap();
|
algMap.put(HMAC_MD5, "HmacMD5");
|
||||||
out.put(HMAC_MD5, "HmacMD5");
|
algMap.put(HMAC_SHA1, "HmacSHA1");
|
||||||
out.put(HMAC_SHA1, "HmacSHA1");
|
algMap.put(HMAC_SHA224, "HmacSHA224");
|
||||||
out.put(HMAC_SHA224, "HmacSHA224");
|
algMap.put(HMAC_SHA256, "HmacSHA256");
|
||||||
out.put(HMAC_SHA256, "HmacSHA256");
|
algMap.put(HMAC_SHA384, "HmacSHA384");
|
||||||
out.put(HMAC_SHA384, "HmacSHA384");
|
algMap.put(HMAC_SHA512, "HmacSHA512");
|
||||||
out.put(HMAC_SHA512, "HmacSHA512");
|
|
||||||
algMap = Collections.unmodifiableMap(out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,7 +141,7 @@ class TSIG {
|
|||||||
|
|
||||||
public static
|
public static
|
||||||
String nameToAlgorithm(Name name) {
|
String nameToAlgorithm(Name name) {
|
||||||
String alg = (String) algMap.get(name);
|
String alg = algMap.get(name);
|
||||||
if (alg != null) {
|
if (alg != null) {
|
||||||
return alg;
|
return alg;
|
||||||
}
|
}
|
||||||
@ -177,14 +175,13 @@ class TSIG {
|
|||||||
|
|
||||||
public static
|
public static
|
||||||
Name algorithmToName(String alg) {
|
Name algorithmToName(String alg) {
|
||||||
Iterator it = algMap.entrySet()
|
|
||||||
.iterator();
|
// false identity check because it's string comparisons.
|
||||||
while (it.hasNext()) {
|
Name foundKey = algMap.findKey(alg, false);
|
||||||
Map.Entry entry = (Map.Entry) it.next();
|
if (foundKey != null) {
|
||||||
if (alg.equalsIgnoreCase((String) entry.getValue())) {
|
return foundKey;
|
||||||
return (Name) entry.getKey();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("Unknown algorithm");
|
throw new IllegalArgumentException("Unknown algorithm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,59 +15,66 @@ import java.util.TreeSet;
|
|||||||
|
|
||||||
import dorkbox.network.dns.DnsInput;
|
import dorkbox.network.dns.DnsInput;
|
||||||
import dorkbox.network.dns.DnsOutput;
|
import dorkbox.network.dns.DnsOutput;
|
||||||
import dorkbox.network.dns.Mnemonic;
|
|
||||||
import dorkbox.network.dns.constants.DnsRecordType;
|
import dorkbox.network.dns.constants.DnsRecordType;
|
||||||
import dorkbox.network.dns.exceptions.WireParseException;
|
import dorkbox.network.dns.exceptions.WireParseException;
|
||||||
import dorkbox.network.dns.utils.Tokenizer;
|
import dorkbox.network.dns.utils.Tokenizer;
|
||||||
|
import dorkbox.util.collections.IntMap;
|
||||||
|
import dorkbox.util.collections.IntMap.Keys;
|
||||||
|
|
||||||
final
|
final
|
||||||
class TypeBitmap implements Serializable {
|
class TypeBitmap implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -125354057735389003L;
|
private static final long serialVersionUID = -125354057735389003L;
|
||||||
|
|
||||||
private TreeSet types;
|
private IntMap<Boolean> types;
|
||||||
|
|
||||||
public
|
public
|
||||||
TypeBitmap(int[] array) {
|
TypeBitmap(int[] array) {
|
||||||
this();
|
this();
|
||||||
for (int i = 0; i < array.length; i++) {
|
for (int i = 0; i < array.length; i++) {
|
||||||
DnsRecordType.check(array[i]);
|
DnsRecordType.check(array[i]);
|
||||||
types.add(new Integer(array[i]));
|
types.put(array[i], Boolean.TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
TypeBitmap() {
|
TypeBitmap() {
|
||||||
types = new TreeSet();
|
types = new IntMap<Boolean>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
TypeBitmap(DnsInput in) throws WireParseException {
|
TypeBitmap(DnsInput in) throws WireParseException {
|
||||||
this();
|
this();
|
||||||
int lastbase = -1;
|
int lastbase = -1;
|
||||||
|
|
||||||
while (in.remaining() > 0) {
|
while (in.remaining() > 0) {
|
||||||
if (in.remaining() < 2) {
|
if (in.remaining() < 2) {
|
||||||
throw new WireParseException("invalid bitmap descriptor");
|
throw new WireParseException("invalid bitmap descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
int mapbase = in.readU8();
|
int mapbase = in.readU8();
|
||||||
if (mapbase < lastbase) {
|
if (mapbase < lastbase) {
|
||||||
throw new WireParseException("invalid ordering");
|
throw new WireParseException("invalid ordering");
|
||||||
}
|
}
|
||||||
|
|
||||||
int maplength = in.readU8();
|
int maplength = in.readU8();
|
||||||
if (maplength > in.remaining()) {
|
if (maplength > in.remaining()) {
|
||||||
throw new WireParseException("invalid bitmap");
|
throw new WireParseException("invalid bitmap");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < maplength; i++) {
|
for (int i = 0; i < maplength; i++) {
|
||||||
int current = in.readU8();
|
int current = in.readU8();
|
||||||
if (current == 0) {
|
if (current == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
if ((current & (1 << (7 - j))) == 0) {
|
if ((current & (1 << (7 - j))) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int typecode = mapbase * 256 + +i * 8 + j;
|
int typecode = mapbase * 256 + +i * 8 + j;
|
||||||
types.add(Mnemonic.toInteger(typecode));
|
types.put(typecode, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,54 +83,71 @@ class TypeBitmap implements Serializable {
|
|||||||
public
|
public
|
||||||
TypeBitmap(Tokenizer st) throws IOException {
|
TypeBitmap(Tokenizer st) throws IOException {
|
||||||
this();
|
this();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
Tokenizer.Token t = st.get();
|
Tokenizer.Token t = st.get();
|
||||||
if (!t.isString()) {
|
if (!t.isString()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int typecode = DnsRecordType.value(t.value);
|
int typecode = DnsRecordType.value(t.value);
|
||||||
if (typecode < 0) {
|
if (typecode < 0) {
|
||||||
throw st.exception("Invalid type: " + t.value);
|
throw st.exception("Invalid type: " + t.value);
|
||||||
}
|
}
|
||||||
types.add(Mnemonic.toInteger(typecode));
|
|
||||||
|
types.put(typecode, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
st.unget();
|
st.unget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
int[] toArray() {
|
int[] toArray() {
|
||||||
int[] array = new int[types.size()];
|
int[] array = new int[types.size];
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (Iterator it = types.iterator(); it.hasNext(); ) {
|
|
||||||
array[n++] = ((Integer) it.next()).intValue();
|
|
||||||
|
Keys keys = types.keys();
|
||||||
|
while (keys.hasNext) {
|
||||||
|
array[n++] = keys.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public
|
public
|
||||||
String toString() {
|
String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (Iterator it = types.iterator(); it.hasNext(); ) {
|
|
||||||
int t = ((Integer) it.next()).intValue();
|
Keys keys = types.keys();
|
||||||
sb.append(DnsRecordType.string(t));
|
while (keys.hasNext) {
|
||||||
if (it.hasNext()) {
|
int t = keys.next();
|
||||||
sb.append(' ');
|
sb.append(DnsRecordType.string(t))
|
||||||
|
.append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove the last ' '
|
||||||
|
int length = sb.length();
|
||||||
|
if (length > 1) {
|
||||||
|
sb.delete(length - 1, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
void toWire(DnsOutput out) {
|
void toWire(DnsOutput out) {
|
||||||
if (types.size() == 0) {
|
if (types.size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mapbase = -1;
|
int mapbase = -1;
|
||||||
TreeSet map = new TreeSet();
|
TreeSet map = new TreeSet();
|
||||||
|
|
||||||
for (Iterator it = types.iterator(); it.hasNext(); ) {
|
Keys keys = types.keys();
|
||||||
int t = ((Integer) it.next()).intValue();
|
while (keys.hasNext) {
|
||||||
|
int t = keys.next();
|
||||||
|
|
||||||
int base = t >> 8;
|
int base = t >> 8;
|
||||||
if (base != mapbase) {
|
if (base != mapbase) {
|
||||||
if (map.size() > 0) {
|
if (map.size() > 0) {
|
||||||
@ -134,20 +158,27 @@ class TypeBitmap implements Serializable {
|
|||||||
}
|
}
|
||||||
map.add(new Integer(t));
|
map.add(new Integer(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
mapToWire(out, map, mapbase);
|
mapToWire(out, map, mapbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param map this must be an ordered data structure!
|
||||||
|
*/
|
||||||
private static
|
private static
|
||||||
void mapToWire(DnsOutput out, TreeSet map, int mapbase) {
|
void mapToWire(DnsOutput out, TreeSet map, int mapbase) {
|
||||||
int arraymax = (((Integer) map.last()).intValue()) & 0xFF;
|
int arraymax = (((Integer) map.last()).intValue()) & 0xFF;
|
||||||
int arraylength = (arraymax / 8) + 1;
|
int arraylength = (arraymax / 8) + 1;
|
||||||
int[] array = new int[arraylength];
|
int[] array = new int[arraylength];
|
||||||
|
|
||||||
out.writeU8(mapbase);
|
out.writeU8(mapbase);
|
||||||
out.writeU8(arraylength);
|
out.writeU8(arraylength);
|
||||||
|
|
||||||
for (Iterator it = map.iterator(); it.hasNext(); ) {
|
for (Iterator it = map.iterator(); it.hasNext(); ) {
|
||||||
int typecode = ((Integer) it.next()).intValue();
|
int typecode = ((Integer) it.next()).intValue();
|
||||||
array[(typecode & 0xFF) / 8] |= (1 << (7 - typecode % 8));
|
array[(typecode & 0xFF) / 8] |= (1 << (7 - typecode % 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < arraylength; j++) {
|
for (int j = 0; j < arraylength; j++) {
|
||||||
out.writeU8(array[j]);
|
out.writeU8(array[j]);
|
||||||
}
|
}
|
||||||
@ -155,12 +186,11 @@ class TypeBitmap implements Serializable {
|
|||||||
|
|
||||||
public
|
public
|
||||||
boolean empty() {
|
boolean empty() {
|
||||||
return types.isEmpty();
|
return types.size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
public
|
||||||
boolean contains(int typecode) {
|
boolean contains(int typecode) {
|
||||||
return types.contains(Mnemonic.toInteger(typecode));
|
return types.containsKey(typecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,39 +54,12 @@ class MnemonicTest extends TestCase {
|
|||||||
m_mn = new Mnemonic(MnemonicTest.class.getName() + " UPPER", Mnemonic.CASE_UPPER);
|
m_mn = new Mnemonic(MnemonicTest.class.getName() + " UPPER", Mnemonic.CASE_UPPER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public
|
|
||||||
void test_toInteger() {
|
|
||||||
Integer i = Mnemonic.toInteger(64);
|
|
||||||
assertEquals(new Integer(64), i);
|
|
||||||
Integer i2 = Mnemonic.toInteger(64);
|
|
||||||
assertEquals(i, i2);
|
|
||||||
assertNotSame(i, i2);
|
|
||||||
|
|
||||||
i = Mnemonic.toInteger(-1);
|
|
||||||
assertEquals(new Integer(-1), i);
|
|
||||||
i2 = Mnemonic.toInteger(-1);
|
|
||||||
assertEquals(i, i2);
|
|
||||||
assertNotSame(i, i2);
|
|
||||||
|
|
||||||
i = Mnemonic.toInteger(0);
|
|
||||||
assertEquals(new Integer(0), i);
|
|
||||||
i2 = Mnemonic.toInteger(0);
|
|
||||||
assertEquals(i, i2);
|
|
||||||
assertSame(i, i2);
|
|
||||||
|
|
||||||
i = Mnemonic.toInteger(63);
|
|
||||||
assertEquals(new Integer(63), i);
|
|
||||||
i2 = Mnemonic.toInteger(63);
|
|
||||||
assertEquals(i, i2);
|
|
||||||
assertSame(i, i2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public
|
public
|
||||||
void test_no_maximum() {
|
void test_no_maximum() {
|
||||||
try {
|
try {
|
||||||
m_mn.check(-1);
|
m_mn.check(-1);
|
||||||
fail("IllegalArgumentException not thrown");
|
fail("IllegalArgumentException not thrown");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException ignored) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
m_mn.check(0);
|
m_mn.check(0);
|
||||||
@ -117,7 +90,7 @@ class MnemonicTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
m_mn.check(-1);
|
m_mn.check(-1);
|
||||||
fail("IllegalArgumentException not thrown");
|
fail("IllegalArgumentException not thrown");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException ignored) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
m_mn.check(0);
|
m_mn.check(0);
|
||||||
@ -132,7 +105,7 @@ class MnemonicTest extends TestCase {
|
|||||||
try {
|
try {
|
||||||
m_mn.check(16);
|
m_mn.check(16);
|
||||||
fail("IllegalArgumentException not thrown");
|
fail("IllegalArgumentException not thrown");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// need numericok to exercise the usage of max in parseNumeric
|
// need numericok to exercise the usage of max in parseNumeric
|
||||||
|
Loading…
Reference in New Issue
Block a user