package water.hadoop;
import water.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* Simple class to help serialize messages from the Mapper to the Driver.
*/
class AbstractMessage {
public static final char TYPE_UNKNOWN = 0;
public static final char TYPE_EOF_NO_MESSAGE = 1;
// Readers
// -------
protected int readBytes(Socket s, byte[] b) throws Exception {
int bytesRead = 0;
int bytesExpected = b.length;
InputStream is = s.getInputStream();
while (bytesRead < bytesExpected) {
int n = is.read(b, bytesRead, bytesExpected - bytesRead);
if (n < 0) {
return n;
}
bytesRead += n;
}
return bytesRead;
}
protected char readType(Socket s) throws Exception {
byte b[] = new byte[1];
int n = readBytes(s, b);
if (n < 0) {
return TYPE_EOF_NO_MESSAGE;
}
// System.out.println("readType: " + b[0]);
return (char) b[0];
}
protected int readInt(Socket s) throws Exception {
byte b[] = new byte[4];
int n = readBytes(s, b);
if (n < 0) {
throw new IOException("AbstractMessage: readBytes failed");
}
int i =
(
((((int) b[0]) << (8*0)) & 0x000000ff) |
((((int) b[1]) << (8*1)) & 0x0000ff00) |
((((int) b[2]) << (8*2)) & 0x00ff0000) |
((((int) b[3]) << (8*3)) & 0xff000000)
);
// System.out.println("readInt: " + i);
// System.out.println("readInt: " + b[0] + " " + b[1] + " " + b[2] + " " + b[3]);
return i;
}
protected String readString(Socket s) throws Exception {
int length = readInt(s);
byte b[] = new byte[length];
int n = readBytes(s, b);
if (n < 0) {
throw new IOException("AbstractMessage: readBytes failed");
}
String str = new String(b, "UTF-8");
// System.out.println("readString: " + str);
return str;
}
// Writers
// -------
protected void writeBytes(Socket s, byte[] b) throws Exception {
OutputStream os = s.getOutputStream();
os.write(b);
}
protected void writeType(Socket s, int type) throws Exception {
byte b[] = new byte[1];
b[0] = (byte)(char)type;
writeBytes(s, b);
}
protected void writeInt(Socket s, int i) throws Exception {
byte b[] = new byte[4];
b[0] = (byte)((i >> (8*0)) & 0xff);
b[1] = (byte)((i >> (8*1)) & 0xff);
b[2] = (byte)((i >> (8*2)) & 0xff);
b[3] = (byte)((i >> (8*3)) & 0xff);
// System.out.println("writeInt: " + b[0] + " " + b[1] + " " + b[2] + " " + b[3]);
writeBytes(s, b);
}
protected void writeString(Socket s, String str) throws Exception {
byte b[] = StringUtils.bytesOf(str);
writeInt(s, b.length);
writeBytes(s, b);
}
}