/* DatagramPacket.java -- Class to model a packet to be sent via UDP
   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.net;


/*
 * Written using on-line Java Platform 1.2 API Specification, as well
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
 * Status:  Believed complete and correct.
 */

/**
 * This class models a packet of data that is to be sent across the network
 * using a connectionless protocol such as UDP.  It contains the data
 * to be send, as well as the destination address and port.  Note that
 * datagram packets can arrive in any order and are not guaranteed to be
 * delivered at all.
 * <p>
 * This class can also be used for receiving data from the network.
 * <p>
 * Note that for all method below where the buffer length passed by the
 * caller cannot exceed the actually length of the byte array passed as
 * the buffer, if this condition is not true, then the method silently
 * reduces the length value to maximum allowable value.
 *
 * Written using on-line Java Platform 1.2 API Specification, as well
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
 * Status:  Believed complete and correct.
 *
 * @author Warren Levy (warrenl@cygnus.com)
 * @author Aarom M. Renn (arenn@urbanophile.com) (Documentation comments)
 * @date April 28, 1999.
 */
public final class DatagramPacket
{
  /**
   * The data buffer to send
   */
  private byte[] buffer;

  /**
   * This is the offset into the buffer to start sending from or receiving to.
   */
  private int offset;

  /**
   * The length of the data buffer to send.
   */
  int length;

  /**
   * The maximal length of the buffer.
   */
  int maxlen;

  /**
   * The address to which the packet should be sent or from which it
   * was received.
   */
  private InetAddress address;

  /**
   * The port to which the packet should be sent or from which it was
   * was received.
   */
  private int port;

  /**
   * This method initializes a new instance of <code>DatagramPacket</code>
   * which has the specified buffer, offset, and length.
   *
   * @param buf The buffer for holding the incoming datagram.
   * @param offset The offset into the buffer to start writing.
   * @param length The maximum number of bytes to read.
   *
   * @since 1.2
   */
  public DatagramPacket(byte[] buf, int offset, int length)
  {
    setData(buf, offset, length);
    address = null;
    port = -1;
  }

  /**
   * Initializes a new instance of <code>DatagramPacket</code> for
   * receiving packets from the network.
   *
   * @param buf A buffer for storing the returned packet data
   * @param length The length of the buffer (must be &lt;= buf.length)
   */
  public DatagramPacket(byte[] buf, int length)
  {
    this(buf, 0, length);
  }

  /**
   * Initializes a new instance of <code>DatagramPacket</code> for
   * transmitting packets across the network.
   *
   * @param buf A buffer containing the data to send
   * @param offset The offset into the buffer to start writing from.
   * @param length The length of the buffer (must be &lt;= buf.length)
   * @param address The address to send to
   * @param port The port to send to
   *
   * @since 1.2
   */
  public DatagramPacket(byte[] buf, int offset, int length,
                        InetAddress address, int port)
  {
    setData(buf, offset, length);
    setAddress(address);
    setPort(port);
  }

  /**
   * Initializes a new instance of <code>DatagramPacket</code> for
   * transmitting packets across the network.
   *
   * @param buf A buffer containing the data to send
   * @param length The length of the buffer (must be &lt;= buf.length)
   * @param address The address to send to
   * @param port The port to send to
   */
  public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
  {
    this(buf, 0, length, address, port);
  }

  /**
   * Initializes a new instance of <code>DatagramPacket</code> for
   * transmitting packets across the network.
   *
   * @param buf A buffer containing the data to send
   * @param offset The offset into the buffer to start writing from.
   * @param length The length of the buffer (must be &lt;= buf.length)
   * @param address The socket address to send to
   *
   * @exception SocketException If an error occurs
   * @exception IllegalArgumentException If address type is not supported
   *
   * @since 1.4
   */
  public DatagramPacket(byte[] buf, int offset, int length,
                        SocketAddress address) throws SocketException
  {
    if (! (address instanceof InetSocketAddress))
      throw new IllegalArgumentException("unsupported address type");

    InetSocketAddress tmp = (InetSocketAddress) address;
    setData(buf, offset, length);
    setAddress(tmp.getAddress());
    setPort(tmp.getPort());
  }

  /**
   * Initializes a new instance of <code>DatagramPacket</code> for
   * transmitting packets across the network.
   *
   * @param buf A buffer containing the data to send
   * @param length The length of the buffer (must be &lt;= buf.length)
   * @param address The socket address to send to
   *
   * @exception SocketException If an error occurs
   * @exception IllegalArgumentException If address type is not supported
   *
   * @since 1.4
   */
  public DatagramPacket(byte[] buf, int length, SocketAddress address)
    throws SocketException
  {
    this(buf, 0, length, address);
  }

  /**
   * Returns the address that this packet is being sent to or, if it was used
   * to receive a packet, the address that is was received from.  If the
   * constructor that doesn not take an address was used to create this object
   * and no packet was actually read into this object, then this method
   * returns <code>null</code>.
   *
   * @return The address for this packet.
   */
  public synchronized InetAddress getAddress()
  {
    return address;
  }

  /**
   * Returns the port number this packet is being sent to or, if it was used
   * to receive a packet, the port that it was received from. If the
   * constructor that doesn not take an address was used to create this object
   * and no packet was actually read into this object, then this method
   * will return 0.
   *
   * @return The port number for this packet
   */
  public synchronized int getPort()
  {
    return port;
  }

  /**
   * Returns the data buffer for this packet
   *
   * @return This packet's data buffer
   */
  public synchronized byte[] getData()
  {
    return buffer;
  }

  /**
   * This method returns the current offset value into the data buffer
   * where data will be sent from.
   *
   * @return The buffer offset.
   *
   * @since 1.2
   */
  public synchronized int getOffset()
  {
    return offset;
  }

  /**
   * Returns the length of the data in the buffer
   *
   * @return The length of the data
   */
  public synchronized int getLength()
  {
    return length;
  }

  /**
   * This sets the address to which the data packet will be transmitted.
   *
   * @param address The destination address
   *
   * @since 1.1
   */
  public synchronized void setAddress(InetAddress address)
  {
    this.address = address;
  }

  /**
   * This sets the port to which the data packet will be transmitted.
   *
   * @param port The destination port
   *
   * @since 1.1
   */
  public synchronized void setPort(int port)
  {
    if (port < 0 || port > 65535)
      throw new IllegalArgumentException("Invalid port: " + port);

    this.port = port;
  }

  /**
   * Sets the address of the remote host this package will be sent
   *
   * @param address The socket address of the remove host
   *
   * @exception IllegalArgumentException If address type is not supported
   *
   * @since 1.4
   */
  public void setSocketAddress(SocketAddress address)
    throws IllegalArgumentException
  {
    if (address == null)
      throw new IllegalArgumentException("address may not be null");

    InetSocketAddress tmp = (InetSocketAddress) address;
    this.address = tmp.getAddress();
    this.port = tmp.getPort();
  }

  /**
   * Gets the socket address of the host this packet
   * will be sent to/is coming from
   *
   * @return The socket address of the remote host
   *
   * @since 1.4
   */
  public SocketAddress getSocketAddress()
  {
    return new InetSocketAddress(address, port);
  }

  /**
   * Sets the data buffer for this packet.
   *
   * @param buf The new buffer for this packet
   *
   * @exception NullPointerException If the argument is null
   *
   * @since 1.1
   */
  public void setData(byte[] buf)
  {
    setData(buf, 0, buf.length);
  }

  /**
   * This method sets the data buffer for the packet.
   *
   * @param buf The byte array containing the data for this packet.
   * @param offset The offset into the buffer to start reading data from.
   * @param length The number of bytes of data in the buffer.
   *
   * @exception NullPointerException If the argument is null
   *
   * @since 1.2
   */
  public synchronized void setData(byte[] buf, int offset, int length)
  {
    // This form of setData must be used if offset is to be changed.
    if (buf == null)
      throw new NullPointerException("Null buffer");
    if (offset < 0)
      throw new IllegalArgumentException("Invalid offset: " + offset);

    buffer = buf;
    this.offset = offset;
    setLength(length);
  }

  /**
   * Sets the length of the data in the buffer.
   *
   * @param length The new length.  (Where len &lt;= buf.length)
   *
   * @exception IllegalArgumentException If the length is negative or
   * if the length is greater than the packet's data buffer length
   *
   * @since 1.1
   */
  public synchronized void setLength(int length)
  {
    if (length < 0)
      throw new IllegalArgumentException("Invalid length: " + length);
    if (offset + length > buffer.length)
      throw new IllegalArgumentException("Potential buffer overflow - offset: "
                                         + offset + " length: " + length);

    this.length = length;
    this.maxlen = length;
  }
}
