package water.parser; import water.util.StringUtils; import java.io.*; import java.util.Arrays; import static water.util.ArrayUtils.*; /** * Recreated "packed domains" functionality, with tests * * Created by vpatryshev on 4/12/17. */ public class PackedDomains { public static int sizeOf(byte[] domain) { return encodeAsInt(domain, 0); } public static String[] unpackToStrings(byte[] domain) { int n = sizeOf(domain); String[] out = new String[n]; int p = 4; for (int i = 0; i < n; i++) { int p0 = p; while (domain[p] != 0 && p++ < domain.length); out[i] = StringUtils.toString(domain, p0, p - p0); p++; } return out; } /** this one is for testing */ static byte[] pack(String... source) { BufferedString[] bss = new BufferedString[source.length]; for (int i = 0; i < source.length; i++) { bss[i] = new BufferedString(source[i]); } return pack(bss); } private static final byte[] ZEROES = new byte[]{0,0,0,0}; public static byte[] pack(BufferedString[] source) { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { out.write(ZEROES); for (BufferedString bs : source) { out.write(bs.getBuffer(), bs.getOffset(), bs.length() - bs.getOffset()); out.write(ZEROES, 0, 1); } } catch (IOException ignore) {} byte[] bytes = out.toByteArray(); decodeAsInt(source.length, bytes, 0); return bytes; } private static void dump(InputStream from, OutputStream to) { try { int b; while ((b = from.read()) >= 0) to.write(b); } catch (IOException ignore) {} } private static void dumpWord(InputStream from, OutputStream to) { try { int b; while ((b = from.read()) > 0) to.write(b); to.write(0); } catch (IOException ignore) {} } public static byte[] merge(byte[] as, byte[] bs) { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream ia = new ByteArrayInputStream(as, 4, as.length); InputStream ib = new ByteArrayInputStream(bs, 4, bs.length); try { out.write(ZEROES); ia.mark(0); ib.mark(0); while (ia.available() > 0 || ib.available() > 0) { if (ia.available() == 0) dump(ib, out); else if (ib.available() == 0) dump(ia, out); else { int a = ia.read(); int b = ib.read(); if (a == b) { out.write(a); if (a == 0) { ia.mark(0); ib.mark(0); } } else if (a < b) { out.write(a); if (a != 0) dumpWord(ia, out); ia.mark(0); ib.reset(); } else { out.write(b); if (b != 0) dumpWord(ib, out); ib.mark(0); ia.reset(); } } } } catch (IOException ignore) {} byte[] bytes = out.toByteArray(); int n = 0; for (byte b : bytes) if (b == 0) n++; decodeAsInt(n - 4, bytes, 0); return bytes; } }