/** * Parse a signature from a byte stream * * @param in input bytes to parse * @return the decoded signature data * @throws CtxException */ static ScalaSig parse(byte[] in) throws CtxException { ByteArrayInputStream bis = new ByteArrayInputStream(in); // Pull version info & check OK int major = Nat.read(bis); int minor = Nat.read(bis); if (major != 5 || minor != 0) { throw new CtxException("Unexpected signature version found: " + major + "." + minor); } // Pull table int tblEntries = Nat.read(bis); Table table = new Table(); for (int e = 0; e < tblEntries; e++) { int type = Nat.read(bis); int size = Nat.read(bis); byte[] raw = new byte[size]; if (bis.read(raw, 0, size) != size) { throw new CtxException("Unexpected EOF in signature data"); } table.addEntry(type, raw); } // The input stream should be consumed at this point but a 'feature' of the encoding is // that there may be a trailer 0 byte, just check all look good int trail = bis.read(); if (trail == 0) trail = bis.read(); if (trail != -1) throw new CtxException("Unexpected additional byte found at end of signature"); // All good so create signature return new ScalaSig(major, minor, table); }
/** * Decode from raw bytes * * @param raw the bytes */ ExtModClassRefEntry(byte[] raw) { ByteArrayInputStream in = new ByteArrayInputStream(raw); _nameRef = Nat.read(in); // Symbol is optional in the encoding _symbolRef = -1; if (in.available() > 0) { _symbolRef = Nat.read(in); } }
/** * Get a byte array containing the encoded signature * * @return the byte array */ byte[] asBytes() { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); Nat.write(_majorVersion, out); Nat.write(_minorVersion, out); _table.write(out); return out.toByteArray(); } catch (IOException e) { throw new CtxException("Unexpected error converting signature to byte array", e); } }
/** * Write entry back to a stream * * @param bos stream to write to * @throws IOException */ public void write(ByteArrayOutputStream bos) throws IOException { Nat.write(TblTypeID.EXT_MOD_CLASS_REF_ID, bos); if (_symbolRef != -1) { Nat.write(Nat.size(_nameRef) + Nat.size(_symbolRef), bos); Nat.write(_nameRef, bos); Nat.write(_symbolRef, bos); } else { Nat.write(Nat.size(_nameRef), bos); Nat.write(_nameRef, bos); } }
/** * Write the table as a byte stream * * @param out the stream to write to * @throws IOException */ void write(ByteArrayOutputStream out) throws IOException { Nat.write(entries.size(), out); for (TableEntry e : entries) { e.write(out); } }
/** * Write entry back to a stream * * @param bos stream to write to * @throws IOException */ public void write(ByteArrayOutputStream bos) throws IOException { Nat.write(TblTypeID.TERM_NAME_ID, bos); byte[] bytes = _name.getBytes(StandardCharsets.UTF_8); Nat.write(bytes.length, bos); bos.write(bytes); }
/** * Write entry back to a stream * * @param bos stream to write to * @throws IOException */ public void write(ByteArrayOutputStream bos) throws IOException { Nat.write(type, bos); Nat.write(raw.length, bos); bos.write(raw); }