/*
* @(#)DatagramObject.java 1.25 06/10/10
*
* Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*
*/
package com.sun.cdc.io.j2me.datagram;
import java.io.*;
import java.net.*;
import javax.microedition.io.*;
import com.sun.cdc.io.j2me.*;
/**
* This class is required because the J2SE Datagram class is final.
*/
public class DatagramObject extends UniversalOutputStream implements Datagram {
DatagramPacket dgram;
String host;
int port;
boolean resetFlag = false;
public DatagramObject(DatagramPacket dpkt) {
dgram = dpkt;
}
public DatagramObject(int p) {
port = p;
host = "localhost";
}
public String getAddress() {
if (dgram == null) {
return null;
}
InetAddress addr = dgram.getAddress();
if (addr == null) {
return null;
}
if (host == null) {
return "datagram://:" + port;
}
return "datagram://" + host + ":" + port;
}
public byte[] getData() {
return dgram.getData();
}
public int getOffset() {
return dgram.getOffset();
}
public int getLength() {
return dgram.getLength();
}
public void setAddress(String addr) throws IOException,
IllegalArgumentException {
if (addr == null)
throw new IllegalArgumentException("NULL datagram address");
if(!addr.startsWith("datagram://")) {
throw new IllegalArgumentException("Invalid datagram address"+addr);
}
String address = addr.substring(11);
try {
host = Protocol.getAddress(address);
port = Protocol.getPort(address);
dgram.setAddress(InetAddress.getByName(host));
dgram.setPort(port);
} catch(NumberFormatException x) {
throw new IllegalArgumentException("Invalid datagram address"+addr);
} catch(UnknownHostException x) {
throw new IllegalArgumentException("Unknown host "+addr);
}
}
public void setAddress(Datagram reference) throws IllegalArgumentException
{
if (reference == null)
throw new IllegalArgumentException("NULL datagram address");
DatagramObject ref = (DatagramObject)reference;
host = ref.host;
port = ref.port;
if (host == null)
throw new IllegalArgumentException("NULL datagram address");
dgram.setAddress(ref.dgram.getAddress());
dgram.setPort(port);
}
public void setData(byte[] buffer, int offset, int len) throws
IllegalArgumentException {
if (buffer == null) {
throw new IllegalArgumentException("NULL buffer");
}
if (offset > buffer.length || len > buffer.length ) {
throw new IllegalArgumentException("offset past length of buffer");
}
dgram.setData(buffer, offset, len);
pointer = 0;
}
public void setLength(int len) {
/* The length of the datagram should not exceed the length of the data buffer length */
if (len > dgram.getData().length ) {
throw new IllegalArgumentException("length past length of buffer");
}
dgram.setLength(len);
}
/*
public void setOffset(int offset) {
dgram.setOffset(offset);
}
*/
//
// Read / write functions.
//
int pointer = 0;
public void reset() {
byte[] b = dgram.getData();
dgram.setData(b, 0, 0);
pointer = 0;
resetFlag = true;
}
public long skip(long n) throws EOFException {
int len = dgram.getLength();
if (n > (len-pointer)) {
throw new EOFException();
}
pointer += n;
return n;
}
public int read() throws IOException {
byte[] b = dgram.getData();
if(pointer >= dgram.getLength()) {
return -1;
}
return b[dgram.getOffset()+(pointer++)] & 0xFF;
}
public void write(int ch) throws IOException {
byte[] b = dgram.getData();
// Check if trying to move past end of datagram buffer
// NOTE: only make this check if reset was not called
if ( (!resetFlag) && (dgram.getLength() > 0) &&
((pointer+1) > dgram.getLength())) {
throw new IOException();
} else if ( (!resetFlag) && (dgram.getLength() == 0) ) {
throw new IOException();
} else {
// Create a new buffer if dgram is now empty
if (dgram.getLength() == 0) {
byte new_b[] = new byte[1];
b = new_b;
dgram.setData(b, 0, 1);
dgram.setLength(1);
}
}
// Grow the datagram if needed
if ((dgram.getOffset()+pointer) == b.length) {
byte new_b[] = new byte[b.length+1];
System.arraycopy(b, 0, new_b, 0, b.length);
b = new_b;
dgram.setData(b, 0, b.length);
dgram.setLength(b.length);
}
b[dgram.getOffset()+pointer++] = (byte)ch;
}
//
// DataInput functions
//
/**
* See the general contract of the <code>readFully</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @param b the buffer into which the data is read.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException if an I/O error occurs.
*/
public final void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length);
}
/**
* See the general contract of the <code>readFully</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @param b the buffer into which the data is read.
* @param off the start offset of the data.
* @param len the number of bytes to read.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException if an I/O error occurs.
*/
public final void readFully(byte b[], int off, int len) throws IOException {
if ((len < 0) || (off < 0) || ((off+len) > b.length))
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int ch = read();
if (ch < 0) {
throw new EOFException();
}
b[off+(n++)] = (byte)ch;
}
}
/**
* See the general contract of the <code>skipBytes</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if an I/O error occurs.
*/
public final int skipBytes(int n) throws IOException {
int len = dgram.getLength();
// Do not skip past end of buffer
if ((n > 0) && (n >= (len-pointer))) {
// Return the last position if trying to go past end of
// buffer
n = len-pointer;
}
pointer += n;
// Return the pointer position of next byte
return n;
}
/**
* See the general contract of the <code>readBoolean</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the <code>boolean</code> value read.
* @exception EOFException if this input stream has reached the end.
*/
public final boolean readBoolean() throws IOException {
int ch = read();
if (ch < 0)
throw new EOFException();
return (ch != 0);
}
/**
* See the general contract of the <code>readByte</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next byte of this input stream as a signed 8-bit
* <code>byte</code>.
* @exception EOFException if this input stream has reached the end.
* @exception IOException if an I/O error occurs.
*/
public final byte readByte() throws IOException {
int ch = read();
if (ch < 0)
throw new EOFException();
return (byte)(ch);
}
/**
* See the general contract of the <code>readUnsignedByte</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next byte of this input stream, interpreted as an
* unsigned 8-bit number.
* @exception EOFException if this input stream has reached the end.
* @exception IOException if an I/O error occurs.
*/
public final int readUnsignedByte() throws IOException {
int ch = read();
if (ch < 0)
throw new EOFException();
return ch;
}
/**
* See the general contract of the <code>readShort</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next two bytes of this input stream, interpreted as a
* signed 16-bit number.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException if an I/O error occurs.
*/
public final short readShort() throws IOException {
int ch1 = read();
int ch2 = read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (short)((ch1 << 8) + (ch2 << 0));
}
/**
* See the general contract of the <code>readUnsignedShort</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next two bytes of this input stream, interpreted as an
* unsigned 16-bit integer.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException if an I/O error occurs.
*/
public final int readUnsignedShort() throws IOException {
int ch1 = read();
int ch2 = read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
/**
* See the general contract of the <code>readChar</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next two bytes of this input stream as a Unicode
* character.
* @exception EOFException if this input stream reaches the end before
* reading two bytes.
* @exception IOException if an I/O error occurs.
*/
public final char readChar() throws IOException {
int ch1 = read();
int ch2 = read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (char)((ch1 << 8) + (ch2 << 0));
}
/**
* See the general contract of the <code>readInt</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next four bytes of this input stream, interpreted as an
* <code>int</code>.
* @exception EOFException if this input stream reaches the end before
* reading four bytes.
* @exception IOException if an I/O error occurs.
*/
public final int readInt() throws IOException {
int ch1 = read();
int ch2 = read();
int ch3 = read();
int ch4 = read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
public final float readFloat() throws IOException {
int ch = readInt();
float fl = Float.intBitsToFloat(ch);
return(fl);
}
public final double readDouble() throws IOException {
long ch = readLong();
double db = Double.longBitsToDouble(ch);
return(db);
}
/**
* See the general contract of the <code>readLong</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return the next eight bytes of this input stream, interpreted as a
* <code>long</code>.
* @exception EOFException if this input stream reaches the end before
* reading eight bytes.
* @exception IOException if an I/O error occurs.
*/
public final long readLong() throws IOException {
return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
}
/**
* See the general contract of the <code>readUTF</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return a Unicode string.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.DataInputStream#readUTF(java.io.DataInput)
*/
public final String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
/**
* See the general contract of the <code>readLine</code>
* method of <code>DataInput</code>.
* <p>
* Bytes
* for this operation are read from the contained
* input stream.
*
* @return a Unicode string.
* @exception EOFException if this input stream reaches the end before
* reading all the bytes.
* @exception IOException if an I/O error occurs.
* @see java.io.DataInputStream#readLine()
*/
public final String readLine() throws IOException {
return DataInputStream.readUTF(this);
}
//
// DataOutput functions come from UniversalOutputStream
//
}