01: // MICPReadWrite.java
02: // $Id: MICPReadWrite.java,v 1.4 2000/08/16 21:38:05 ylafon Exp $
03: // (c) COPYRIGHT MIT and INRIA, 1997.
04: // Please first read the full copyright statement in file COPYRIGHT.html
05:
06: package org.w3c.www.protocol.http.micp;
07:
08: /**
09: * A class to parse/emit MICP messages.
10: */
11:
12: public class MICPReadWrite implements MICP {
13:
14: private final void encodeShort(byte buf[], int off, int s) {
15: buf[off] = (byte) ((s & 0xff00) >>> 8);
16: buf[off + 1] = (byte) (s & 0xff);
17: }
18:
19: private final int decodeShort(byte buf[], int off) {
20: return ((buf[off] & 0xff) << 8) + (buf[off + 1] & 0xff);
21: }
22:
23: private final void encodeInt(byte buf[], int off, int i) {
24: buf[off] = (byte) ((i & 0xff000000) >>> 24);
25: buf[off + 1] = (byte) ((i & 0x00ff0000) >>> 16);
26: buf[off + 2] = (byte) ((i & 0x0000ff00) >>> 8);
27: buf[off + 3] = (byte) ((i & 0xff0000ff) >>> 0);
28: }
29:
30: private final int decodeInt(byte buf[], int off) {
31: return (((buf[off] & 0xff) << 24)
32: + ((buf[off + 1] & 0xff) << 16)
33: + ((buf[off + 2] & 0xff) << 8) + (buf[off + 3] & 0xff));
34: }
35:
36: private final void encodeString(byte buf[], int off, String s) {
37: byte bits[] = s.getBytes();
38: System.arraycopy(bits, 0, buf, off, bits.length);
39: }
40:
41: /**
42: * Parse the given buffer as an mICP message.
43: * @param buf The wire data to parse.
44: * @param len The length of above buffer.
45: * @param into Message structure to fill in.
46: * @return The filled in message.
47: * @exception MICPProtocolException If the given buffer is not an mICP
48: * wire formatted message.
49: */
50:
51: public MICPMessage decode(byte buf[], int len, MICPMessage into)
52: throws MICPProtocolException {
53: if (len < 12)
54: throw new MICPProtocolException("invalid buffer length "
55: + len);
56: int packlen = decodeShort(buf, 2);
57: if (len < packlen)
58: throw new MICPProtocolException("invalid length " + packlen
59: + "/" + len);
60: into.version = (buf[0] & 0xff);
61: into.op = (buf[1] & 0xff);
62: into.src = decodeInt(buf, 4);
63: into.id = decodeInt(buf, 8);
64: into.url = new String(buf, 12, len - 12);
65: return into;
66: }
67:
68: /**
69: * Emit an MICP message into provided buffer.
70: * If the buffer is too small, a new buffer is allocated in place of
71: * the provided one (and returned).
72: * @param op The opcode for the message.
73: * @param src The source field for the message.
74: * @param id The identifier of that message.
75: * @param url The URL for that message.
76: * @param buf The buffer to encode the message to.
77: * @return A positive integer, giving the message length if buffer was big
78: * enough to hold the packet, a negative integer, giving required buffer
79: * size otherwise.
80: */
81:
82: public int encode(int op, int src, int id, String url, byte buf[]) {
83: int len = 12 + url.length();
84: if (len >= buf.length)
85: return -len;
86: buf[0] = (byte) (MICP_VERSION & 0xff); // mICP version
87: buf[1] = (byte) (op & 0xff); // mICP opcode
88: encodeShort(buf, 2, len); // mICP length
89: encodeInt(buf, 4, src); // mICP source
90: encodeInt(buf, 8, id); // mICP id
91: encodeString(buf, 12, url); // mICP url
92: return len;
93: }
94:
95: }
|