package peergos.shared.io.ipfs.multiaddr; import peergos.shared.io.ipfs.multihash.*; import java.io.*; import java.util.*; public class MultiAddress { private final byte[] raw; public MultiAddress(Multihash hash) { this("/ipfs/" + hash.toString()); } public MultiAddress(String address) { this(decodeFromString(address)); } public MultiAddress(byte[] raw) { encodeToString(raw); // check validity this.raw = raw; } public byte[] getBytes() { return Arrays.copyOfRange(raw, 0, raw.length); } public boolean isTCPIP() { String[] parts = toString().substring(1).split("/"); if (parts.length != 4) return false; if (!parts[0].startsWith("ip")) return false; if (!parts[2].equals("tcp")) return false; return true; } public String getHost() { String[] parts = toString().substring(1).split("/"); if (parts[0].startsWith("ip")) return parts[1]; throw new IllegalStateException("This multiaddress doesn't have a host: "+toString()); } public int getTCPPort() { String[] parts = toString().substring(1).split("/"); if (parts[2].startsWith("tcp")) return Integer.parseInt(parts[3]); throw new IllegalStateException("This multiaddress doesn't have a tcp port: "+toString()); } private static byte[] decodeFromString(String addr) { while (addr.endsWith("/")) addr = addr.substring(0, addr.length()-1); String[] parts = addr.split("/"); if (parts[0].length() != 0) throw new IllegalStateException("MultiAddress must start with a /"); ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { for (int i = 1; i < parts.length;) { String part = parts[i++]; Protocol p = Protocol.get(part); p.appendCode(bout); if (p.size() == 0) continue; String component = parts[i++]; if (component.length() == 0) throw new IllegalStateException("Protocol requires address, but non provided!"); bout.write(p.addressToBytes(component)); } return bout.toByteArray(); } catch (IOException e) { throw new IllegalStateException("Error decoding multiaddress: "+addr); } } private static String encodeToString(byte[] raw) { StringBuilder b = new StringBuilder(); InputStream in = new ByteArrayInputStream(raw); try { while (true) { int code = (int)Protocol.readVarint(in); Protocol p = Protocol.get(code); b.append("/" + p.name()); if (p.size() == 0) continue; String addr = p.readAddress(in); if (addr.length() > 0) b.append("/" +addr); } } catch (EOFException eof) {} catch (IOException e) { throw new RuntimeException(e); } return b.toString(); } @Override public String toString() { return encodeToString(raw); } @Override public boolean equals(Object other) { if (!(other instanceof MultiAddress)) return false; return Arrays.equals(raw, ((MultiAddress) other).raw); } @Override public int hashCode() { return Arrays.hashCode(raw); } }