1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
package edu.ucsb.cs.nws.nwsprotocol;
import java.io.*;
import java.net.*;
/**
* The NwsMessage class provides support to the NWS host classes for sending
* messages to and from NWS hosts. It encapsulates a number of useful class
* functions and values and is not intended to be instantiated.
*/
public class NwsMessage {
/** Message number ranges as defined in messages.h. */
public static final int ALLHOSTS_FIRST_MESSAGE = 200;
public static final int ALLHOSTS_LAST_MESSAGE = 299;
public static final int CLIQUE_FIRST_MESSAGE = 400;
public static final int CLIQUE_LAST_MESSAGE = 499;
public static final int FORECASTER_FIRST_MESSAGE = 500;
public static final int FORECASTER_LAST_MESSAGE = 599;
public static final int MEMORY_FIRST_MESSAGE = 100;
public static final int MEMORY_LAST_MESSAGE = 199;
public static final int NAMESERVER_FIRST_MESSAGE = 700;
public static final int NAMESERVER_LAST_MESSAGE = 799;
public static final int PERIODIC_FIRST_MESSAGE = 300;
public static final int PERIODIC_LAST_MESSAGE = 399;
public static final int SENSOR_FIRST_MESSAGE = 600;
public static final int SENSOR_LAST_MESSAGE = 699;
public static final int SKILLS_FIRST_MESSAGE = 800;
public static final int SKILLS_LAST_MESSAGE = 899;
public static final int PROXY_FIRST_MESSAGE = 900;
public static final int PROXY_LAST_MESSAGE = 999;
/**
* A convenience function that concatenates any number of byte arrays into a
* single large byte array.
*/
public static byte[] concatenateBytes(byte[][] arrays) {
int i;
byte[] returnValue;
int totalSize;
totalSize = 0;
for(i = 0; i < arrays.length; i++)
totalSize += arrays[i].length;
returnValue = new byte[totalSize];
totalSize = 0;
for(i = 0; i < arrays.length; i++) {
System.arraycopy(arrays[i], 0, returnValue, totalSize, arrays[i].length);
totalSize += arrays[i].length;
}
return returnValue;
}
/** An interface for a class that can receive NWS messages. */
public static interface MessageReceiver {
/**
* Notification that <i>message</i> has arrived, accompanied by
* <i>dataLength</i> bytes of data which may be read from <i>stream</i>.
*/
public Object receive(int message,
DataInputStream stream,
int dataLength) throws Exception;
}
/** Passes the next message that arrives on <i>sd</i> to <i>receiver</i>. */
public static Object receive(Socket sd,
MessageReceiver receiver) throws Exception {
DataInputStream dataStream = new DataInputStream(sd.getInputStream());
MessageHeader header = new MessageHeader(dataStream);
return receiver.receive(header.type, dataStream, header.dataSize);
}
/** Sends <i>message</i> on <i>sd</i> accompanied by no data. */
public static void send(Socket sd,
int message) throws Exception {
sd.getOutputStream().write(new MessageHeader(message, 0).toBytes());
}
/** Sends <i>message</i> on <i>sd</i> accompanied by <i>data</i>. */
public static void send(Socket sd,
int message,
byte[] data) throws Exception {
sd.getOutputStream().write
(new MessageHeader(message, data.length).toBytes());
sd.getOutputStream().write(data);
}
/** A convenience function for converting a double to bytes. */
public static byte[] toBytes(double value) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
new DataOutputStream(byteStream).writeDouble(value);
} catch(Exception x) { }
return byteStream.toByteArray();
}
/** A convenience function for converting an integer to bytes. */
public static byte[] toBytes(int value) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
new DataOutputStream(byteStream).writeInt(value);
} catch(Exception x) { }
return byteStream.toByteArray();
}
/** The standard NWS message header */
protected static class MessageHeader {
public int version = 0x02000000;
public int type;
public int dataSize = 0;
/**
* Produces an NWS header with the type and size fields set to the
* parameters.
*/
public MessageHeader(int type,
int size) {
this.type = type;
dataSize = size;
}
/** Produces an NWS header initialized by reading <i>stream</i>. */
public MessageHeader(DataInputStream stream) throws Exception {
version = stream.readInt();
type = stream.readInt();
dataSize = stream.readInt();
}
/** Returns the contents of the header converted to bytes. */
public byte[] toBytes() {
byte[][] allBytes =
{NwsMessage.toBytes(version), NwsMessage.toBytes(type),
NwsMessage.toBytes(dataSize)};
return concatenateBytes(allBytes);
}
}
}
|