001/* DatagramPacket.java -- Class to model a packet to be sent via UDP
002   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package java.net;
039
040
041/*
042 * Written using on-line Java Platform 1.2 API Specification, as well
043 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
044 * Status:  Believed complete and correct.
045 */
046
047/**
048 * This class models a packet of data that is to be sent across the network
049 * using a connectionless protocol such as UDP.  It contains the data
050 * to be send, as well as the destination address and port.  Note that
051 * datagram packets can arrive in any order and are not guaranteed to be
052 * delivered at all.
053 * <p>
054 * This class can also be used for receiving data from the network.
055 * <p>
056 * Note that for all method below where the buffer length passed by the
057 * caller cannot exceed the actually length of the byte array passed as
058 * the buffer, if this condition is not true, then the method silently
059 * reduces the length value to maximum allowable value.
060 *
061 * Written using on-line Java Platform 1.2 API Specification, as well
062 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
063 * Status:  Believed complete and correct.
064 *
065 * @author Warren Levy (warrenl@cygnus.com)
066 * @author Aarom M. Renn (arenn@urbanophile.com) (Documentation comments)
067 * @date April 28, 1999.
068 */
069public final class DatagramPacket
070{
071  /**
072   * The data buffer to send
073   */
074  private byte[] buffer;
075
076  /**
077   * This is the offset into the buffer to start sending from or receiving to.
078   */
079  private int offset;
080
081  /**
082   * The length of the data buffer to send.
083   */
084  int length;
085
086  /**
087   * The maximal length of the buffer.
088   */
089  int maxlen;
090
091  /**
092   * The address to which the packet should be sent or from which it
093   * was received.
094   */
095  private InetAddress address;
096
097  /**
098   * The port to which the packet should be sent or from which it was
099   * was received.
100   */
101  private int port;
102
103  /**
104   * This method initializes a new instance of <code>DatagramPacket</code>
105   * which has the specified buffer, offset, and length.
106   *
107   * @param buf The buffer for holding the incoming datagram.
108   * @param offset The offset into the buffer to start writing.
109   * @param length The maximum number of bytes to read.
110   *
111   * @since 1.2
112   */
113  public DatagramPacket(byte[] buf, int offset, int length)
114  {
115    setData(buf, offset, length);
116    address = null;
117    port = -1;
118  }
119
120  /**
121   * Initializes a new instance of <code>DatagramPacket</code> for
122   * receiving packets from the network.
123   *
124   * @param buf A buffer for storing the returned packet data
125   * @param length The length of the buffer (must be &lt;= buf.length)
126   */
127  public DatagramPacket(byte[] buf, int length)
128  {
129    this(buf, 0, length);
130  }
131
132  /**
133   * Initializes a new instance of <code>DatagramPacket</code> for
134   * transmitting packets across the network.
135   *
136   * @param buf A buffer containing the data to send
137   * @param offset The offset into the buffer to start writing from.
138   * @param length The length of the buffer (must be &lt;= buf.length)
139   * @param address The address to send to
140   * @param port The port to send to
141   *
142   * @since 1.2
143   */
144  public DatagramPacket(byte[] buf, int offset, int length,
145                        InetAddress address, int port)
146  {
147    setData(buf, offset, length);
148    setAddress(address);
149    setPort(port);
150  }
151
152  /**
153   * Initializes a new instance of <code>DatagramPacket</code> for
154   * transmitting packets across the network.
155   *
156   * @param buf A buffer containing the data to send
157   * @param length The length of the buffer (must be &lt;= buf.length)
158   * @param address The address to send to
159   * @param port The port to send to
160   */
161  public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
162  {
163    this(buf, 0, length, address, port);
164  }
165
166  /**
167   * Initializes a new instance of <code>DatagramPacket</code> for
168   * transmitting packets across the network.
169   *
170   * @param buf A buffer containing the data to send
171   * @param offset The offset into the buffer to start writing from.
172   * @param length The length of the buffer (must be &lt;= buf.length)
173   * @param address The socket address to send to
174   *
175   * @exception SocketException If an error occurs
176   * @exception IllegalArgumentException If address type is not supported
177   *
178   * @since 1.4
179   */
180  public DatagramPacket(byte[] buf, int offset, int length,
181                        SocketAddress address) throws SocketException
182  {
183    if (! (address instanceof InetSocketAddress))
184      throw new IllegalArgumentException("unsupported address type");
185
186    InetSocketAddress tmp = (InetSocketAddress) address;
187    setData(buf, offset, length);
188    setAddress(tmp.getAddress());
189    setPort(tmp.getPort());
190  }
191
192  /**
193   * Initializes a new instance of <code>DatagramPacket</code> for
194   * transmitting packets across the network.
195   *
196   * @param buf A buffer containing the data to send
197   * @param length The length of the buffer (must be &lt;= buf.length)
198   * @param address The socket address to send to
199   *
200   * @exception SocketException If an error occurs
201   * @exception IllegalArgumentException If address type is not supported
202   *
203   * @since 1.4
204   */
205  public DatagramPacket(byte[] buf, int length, SocketAddress address)
206    throws SocketException
207  {
208    this(buf, 0, length, address);
209  }
210
211  /**
212   * Returns the address that this packet is being sent to or, if it was used
213   * to receive a packet, the address that is was received from.  If the
214   * constructor that doesn not take an address was used to create this object
215   * and no packet was actually read into this object, then this method
216   * returns <code>null</code>.
217   *
218   * @return The address for this packet.
219   */
220  public synchronized InetAddress getAddress()
221  {
222    return address;
223  }
224
225  /**
226   * Returns the port number this packet is being sent to or, if it was used
227   * to receive a packet, the port that it was received from. If the
228   * constructor that doesn not take an address was used to create this object
229   * and no packet was actually read into this object, then this method
230   * will return 0.
231   *
232   * @return The port number for this packet
233   */
234  public synchronized int getPort()
235  {
236    return port;
237  }
238
239  /**
240   * Returns the data buffer for this packet
241   *
242   * @return This packet's data buffer
243   */
244  public synchronized byte[] getData()
245  {
246    return buffer;
247  }
248
249  /**
250   * This method returns the current offset value into the data buffer
251   * where data will be sent from.
252   *
253   * @return The buffer offset.
254   *
255   * @since 1.2
256   */
257  public synchronized int getOffset()
258  {
259    return offset;
260  }
261
262  /**
263   * Returns the length of the data in the buffer
264   *
265   * @return The length of the data
266   */
267  public synchronized int getLength()
268  {
269    return length;
270  }
271
272  /**
273   * This sets the address to which the data packet will be transmitted.
274   *
275   * @param address The destination address
276   *
277   * @since 1.1
278   */
279  public synchronized void setAddress(InetAddress address)
280  {
281    this.address = address;
282  }
283
284  /**
285   * This sets the port to which the data packet will be transmitted.
286   *
287   * @param port The destination port
288   *
289   * @since 1.1
290   */
291  public synchronized void setPort(int port)
292  {
293    if (port < 0 || port > 65535)
294      throw new IllegalArgumentException("Invalid port: " + port);
295
296    this.port = port;
297  }
298
299  /**
300   * Sets the address of the remote host this package will be sent
301   *
302   * @param address The socket address of the remove host
303   *
304   * @exception IllegalArgumentException If address type is not supported
305   *
306   * @since 1.4
307   */
308  public void setSocketAddress(SocketAddress address)
309    throws IllegalArgumentException
310  {
311    if (address == null)
312      throw new IllegalArgumentException("address may not be null");
313
314    InetSocketAddress tmp = (InetSocketAddress) address;
315    this.address = tmp.getAddress();
316    this.port = tmp.getPort();
317  }
318
319  /**
320   * Gets the socket address of the host this packet
321   * will be sent to/is coming from
322   *
323   * @return The socket address of the remote host
324   *
325   * @since 1.4
326   */
327  public SocketAddress getSocketAddress()
328  {
329    return new InetSocketAddress(address, port);
330  }
331
332  /**
333   * Sets the data buffer for this packet.
334   *
335   * @param buf The new buffer for this packet
336   *
337   * @exception NullPointerException If the argument is null
338   *
339   * @since 1.1
340   */
341  public void setData(byte[] buf)
342  {
343    setData(buf, 0, buf.length);
344  }
345
346  /**
347   * This method sets the data buffer for the packet.
348   *
349   * @param buf The byte array containing the data for this packet.
350   * @param offset The offset into the buffer to start reading data from.
351   * @param length The number of bytes of data in the buffer.
352   *
353   * @exception NullPointerException If the argument is null
354   *
355   * @since 1.2
356   */
357  public synchronized void setData(byte[] buf, int offset, int length)
358  {
359    // This form of setData must be used if offset is to be changed.
360    if (buf == null)
361      throw new NullPointerException("Null buffer");
362    if (offset < 0)
363      throw new IllegalArgumentException("Invalid offset: " + offset);
364
365    buffer = buf;
366    this.offset = offset;
367    setLength(length);
368  }
369
370  /**
371   * Sets the length of the data in the buffer.
372   *
373   * @param length The new length.  (Where len &lt;= buf.length)
374   *
375   * @exception IllegalArgumentException If the length is negative or
376   * if the length is greater than the packet's data buffer length
377   *
378   * @since 1.1
379   */
380  public synchronized void setLength(int length)
381  {
382    if (length < 0)
383      throw new IllegalArgumentException("Invalid length: " + length);
384    if (offset + length > buffer.length)
385      throw new IllegalArgumentException("Potential buffer overflow - offset: "
386                                         + offset + " length: " + length);
387
388    this.length = length;
389    this.maxlen = length;
390  }
391}