/* * Copyright 2013 Guidewire Software, Inc. */ package gw.compiler.ij.api; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; public class ObjectClient { private static boolean matches(byte[] buffer, int offset, byte[] search) { final int len = buffer.length; for (int i = 0; i < len; ++i) { if (search[i] != buffer[(offset + i) % len]) { return false; } } return true; } private static void skipMarker(InputStream stream) throws IOException { final byte[] buf = new byte[MARKER.length]; int cnt = stream.read(buf); if (cnt != buf.length) { throw new EOFException("Cannot skip marker"); } // Continuously match cyclic buffer against the marker int offset = 0; while (true) { if (matches(buf, offset, MARKER)) { break; } int c = stream.read(); if (c == -1) { throw new EOFException("Cannot skip marker"); } buf[offset] = (byte) c; offset = (offset + 1) % buf.length; } } private static final byte[] MARKER = "###STREAM_MARKER###".getBytes(); private ObjectInputStream in; private ObjectOutputStream out; private InputStream rawIn; private OutputStream rawOut; public ObjectClient(InputStream rawIn, OutputStream rawOut) { this.rawIn = rawIn; this.rawOut = rawOut; } public Object read() throws IOException { if (in == null) { skipMarker(rawIn); in = new ObjectInputStream(new BufferedInputStream(rawIn,1<<16)); //64K buffer } try { return in.readObject(); } catch (Exception e) { throw new IOException("Error while reading object from the socket.", e); } } public void write(Object obj, boolean flush) throws IOException { if (out == null) { rawOut.write(MARKER); out = new ObjectOutputStream(new BufferedOutputStream(rawOut,1<<16)); //64K buffer } try { out.writeObject(obj); } catch (IOException e) { throw new IOException(String.format("Error while writing object '%s' to the socket.", obj), e); } if (flush) { out.flush(); } } }