1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.net;
19
20import org.apache.harmony.luni.util.Msg;
21
22/**
23 * This class represents a datagram packet which contains data either to be sent
24 * or received through a {@code DatagramSocket}. It holds additional information
25 * such as its source or destination host.
26 *
27 * @see DatagramSocket
28 * @since Android 1.0
29 */
30public final class DatagramPacket {
31
32    byte[] data;
33
34    int length;
35
36    InetAddress address;
37
38    int port = -1; // The default port number is -1
39
40    int offset = 0;
41
42    /**
43     * Constructs a new {@code DatagramPacket} object to receive data up to
44     * {@code length} bytes.
45     *
46     * @param data
47     *            a byte array to store the read characters.
48     * @param length
49     *            the length of the data buffer.
50     * @since Android 1.0
51     */
52    public DatagramPacket(byte[] data, int length) {
53        this(data, 0, length);
54    }
55
56    /**
57     * Constructs a new {@code DatagramPacket} object to receive data up to
58     * {@code length} bytes with a specified buffer offset.
59     *
60     * @param data
61     *            a byte array to store the read characters.
62     * @param offset
63     *            the offset of the byte array where the bytes is written.
64     * @param length
65     *            the length of the data.
66     * @since Android 1.0
67     */
68    public DatagramPacket(byte[] data, int offset, int length) {
69        super();
70        setData(data, offset, length);
71    }
72
73    /**
74     * Constructs a new {@code DatagramPacket} object to send data to the port
75     * {@code aPort} of the address {@code host}. The {@code length} must be
76     * lesser than or equal to the size of {@code data}. The first {@code
77     * length} bytes from the byte array position {@code offset} are sent.
78     *
79     * @param data
80     *            a byte array which stores the characters to be sent.
81     * @param offset
82     *            the offset of {@code data} where to read from.
83     * @param length
84     *            the length of data.
85     * @param host
86     *            the address of the target host.
87     * @param aPort
88     *            the port of the target host.
89     * @since Android 1.0
90     */
91    public DatagramPacket(byte[] data, int offset, int length,
92            InetAddress host, int aPort) {
93        this(data, offset, length);
94        setPort(aPort);
95        address = host;
96    }
97
98    /**
99     * Constructs a new {@code DatagramPacket} object to send data to the port
100     * {@code aPort} of the address {@code host}. The {@code length} must be
101     * lesser than or equal to the size of {@code data}. The first {@code
102     * length} bytes are sent.
103     *
104     * @param data
105     *            a byte array which stores the characters to be sent.
106     * @param length
107     *            the length of data.
108     * @param host
109     *            the address of the target host.
110     * @param port
111     *            the port of the target host.
112     * @since Android 1.0
113     */
114    public DatagramPacket(byte[] data, int length, InetAddress host, int port) {
115        this(data, 0, length, host, port);
116    }
117
118    /**
119     * Gets the sender or destination IP address of this datagram packet.
120     *
121     * @return the address from where the datagram was received or to which it
122     *         is sent.
123     * @since Android 1.0
124     */
125    public synchronized InetAddress getAddress() {
126        return address;
127    }
128
129    /**
130     * Gets the data of this datagram packet.
131     *
132     * @return the received data or the data to be sent.
133     * @since Android 1.0
134     */
135    public synchronized byte[] getData() {
136        return data;
137    }
138
139    /**
140     * Gets the length of the data stored in this datagram packet.
141     *
142     * @return the length of the received data or the data to be sent.
143     * @since Android 1.0
144     */
145    public synchronized int getLength() {
146        return length;
147    }
148
149    /**
150     * Gets the offset of the data stored in this datagram packet.
151     *
152     * @return the position of the received data or the data to be sent.
153     * @since Android 1.0
154     */
155    public synchronized int getOffset() {
156        return offset;
157    }
158
159    /**
160     * Gets the port number of the target or sender host of this datagram
161     * packet.
162     *
163     * @return the port number of the origin or target host.
164     * @since Android 1.0
165     */
166    public synchronized int getPort() {
167        return port;
168    }
169
170    /**
171     * Sets the IP address of the target host.
172     *
173     * @param addr
174     *            the target host address.
175     * @since Android 1.0
176     */
177    public synchronized void setAddress(InetAddress addr) {
178        address = addr;
179    }
180
181    /**
182     * Sets the data buffer for this datagram packet.
183     *
184     * @param buf
185     *            the buffer to store the data.
186     * @param anOffset
187     *            the buffer offset where the data is stored.
188     * @param aLength
189     *            the length of the data to be sent or the length of buffer to
190     *            store the received data.
191     * @since Android 1.0
192     */
193    public synchronized void setData(byte[] buf, int anOffset, int aLength) {
194        if (0 > anOffset || anOffset > buf.length || 0 > aLength
195                || aLength > buf.length - anOffset) {
196            throw new IllegalArgumentException(Msg.getString("K002f")); //$NON-NLS-1$
197        }
198        data = buf;
199        offset = anOffset;
200        length = aLength;
201    }
202
203    /**
204     * Sets the data buffer for this datagram packet. The length of the datagram
205     * packet is set to the buffer length.
206     *
207     * @param buf
208     *            the buffer to store the data.
209     * @since Android 1.0
210     */
211    public synchronized void setData(byte[] buf) {
212        length = buf.length; // This will check for null
213        data = buf;
214        offset = 0;
215    }
216
217    /**
218     * Sets the length of the datagram packet. This length plus the offset must
219     * be lesser than or equal to the buffer size.
220     *
221     * @param len
222     *            the length of this datagram packet.
223     * @since Android 1.0
224     */
225    public synchronized void setLength(int len) {
226        if (0 > len || offset + len > data.length) {
227            throw new IllegalArgumentException(Msg.getString("K002f")); //$NON-NLS-1$
228        }
229        length = len;
230    }
231
232    /**
233     * Sets the port number of the target host of this datagram packet.
234     *
235     * @param aPort
236     *            the target host port number.
237     * @since Android 1.0
238     */
239    public synchronized void setPort(int aPort) {
240        if (aPort < 0 || aPort > 65535) {
241            throw new IllegalArgumentException(Msg.getString("K0325", aPort)); //$NON-NLS-1$
242        }
243        port = aPort;
244    }
245
246    /**
247     * Constructs a new {@code DatagramPacket} object to send data to the
248     * address {@code sockAddr}. The {@code length} must be lesser than or equal
249     * to the size of {@code data}. The first {@code length} bytes of the data
250     * are sent.
251     *
252     * @param data
253     *            the byte array to store the data.
254     * @param length
255     *            the length of the data.
256     * @param sockAddr
257     *            the target host address and port.
258     * @throws SocketException
259     *             if an error in the underlying protocol occurs.
260     * @since Android 1.0
261     */
262    public DatagramPacket(byte[] data, int length, SocketAddress sockAddr) throws SocketException {
263        this(data, 0, length);
264        setSocketAddress(sockAddr);
265    }
266
267    /**
268     * Constructs a new {@code DatagramPacket} object to send data to the
269     * address {@code sockAddr}. The {@code length} must be lesser than or equal
270     * to the size of {@code data}. The first {@code length} bytes of the data
271     * are sent.
272     *
273     * @param data
274     *            the byte array to store the data.
275     * @param offset
276     *            the offset of the data.
277     * @param length
278     *            the length of the data.
279     * @param sockAddr
280     *            the target host address and port.
281     * @throws SocketException
282     *             if an error in the underlying protocol occurs.
283     * @since Android 1.0
284     */
285    public DatagramPacket(byte[] data, int offset, int length,
286            SocketAddress sockAddr) throws SocketException {
287        this(data, offset, length);
288        setSocketAddress(sockAddr);
289    }
290
291    /**
292     * Gets the host address and the port to which this datagram packet is sent
293     * as a {@code SocketAddress} object.
294     *
295     * @return the SocketAddress of the target host.
296     * @since Android 1.0
297     */
298    public synchronized SocketAddress getSocketAddress() {
299        return new InetSocketAddress(getAddress(), getPort());
300    }
301
302    /**
303     * Sets the {@code SocketAddress} for this datagram packet.
304     *
305     * @param sockAddr
306     *            the SocketAddress of the target host.
307     * @since Android 1.0
308     */
309    public synchronized void setSocketAddress(SocketAddress sockAddr) {
310        if (!(sockAddr instanceof InetSocketAddress)) {
311            throw new IllegalArgumentException(Msg.getString(
312                    "K0316", sockAddr == null ? null : sockAddr.getClass())); //$NON-NLS-1$
313        }
314        InetSocketAddress inetAddr = (InetSocketAddress) sockAddr;
315        port = inetAddr.getPort();
316        address = inetAddr.getAddress();
317    }
318}
319