1package de.measite.minidns.util;
2
3import java.io.ByteArrayOutputStream;
4import java.io.DataInputStream;
5import java.io.DataOutputStream;
6import java.io.IOException;
7import java.net.IDN;
8import java.util.HashSet;
9import java.util.Arrays;
10
11public class NameUtil {
12
13 public static int size(String name) {
14 return name.length() + 2;
15 }
16
17 public static boolean idnEquals(String name1, String name2) {
18 if (name1 == name2) return true; // catches null, null
19 if (name1 == null) return false;
20 if (name2 == null) return false;
21 if (name1.equals(name2)) return true;
22
23 try {
24 return Arrays.equals(toByteArray(name1),toByteArray(name2));
25 } catch (IOException e) {
26 return false; // impossible
27 }
28 }
29
30 public static byte[] toByteArray(String name) throws IOException {
31 ByteArrayOutputStream baos = new ByteArrayOutputStream(64);
32 DataOutputStream dos = new DataOutputStream(baos);
33 for (String s: name.split("[.\u3002\uFF0E\uFF61]")) {
34 byte[] buffer = IDN.toASCII(s).getBytes();
35 dos.writeByte(buffer.length);
36 dos.write(buffer);
37 }
38 dos.writeByte(0);
39 dos.flush();
40 return baos.toByteArray();
41 }
42
43 public static String parse(DataInputStream dis, byte data[])
44 throws IOException
45 {
46 int c = dis.readUnsignedByte();
47 if ((c & 0xc0) == 0xc0) {
48 c = ((c & 0x3f) << 8) + dis.readUnsignedByte();
49 HashSet<Integer> jumps = new HashSet<Integer>();
50 jumps.add(c);
51 return parse(data, c, jumps);
52 }
53 if (c == 0) {
54 return "";
55 }
56 byte b[] = new byte[c];
57 dis.readFully(b);
58 String s = IDN.toUnicode(new String(b));
59 String t = parse(dis, data);
60 if (t.length() > 0) {
61 s = s + "." + t;
62 }
63 return s;
64 }
65
66 public static String parse(
67 byte data[],
68 int offset,
69 HashSet<Integer> jumps
70 ) {
71 int c = data[offset] & 0xff;
72 if ((c & 0xc0) == 0xc0) {
73 c = ((c & 0x3f) << 8) + (data[offset + 1] & 0xff);
74 if (jumps.contains(c)) {
75 throw new IllegalStateException("Cyclic offsets detected.");
76 }
77 jumps.add(c);
78 return parse(data, c, jumps);
79 }
80 if (c == 0) {
81 return "";
82 }
83 String s = new String(data,offset + 1, c);
84 String t = parse(data, offset + 1 + c, jumps);
85 if (t.length() > 0) {
86 s = s + "." + t;
87 }
88 return s;
89 }
90
91}