aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/measite/minidns/util/NameUtil.java
diff options
context:
space:
mode:
authorFlorian Schmaus <flo@geekplace.eu>2014-06-08 13:18:46 +0200
committerFlorian Schmaus <flo@geekplace.eu>2014-06-08 13:27:25 +0200
commit3236432c39f1d5a1bbbe362c5cfdb088756fd04f (patch)
tree3e67a0bed7fdd2d7525eca395c7f0dfd44bc64f5 /src/main/java/de/measite/minidns/util/NameUtil.java
parent152be6eb1a22da8cebe24ac4ee05b487936c9f2a (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.java91
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;
+ }
+
+}