diff options
Diffstat (limited to 'src/org/xbill/DNS/TypeBitmap.java')
-rw-r--r-- | src/org/xbill/DNS/TypeBitmap.java | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/org/xbill/DNS/TypeBitmap.java b/src/org/xbill/DNS/TypeBitmap.java new file mode 100644 index 0000000..628cc35 --- /dev/null +++ b/src/org/xbill/DNS/TypeBitmap.java @@ -0,0 +1,147 @@ +// Copyright (c) 2004-2009 Brian Wellington (bwelling@xbill.org) + +package org.xbill.DNS; + +/** + * Routines for deal with the lists of types found in NSEC/NSEC3 records. + * + * @author Brian Wellington + */ + +import java.io.*; +import java.util.*; + +final class TypeBitmap implements Serializable { + +private static final long serialVersionUID = -125354057735389003L; + +private TreeSet types; + +private +TypeBitmap() { + types = new TreeSet(); +} + +public +TypeBitmap(int [] array) { + this(); + for (int i = 0; i < array.length; i++) { + Type.check(array[i]); + types.add(new Integer(array[i])); + } +} + +public +TypeBitmap(DNSInput in) throws WireParseException { + this(); + int lastbase = -1; + while (in.remaining() > 0) { + if (in.remaining() < 2) + throw new WireParseException + ("invalid bitmap descriptor"); + int mapbase = in.readU8(); + if (mapbase < lastbase) + throw new WireParseException("invalid ordering"); + int maplength = in.readU8(); + if (maplength > in.remaining()) + throw new WireParseException("invalid bitmap"); + for (int i = 0; i < maplength; i++) { + int current = in.readU8(); + if (current == 0) + continue; + for (int j = 0; j < 8; j++) { + if ((current & (1 << (7 - j))) == 0) + continue; + int typecode = mapbase * 256 + + i * 8 + j; + types.add(Mnemonic.toInteger(typecode)); + } + } + } +} + +public +TypeBitmap(Tokenizer st) throws IOException { + this(); + while (true) { + Tokenizer.Token t = st.get(); + if (!t.isString()) + break; + int typecode = Type.value(t.value); + if (typecode < 0) { + throw st.exception("Invalid type: " + t.value); + } + types.add(Mnemonic.toInteger(typecode)); + } + st.unget(); +} + +public int [] +toArray() { + int [] array = new int[types.size()]; + int n = 0; + for (Iterator it = types.iterator(); it.hasNext(); ) + array[n++] = ((Integer)it.next()).intValue(); + return array; +} + +public String +toString() { + StringBuffer sb = new StringBuffer(); + for (Iterator it = types.iterator(); it.hasNext(); ) { + int t = ((Integer)it.next()).intValue(); + sb.append(Type.string(t)); + if (it.hasNext()) + sb.append(' '); + } + return sb.toString(); +} + +private static void +mapToWire(DNSOutput out, TreeSet map, int mapbase) { + int arraymax = (((Integer)map.last()).intValue()) & 0xFF; + int arraylength = (arraymax / 8) + 1; + int [] array = new int[arraylength]; + out.writeU8(mapbase); + out.writeU8(arraylength); + for (Iterator it = map.iterator(); it.hasNext(); ) { + int typecode = ((Integer)it.next()).intValue(); + array[(typecode & 0xFF) / 8] |= (1 << ( 7 - typecode % 8)); + } + for (int j = 0; j < arraylength; j++) + out.writeU8(array[j]); +} + +public void +toWire(DNSOutput out) { + if (types.size() == 0) + return; + + int mapbase = -1; + TreeSet map = new TreeSet(); + + for (Iterator it = types.iterator(); it.hasNext(); ) { + int t = ((Integer)it.next()).intValue(); + int base = t >> 8; + if (base != mapbase) { + if (map.size() > 0) { + mapToWire(out, map, mapbase); + map.clear(); + } + mapbase = base; + } + map.add(new Integer(t)); + } + mapToWire(out, map, mapbase); +} + +public boolean +empty() { + return types.isEmpty(); +} + +public boolean +contains(int typecode) { + return types.contains(Mnemonic.toInteger(typecode)); +} + +} |