1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package java.net;
28
29/**
30 * This class represents a datagram packet.
31 * <p>
32 * Datagram packets are used to implement a connectionless packet
33 * delivery service. Each message is routed from one machine to
34 * another based solely on information contained within that packet.
35 * Multiple packets sent from one machine to another might be routed
36 * differently, and might arrive in any order. Packet delivery is
37 * not guaranteed.
38 *
39 * @author  Pavani Diwanji
40 * @author  Benjamin Renaud
41 * @since   JDK1.0
42 */
43public final
44class DatagramPacket {
45
46    /**
47     * Perform class initialization
48     */
49    static {
50        init();
51    }
52
53    /*
54     * The fields of this class are package-private since DatagramSocketImpl
55     * classes needs to access them.
56     */
57    byte[] buf;
58    int offset;
59    int length;
60    int bufLength;
61    InetAddress address;
62    int port;
63
64    /**
65     * Constructs a <code>DatagramPacket</code> for receiving packets of
66     * length <code>length</code>, specifying an offset into the buffer.
67     * <p>
68     * The <code>length</code> argument must be less than or equal to
69     * <code>buf.length</code>.
70     *
71     * @param   buf      buffer for holding the incoming datagram.
72     * @param   offset   the offset for the buffer
73     * @param   length   the number of bytes to read.
74     *
75     * @since 1.2
76     */
77    public DatagramPacket(byte buf[], int offset, int length) {
78        setData(buf, offset, length);
79        this.address = null;
80        this.port = -1;
81    }
82
83    /**
84     * Constructs a <code>DatagramPacket</code> for receiving packets of
85     * length <code>length</code>.
86     * <p>
87     * The <code>length</code> argument must be less than or equal to
88     * <code>buf.length</code>.
89     *
90     * @param   buf      buffer for holding the incoming datagram.
91     * @param   length   the number of bytes to read.
92     */
93    public DatagramPacket(byte buf[], int length) {
94        this (buf, 0, length);
95    }
96
97    /**
98     * Constructs a datagram packet for sending packets of length
99     * <code>length</code> with offset <code>ioffset</code>to the
100     * specified port number on the specified host. The
101     * <code>length</code> argument must be less than or equal to
102     * <code>buf.length</code>.
103     *
104     * @param   buf      the packet data.
105     * @param   offset   the packet data offset.
106     * @param   length   the packet data length.
107     * @param   address  the destination address.
108     * @param   port     the destination port number.
109     * @see java.net.InetAddress
110     *
111     * @since 1.2
112     */
113    public DatagramPacket(byte buf[], int offset, int length,
114                          InetAddress address, int port) {
115        setData(buf, offset, length);
116        setAddress(address);
117        setPort(port);
118    }
119
120    /**
121     * Constructs a datagram packet for sending packets of length
122     * <code>length</code> with offset <code>ioffset</code>to the
123     * specified port number on the specified host. The
124     * <code>length</code> argument must be less than or equal to
125     * <code>buf.length</code>.
126     *
127     * @param   buf      the packet data.
128     * @param   offset   the packet data offset.
129     * @param   length   the packet data length.
130     * @param   address  the destination socket address.
131     * @throws  IllegalArgumentException if address type is not supported
132     * @see java.net.InetAddress
133     *
134     * @since 1.4
135     */
136    public DatagramPacket(byte buf[], int offset, int length,
137                          SocketAddress address) throws SocketException {
138        setData(buf, offset, length);
139        setSocketAddress(address);
140    }
141
142    /**
143     * Constructs a datagram packet for sending packets of length
144     * <code>length</code> to the specified port number on the specified
145     * host. The <code>length</code> argument must be less than or equal
146     * to <code>buf.length</code>.
147     *
148     * @param   buf      the packet data.
149     * @param   length   the packet length.
150     * @param   address  the destination address.
151     * @param   port     the destination port number.
152     * @see     java.net.InetAddress
153     */
154    public DatagramPacket(byte buf[], int length,
155                          InetAddress address, int port) {
156        this(buf, 0, length, address, port);
157    }
158
159    /**
160     * Constructs a datagram packet for sending packets of length
161     * <code>length</code> to the specified port number on the specified
162     * host. The <code>length</code> argument must be less than or equal
163     * to <code>buf.length</code>.
164     *
165     * @param   buf      the packet data.
166     * @param   length   the packet length.
167     * @param   address  the destination address.
168     * @throws  IllegalArgumentException if address type is not supported
169     * @since 1.4
170     * @see     java.net.InetAddress
171     */
172    public DatagramPacket(byte buf[], int length,
173                          SocketAddress address) throws SocketException {
174        this(buf, 0, length, address);
175    }
176
177    /**
178     * Returns the IP address of the machine to which this datagram is being
179     * sent or from which the datagram was received.
180     *
181     * @return  the IP address of the machine to which this datagram is being
182     *          sent or from which the datagram was received.
183     * @see     java.net.InetAddress
184     * @see #setAddress(java.net.InetAddress)
185     */
186    public synchronized InetAddress getAddress() {
187        return address;
188    }
189
190    /**
191     * Returns the port number on the remote host to which this datagram is
192     * being sent or from which the datagram was received.
193     *
194     * @return  the port number on the remote host to which this datagram is
195     *          being sent or from which the datagram was received.
196     * @see #setPort(int)
197     */
198    public synchronized int getPort() {
199        return port;
200    }
201
202    /**
203     * Returns the data buffer. The data received or the data to be sent
204     * starts from the <code>offset</code> in the buffer,
205     * and runs for <code>length</code> long.
206     *
207     * @return  the buffer used to receive or  send data
208     * @see #setData(byte[], int, int)
209     */
210    public synchronized byte[] getData() {
211        return buf;
212    }
213
214    /**
215     * Returns the offset of the data to be sent or the offset of the
216     * data received.
217     *
218     * @return  the offset of the data to be sent or the offset of the
219     *          data received.
220     *
221     * @since 1.2
222     */
223    public synchronized int getOffset() {
224        return offset;
225    }
226
227    /**
228     * Returns the length of the data to be sent or the length of the
229     * data received.
230     *
231     * @return  the length of the data to be sent or the length of the
232     *          data received.
233     * @see #setLength(int)
234     */
235    public synchronized int getLength() {
236        return length;
237    }
238
239    /**
240     * Set the data buffer for this packet. This sets the
241     * data, length and offset of the packet.
242     *
243     * @param buf the buffer to set for this packet
244     *
245     * @param offset the offset into the data
246     *
247     * @param length the length of the data
248     *       and/or the length of the buffer used to receive data
249     *
250     * @exception NullPointerException if the argument is null
251     *
252     * @see #getData
253     * @see #getOffset
254     * @see #getLength
255     *
256     * @since 1.2
257     */
258    public synchronized void setData(byte[] buf, int offset, int length) {
259        /* this will check to see if buf is null */
260        if (length < 0 || offset < 0 ||
261            (length + offset) < 0 ||
262            ((length + offset) > buf.length)) {
263            throw new IllegalArgumentException("illegal length or offset");
264        }
265        this.buf = buf;
266        this.length = length;
267        this.bufLength = length;
268        this.offset = offset;
269    }
270
271    /**
272     * Sets the IP address of the machine to which this datagram
273     * is being sent.
274     * @param iaddr the <code>InetAddress</code>
275     * @since   JDK1.1
276     * @see #getAddress()
277     */
278    public synchronized void setAddress(InetAddress iaddr) {
279        address = iaddr;
280    }
281
282    // ----- BEGIN android -----
283    /**
284     * Sets 'length' without changing 'userSuppliedLength', after receiving a packet.
285     * @hide for IoBridge
286     */
287    public void setReceivedLength(int length) {
288        this.length = length;
289    }
290    // ----- END android -----
291
292    /**
293     * Sets the port number on the remote host to which this datagram
294     * is being sent.
295     * @param iport the port number
296     * @since   JDK1.1
297     * @see #getPort()
298     */
299    public synchronized void setPort(int iport) {
300        if (iport < 0 || iport > 0xFFFF) {
301            throw new IllegalArgumentException("Port out of range:"+ iport);
302        }
303        port = iport;
304    }
305
306    /**
307     * Sets the SocketAddress (usually IP address + port number) of the remote
308     * host to which this datagram is being sent.
309     *
310     * @param address the <code>SocketAddress</code>
311     * @throws  IllegalArgumentException if address is null or is a
312     *          SocketAddress subclass not supported by this socket
313     *
314     * @since 1.4
315     * @see #getSocketAddress
316     */
317    public synchronized void setSocketAddress(SocketAddress address) {
318        if (address == null || !(address instanceof InetSocketAddress))
319            throw new IllegalArgumentException("unsupported address type");
320        InetSocketAddress addr = (InetSocketAddress) address;
321        if (addr.isUnresolved())
322            throw new IllegalArgumentException("unresolved address");
323        setAddress(addr.getAddress());
324        setPort(addr.getPort());
325    }
326
327    /**
328     * Gets the SocketAddress (usually IP address + port number) of the remote
329     * host that this packet is being sent to or is coming from.
330     *
331     * @return the <code>SocketAddress</code>
332     * @since 1.4
333     * @see #setSocketAddress
334     */
335    public synchronized SocketAddress getSocketAddress() {
336        return new InetSocketAddress(getAddress(), getPort());
337    }
338
339    /**
340     * Set the data buffer for this packet. With the offset of
341     * this DatagramPacket set to 0, and the length set to
342     * the length of <code>buf</code>.
343     *
344     * @param buf the buffer to set for this packet.
345     *
346     * @exception NullPointerException if the argument is null.
347     *
348     * @see #getLength
349     * @see #getData
350     *
351     * @since JDK1.1
352     */
353    public synchronized void setData(byte[] buf) {
354        if (buf == null) {
355            throw new NullPointerException("null packet buffer");
356        }
357        this.buf = buf;
358        this.offset = 0;
359        this.length = buf.length;
360        this.bufLength = buf.length;
361    }
362
363    /**
364     * Set the length for this packet. The length of the packet is
365     * the number of bytes from the packet's data buffer that will be
366     * sent, or the number of bytes of the packet's data buffer that
367     * will be used for receiving data. The length must be lesser or
368     * equal to the offset plus the length of the packet's buffer.
369     *
370     * @param length the length to set for this packet.
371     *
372     * @exception IllegalArgumentException if the length is negative
373     * of if the length is greater than the packet's data buffer
374     * length.
375     *
376     * @see #getLength
377     * @see #setData
378     *
379     * @since JDK1.1
380     */
381    public synchronized void setLength(int length) {
382        if ((length + offset) > buf.length || length < 0 ||
383            (length + offset) < 0) {
384            throw new IllegalArgumentException("illegal length");
385        }
386        this.length = length;
387        this.bufLength = this.length;
388    }
389
390    /**
391     * Perform class load-time initializations.
392     */
393    private native static void init();
394}
395