aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/measite/minidns/util/NameUtil.java
diff options
context:
space:
mode:
authorRene Treffer <treffer+github@measite.de>2014-06-08 15:37:40 +0200
committerRene Treffer <treffer+github@measite.de>2014-06-08 15:37:40 +0200
commitf66c0db63f0c0b65ad59ac1a8aaadc1cbaf40761 (patch)
treed8f8364ccd928865b04056cdf3ac2c77812a5fa7 /src/main/java/de/measite/minidns/util/NameUtil.java
parent152be6eb1a22da8cebe24ac4ee05b487936c9f2a (diff)
parent52807fe7c415e9977cd2d7191b7e1251c9216256 (diff)
Merge pull request #3 from Flowdalic/androidagnostic
Make minidns Android agnostic
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;
+ }
+
+}