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    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath 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 for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package 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     */
069    public 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    }