blob: 628cc35ea6eb4758872e628809c1136861f54bc2 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001// Copyright (c) 2004-2009 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5/**
6 * Routines for deal with the lists of types found in NSEC/NSEC3 records.
7 *
8 * @author Brian Wellington
9 */
10
11import java.io.*;
12import java.util.*;
13
14final class TypeBitmap implements Serializable {
15
16private static final long serialVersionUID = -125354057735389003L;
17
18private TreeSet types;
19
20private
21TypeBitmap() {
22 types = new TreeSet();
23}
24
25public
26TypeBitmap(int [] array) {
27 this();
28 for (int i = 0; i < array.length; i++) {
29 Type.check(array[i]);
30 types.add(new Integer(array[i]));
31 }
32}
33
34public
35TypeBitmap(DNSInput in) throws WireParseException {
36 this();
37 int lastbase = -1;
38 while (in.remaining() > 0) {
39 if (in.remaining() < 2)
40 throw new WireParseException
41 ("invalid bitmap descriptor");
42 int mapbase = in.readU8();
43 if (mapbase < lastbase)
44 throw new WireParseException("invalid ordering");
45 int maplength = in.readU8();
46 if (maplength > in.remaining())
47 throw new WireParseException("invalid bitmap");
48 for (int i = 0; i < maplength; i++) {
49 int current = in.readU8();
50 if (current == 0)
51 continue;
52 for (int j = 0; j < 8; j++) {
53 if ((current & (1 << (7 - j))) == 0)
54 continue;
55 int typecode = mapbase * 256 + + i * 8 + j;
56 types.add(Mnemonic.toInteger(typecode));
57 }
58 }
59 }
60}
61
62public
63TypeBitmap(Tokenizer st) throws IOException {
64 this();
65 while (true) {
66 Tokenizer.Token t = st.get();
67 if (!t.isString())
68 break;
69 int typecode = Type.value(t.value);
70 if (typecode < 0) {
71 throw st.exception("Invalid type: " + t.value);
72 }
73 types.add(Mnemonic.toInteger(typecode));
74 }
75 st.unget();
76}
77
78public int []
79toArray() {
80 int [] array = new int[types.size()];
81 int n = 0;
82 for (Iterator it = types.iterator(); it.hasNext(); )
83 array[n++] = ((Integer)it.next()).intValue();
84 return array;
85}
86
87public String
88toString() {
89 StringBuffer sb = new StringBuffer();
90 for (Iterator it = types.iterator(); it.hasNext(); ) {
91 int t = ((Integer)it.next()).intValue();
92 sb.append(Type.string(t));
93 if (it.hasNext())
94 sb.append(' ');
95 }
96 return sb.toString();
97}
98
99private static void
100mapToWire(DNSOutput out, TreeSet map, int mapbase) {
101 int arraymax = (((Integer)map.last()).intValue()) & 0xFF;
102 int arraylength = (arraymax / 8) + 1;
103 int [] array = new int[arraylength];
104 out.writeU8(mapbase);
105 out.writeU8(arraylength);
106 for (Iterator it = map.iterator(); it.hasNext(); ) {
107 int typecode = ((Integer)it.next()).intValue();
108 array[(typecode & 0xFF) / 8] |= (1 << ( 7 - typecode % 8));
109 }
110 for (int j = 0; j < arraylength; j++)
111 out.writeU8(array[j]);
112}
113
114public void
115toWire(DNSOutput out) {
116 if (types.size() == 0)
117 return;
118
119 int mapbase = -1;
120 TreeSet map = new TreeSet();
121
122 for (Iterator it = types.iterator(); it.hasNext(); ) {
123 int t = ((Integer)it.next()).intValue();
124 int base = t >> 8;
125 if (base != mapbase) {
126 if (map.size() > 0) {
127 mapToWire(out, map, mapbase);
128 map.clear();
129 }
130 mapbase = base;
131 }
132 map.add(new Integer(t));
133 }
134 mapToWire(out, map, mapbase);
135}
136
137public boolean
138empty() {
139 return types.isEmpty();
140}
141
142public boolean
143contains(int typecode) {
144 return types.contains(Mnemonic.toInteger(typecode));
145}
146
147}