package hep.io.root.daemon.xrootd; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.logging.Logger; /** * A message contains all of the information needed to perform a single * xrootd operation. A message normally consists of an xrootd op code, an * optional string (such as a file path), and op code dependent extra information * which can be encoded into the header. The extra information can be written * to the header by calling the write* methods of this class. * @author tonyj */ class Message { ByteBuffer buffer; private static Logger logger = Logger.getLogger(Response.class.getName()); private ByteBuffer data; /** Create a message from an Xrootd operation code * @param message The op code */ Message(int message) { buffer = ByteBuffer.allocate(24); buffer.putShort((short) 0); buffer.putShort((short)message); } /** * Create a message from an Xrootd operation code plus a string * @param message The op code * @param string The string to be sent with the message (such as a file path) */ Message(int message, String string) { byte[] bytes = string.getBytes(); buffer = ByteBuffer.allocate(24+bytes.length); buffer.putShort((short) 0); buffer.putShort((short) message); buffer.position(20); buffer.putInt(bytes.length); buffer.put(bytes); buffer.position(4); } int send(short handle, SocketChannel out) throws IOException { buffer.position(0); buffer.putShort(handle); logger.finest("->" + buffer.getShort()); writeExtra(buffer); if (data != null) buffer.putInt(20,data.remaining()); buffer.position(0); out.write(buffer); if (data!= null) out.write(data); return buffer.limit(); } void writeByte(int i) { buffer.put((byte) (i & 0xff)); } void writeInt(int i) { buffer.putInt(i); } void writeLong(long i) { buffer.putLong(i); } void writeShort(int i) { buffer.putShort((short) (i & 0xffff)); } /** * This method can be overriden by classes that want to send the extra bytes * in the header themselves. * @param out * @throws java.io.IOException */ void writeExtra(ByteBuffer out) throws IOException { } /** * Used by classes that want to write their own data to the message * @param buffer * @param offset * @param length */ void setData(byte[] buffer, int offset, int length) { this.data = ByteBuffer.wrap(buffer,offset,length); } }