diff options
author | Florian Schmaus <flo@geekplace.eu> | 2014-06-08 13:18:46 +0200 |
---|---|---|
committer | Florian Schmaus <flo@geekplace.eu> | 2014-06-08 13:27:25 +0200 |
commit | 3236432c39f1d5a1bbbe362c5cfdb088756fd04f (patch) | |
tree | 3e67a0bed7fdd2d7525eca395c7f0dfd44bc64f5 /src/main/java/de/measite/minidns/util/NameUtil.java | |
parent | 152be6eb1a22da8cebe24ac4ee05b487936c9f2a (diff) |
Make minidns Android agnostic
there is really no need for minidns to be Android exclusive. Replacing
the Android log API with JUL make minidns available for Android and Java
SE.
Diffstat (limited to 'src/main/java/de/measite/minidns/util/NameUtil.java')
-rw-r--r-- | src/main/java/de/measite/minidns/util/NameUtil.java | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/main/java/de/measite/minidns/util/NameUtil.java b/src/main/java/de/measite/minidns/util/NameUtil.java new file mode 100644 index 00000000..91a6649d --- /dev/null +++ b/src/main/java/de/measite/minidns/util/NameUtil.java @@ -0,0 +1,91 @@ +package de.measite.minidns.util; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.IDN; +import java.util.HashSet; +import java.util.Arrays; + +public class NameUtil { + + public static int size(String name) { + return name.length() + 2; + } + + public static boolean idnEquals(String name1, String name2) { + if (name1 == name2) return true; // catches null, null + if (name1 == null) return false; + if (name2 == null) return false; + if (name1.equals(name2)) return true; + + try { + return Arrays.equals(toByteArray(name1),toByteArray(name2)); + } catch (IOException e) { + return false; // impossible + } + } + + public static byte[] toByteArray(String name) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(64); + DataOutputStream dos = new DataOutputStream(baos); + for (String s: name.split("[.\u3002\uFF0E\uFF61]")) { + byte[] buffer = IDN.toASCII(s).getBytes(); + dos.writeByte(buffer.length); + dos.write(buffer); + } + dos.writeByte(0); + dos.flush(); + return baos.toByteArray(); + } + + public static String parse(DataInputStream dis, byte data[]) + throws IOException + { + int c = dis.readUnsignedByte(); + if ((c & 0xc0) == 0xc0) { + c = ((c & 0x3f) << 8) + dis.readUnsignedByte(); + HashSet<Integer> jumps = new HashSet<Integer>(); + jumps.add(c); + return parse(data, c, jumps); + } + if (c == 0) { + return ""; + } + byte b[] = new byte[c]; + dis.readFully(b); + String s = IDN.toUnicode(new String(b)); + String t = parse(dis, data); + if (t.length() > 0) { + s = s + "." + t; + } + return s; + } + + public static String parse( + byte data[], + int offset, + HashSet<Integer> jumps + ) { + int c = data[offset] & 0xff; + if ((c & 0xc0) == 0xc0) { + c = ((c & 0x3f) << 8) + (data[offset + 1] & 0xff); + if (jumps.contains(c)) { + throw new IllegalStateException("Cyclic offsets detected."); + } + jumps.add(c); + return parse(data, c, jumps); + } + if (c == 0) { + return ""; + } + String s = new String(data,offset + 1, c); + String t = parse(data, offset + 1 + c, jumps); + if (t.length() > 0) { + s = s + "." + t; + } + return s; + } + +} |