001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.tck.wma.sms;
028:
029: import java.io.ByteArrayOutputStream;
030: import java.io.DataOutputStream;
031:
032: import java.io.IOException;
033:
034: /**
035: * A generic message packet that treats the packet as an input or output stream
036: * of data.
037: */
038: public class MessagePacket {
039:
040: /** The maximum payload size for a datagram. */
041: private final int DATAGRAM_PACKET_LENGTH = 1500;
042:
043: /** The current read-write index into the data buffer (stream). */
044: private int index = 0;
045:
046: /** The data buffer (stream). */
047: private byte[] data;
048:
049: private boolean firstWrite = true;
050:
051: /** The byte output stream, used when creating a new packet. */
052: private ByteArrayOutputStream bos = null;
053:
054: /** The data output stream, used when creating a new packet. */
055: private DataOutputStream dos = null;
056:
057: /**
058: * Construct a new message packet that can be populated with some data.
059: */
060: public MessagePacket() {
061: firstWrite = true;
062: }
063:
064: /**
065: * Construct a new message packet that contains the given payload.
066: *
067: * @param payload The bytes to be read.
068: */
069: public MessagePacket(byte[] payload) {
070:
071: /* Make a clone of the payload (message) bytes. */
072: int length = payload.length;
073: data = new byte[length];
074: for (int i = 0; i < length; i++) {
075: data[i] = payload[i];
076: }
077: }
078:
079: /**
080: * Read an integer (32-bit) value from the data stream, starting at the
081: * current index.
082: *
083: * @return The integer that was read from the data stream.
084: *
085: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
086: * end of the data stream.
087: */
088: public int getInt() {
089: int x1 = ((int) (data[index++] & 0xff));
090: int x2 = ((int) (data[index++] & 0xff) << 8);
091: int x3 = ((int) (data[index++] & 0xff) << 16);
092: int x4 = ((int) (data[index++] & 0xff) << 24);
093: return (x1 | x2 | x3 | x4);
094: }
095:
096: /**
097: * Write an integer (32-bit) value into the data stream and advance the
098: * index.
099: *
100: * @param x The integer to be written.
101: *
102: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
103: * end of the data stream.
104: */
105: public void putInt(int x) throws IOException {
106: checkFirstWrite();
107: dos.writeByte((byte) (x & 0xff));
108: dos.writeByte((byte) ((x >> 8) & 0xff));
109: dos.writeByte((byte) ((x >> 16) & 0xff));
110: dos.writeByte((byte) ((x >> 24) & 0xff));
111: }
112:
113: /**
114: * Read a short (16-bit) value from the data stream, starting at the
115: * current index.
116: *
117: * @return The short that was read from the data stream.
118: *
119: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
120: * end of the data stream.
121: */
122: public short getShort() {
123: short x1 = ((short) (data[index++] & 0xff));
124: short x2 = (short) ((data[index++] & 0xff) << 8);
125: return (short) (x1 | x2);
126: }
127:
128: /**
129: * Write a short (16-bit) value into the data stream and advance the
130: * index.
131: *
132: * @param x The short to be written.
133: *
134: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
135: * end of the data stream.
136: */
137: public void putShort(short x) throws IOException {
138: checkFirstWrite();
139: dos.writeByte((byte) (x & 0xff));
140: dos.writeByte((byte) ((x >> 8) & 0xff));
141: }
142:
143: /**
144: * Read a long (64-bit) value from data stream, starting at the current
145: * index.
146: *
147: * @return The long value that was read from the data stream.
148: *
149: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
150: * end of the data stream.
151: */
152: public long getLong() {
153: long x1 = ((long) (data[index++] & 0xff));
154: long x2 = ((long) (data[index++] & 0xff) << 8);
155: long x3 = ((long) (data[index++] & 0xff) << 16);
156: long x4 = ((long) (data[index++] & 0xff) << 24);
157: long x5 = ((long) (data[index++] & 0xff) << 32);
158: long x6 = ((long) (data[index++] & 0xff) << 40);
159: long x7 = ((long) (data[index++] & 0xff) << 48);
160: long x8 = ((long) (data[index++] & 0xff) << 56);
161: return (x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8);
162: }
163:
164: /**
165: * Write a long (64-bit) value into the data stream and advance the index.
166: *
167: * @param x The long to be written.
168: *
169: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
170: * end of the data stream.
171: */
172: public void putLong(long x) throws IOException {
173: checkFirstWrite();
174: dos.writeByte((byte) (x & 0xff));
175: dos.writeByte((byte) ((x >> 8) & 0xff));
176: dos.writeByte((byte) ((x >> 16) & 0xff));
177: dos.writeByte((byte) ((x >> 24) & 0xff));
178: dos.writeByte((byte) ((x >> 32) & 0xff));
179: dos.writeByte((byte) ((x >> 40) & 0xff));
180: dos.writeByte((byte) ((x >> 48) & 0xff));
181: dos.writeByte((byte) ((x >> 56) & 0xff));
182: }
183:
184: /**
185: * Write a string to the data stream, starting at the current index. The
186: * characters in the string are written, followed by a null-character
187: * terminator.
188: *
189: * @param s The string to be written.
190: *
191: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
192: * end of the data stream.
193: */
194: public void putString(String s) throws IOException {
195: checkFirstWrite();
196: dos.writeBytes(s);
197: dos.writeByte(0);
198: }
199:
200: /**
201: * Read a string from the data stream, starting at the current index. The
202: * string is assumed to be terminated by a null character.
203: *
204: * @return The string of characters, converted to a
205: * <code>java.lang.String</code> object.
206: *
207: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
208: * end of the data stream.
209: */
210: public String getString() {
211: int offset = index;
212: int len = 0;
213:
214: /* Determine length of string */
215: for (int i = index; i < data.length; i++) {
216: if (data[i] == '\0') {
217: break;
218: }
219: len++;
220: }
221:
222: /* update index */
223: index += len + 1;
224:
225: return new String(data, offset, len);
226: }
227:
228: /**
229: * Write an array of bytes into the data stream, starting at the current
230: * index.
231: *
232: * @param buf The buffer of bytes to be written into the data stream.
233: *
234: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
235: * end of the data stream.
236: */
237: public void putBytes(byte[] buf) throws IOException {
238: checkFirstWrite();
239: dos.write(buf, 0, buf.length);
240: }
241:
242: /**
243: * Read an array of bytes from the data stream, starting at the current
244: * index. The number of bytes to be read is specified by
245: * <code>length</code>. The index is advanced by <code>length</code>.
246: *
247: * @param length The number of bytes to be read.
248: *
249: * @return The buffer of bytes that were read.
250: *
251: * @exception ArrayIndexOutOfBoundsException if reading goes beyond the
252: * end of the data stream.
253: */
254: public byte[] getBytes(int length) {
255:
256: byte[] buffer = new byte[length];
257:
258: for (int i = 0; i < length; i++) {
259: buffer[i] = data[index++];
260: }
261:
262: return buffer;
263: }
264:
265: /**
266: * Returns the contents of the packet as a byte array.
267: *
268: * @return The array of packet bytes.
269: *
270: * @exception IOException if there was a problem while closing the streams.
271: */
272: public byte[] getData() throws IOException {
273:
274: byte[] buffer = new byte[0];
275:
276: if (firstWrite == false) {
277: dos.close();
278: buffer = bos.toByteArray();
279: bos.close();
280: }
281:
282: return buffer;
283: }
284:
285: /**
286: * Checks to see if the data output streams need to be opened.
287: */
288: private void checkFirstWrite() {
289: if (firstWrite == true) {
290: firstWrite = false;
291: bos = new ByteArrayOutputStream();
292: dos = new DataOutputStream(bos);
293: }
294: }
295:
296: }
|