View Javadoc

1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2007 Ludovic Dewailly <ludovic.dewailly@dreameffect.org>
4    *
5    *  It is licensed under the following two licenses as alternatives:
6    *    1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
7    *    2. Apache License (the "AL") Version 2.0
8    *
9    *  You may not use this file except in compliance with at least one of
10   *  the above two licenses.
11   *
12   *  You may obtain a copy of the LGPL at
13   *      http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
14   *
15   *  You may obtain a copy of the AL at
16   *      http://www.apache.org/licenses/LICENSE-2.0
17   *
18   *  Unless required by applicable law or agreed to in writing, software
19   *  distributed under the License is distributed on an "AS IS" BASIS,
20   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   *  See the LGPL or the AL for the specific language governing permissions and
22   *  limitations.
23   */
24  
25  package org.microemu.cldc.datagram;
26  
27  import java.io.ByteArrayInputStream;
28  import java.io.DataInputStream;
29  import java.io.DataOutputStream;
30  import java.io.IOException;
31  import java.io.OutputStream;
32  import java.net.DatagramPacket;
33  import java.net.InetAddress;
34  import java.nio.BufferOverflowException;
35  
36  import javax.microedition.io.Datagram;
37  
38  /**
39   * {@link Datagram} realisation.
40   */
41  public class DatagramImpl implements Datagram {
42  
43  	/**
44  	 * The encapsulated {@link DatagramPacket}
45  	 */
46  	private DatagramPacket packet;
47  
48  	/**
49  	 * Our specialised {@link OutputStream} to write to the packet buffer
50  	 */
51  	private BufferOutputStream os;
52  
53  	/**
54  	 * Used to write to the packet buffer
55  	 */
56  	private DataOutputStream dos;
57  
58  	/**
59  	 * Used to read from packet buffer
60  	 */
61  	private DataInputStream dis;
62  
63  	/**
64  	 * A specialisation of {@link OutputStream} that writes into the
65  	 * encapsulated {@link DatagramPacket} buffer
66  	 */
67  	class BufferOutputStream extends OutputStream {
68  
69  		private int originalOffset;
70  
71  		private int offset;
72  
73  		public BufferOutputStream() {
74  			this.originalOffset = packet.getOffset();
75  			this.offset = originalOffset;
76  		}
77  
78  		public void write(int b) throws IOException {
79  			byte[] buffer = packet.getData();
80  			if (offset == buffer.length - 1) {
81  				throw new BufferOverflowException();
82  			}
83  			buffer[offset++] = (byte) b;
84  		}
85  
86  		public void reset() {
87  			offset = originalOffset;
88  		}
89  	}
90  
91  	/**
92  	 * Instantiates a new {@link DatagramImpl} with the given buffer size.
93  	 * 
94  	 * @param size
95  	 *            the buffer size
96  	 * 
97  	 * @throws IllegalAccessException
98  	 *             if <tt>size</tt> is negative or equal to zero
99  	 */
100 	DatagramImpl(int size) {
101 		if (size <= 0) {
102 			throw new IllegalArgumentException("Invalid size: " + size);
103 		}
104 		packet = new DatagramPacket(new byte[size], size);
105 		initialiseInOut();
106 	}
107 
108 	/**
109 	 * Instantiates a new {@link DatagramImpl} with the given buffer.
110 	 * 
111 	 * @param buff
112 	 *            the buffer to use
113 	 * @param length
114 	 *            the length of the buffer to use
115 	 */
116 	DatagramImpl(byte[] buff, int length) {
117 		packet = new DatagramPacket(buff, length);
118 		initialiseInOut();
119 	}
120 
121 	/**
122 	 * Initialises the input and output streams.
123 	 */
124 	private void initialiseInOut() {
125 		os = new BufferOutputStream();
126 		dos = new DataOutputStream(os);
127 		dis = new DataInputStream(new ByteArrayInputStream(packet.getData()));
128 	}
129 
130 	public String getAddress() {
131 		return packet.getAddress().getCanonicalHostName() + ":" + packet.getPort();
132 	}
133 
134 	public byte[] getData() {
135 		return packet.getData();
136 	}
137 
138 	public int getLength() {
139 		return packet.getLength();
140 	}
141 
142 	public int getOffset() {
143 		return packet.getOffset();
144 	}
145 
146 	public void reset() {
147 		try {
148 			os.reset();
149 			dis.reset();
150 		} catch (IOException e) {
151 			// just print it
152 			e.printStackTrace();
153 		}
154 	}
155 
156 	public void setAddress(String address) throws IOException {
157 		if (address == null) {
158 			throw new NullPointerException("address cannot be null");
159 		}
160 		int index = address.indexOf(':');
161 		if (index == -1) {
162 			throw new IllegalArgumentException("Missing port in address: " + address);
163 		}
164 		String host = address.substring(0, index);
165 		String port = address.substring(index + 1);
166 		packet.setAddress(InetAddress.getByName(host));
167 		packet.setPort(Integer.parseInt(port));
168 	}
169 
170 	public void setAddress(Datagram reference) {
171 		packet.setAddress(((DatagramImpl) reference).getDatagramPacket().getAddress());
172 		packet.setPort(((DatagramImpl) reference).getDatagramPacket().getPort());
173 	}
174 
175 	public void setData(byte[] buffer, int offset, int len) {
176 		packet.setData(buffer, offset, len);
177 	}
178 
179 	public void setLength(int len) {
180 		packet.setLength(len);
181 	}
182 
183 	public boolean readBoolean() throws IOException {
184 		return dis.readBoolean();
185 	}
186 
187 	public byte readByte() throws IOException {
188 		return dis.readByte();
189 	}
190 
191 	public char readChar() throws IOException {
192 		return dis.readChar();
193 	}
194 
195 	public double readDouble() throws IOException {
196 		return dis.readDouble();
197 	}
198 
199 	public float readFloat() throws IOException {
200 		return dis.readFloat();
201 	}
202 
203 	public void readFully(byte[] b) throws IOException {
204 		dis.readFully(b);
205 	}
206 
207 	public void readFully(byte[] b, int off, int len) throws IOException {
208 		dis.read(b, off, len);
209 	}
210 
211 	public int readInt() throws IOException {
212 		return dis.readInt();
213 	}
214 
215 	public String readLine() throws IOException {
216 		return dis.readLine();
217 	}
218 
219 	public long readLong() throws IOException {
220 		return dis.readLong();
221 	}
222 
223 	public short readShort() throws IOException {
224 		return dis.readShort();
225 	}
226 
227 	public String readUTF() throws IOException {
228 		return dis.readUTF();
229 	}
230 
231 	public int readUnsignedByte() throws IOException {
232 		return dis.readUnsignedByte();
233 	}
234 
235 	public int readUnsignedShort() throws IOException {
236 		return dis.readUnsignedShort();
237 	}
238 
239 	public int skipBytes(int n) throws IOException {
240 		return dis.skipBytes(n);
241 	}
242 
243 	public void write(int b) throws IOException {
244 		dos.write(b);
245 	}
246 
247 	public void write(byte[] b) throws IOException {
248 		dos.write(b);
249 	}
250 
251 	public void write(byte[] b, int off, int len) throws IOException {
252 		dos.write(b, off, len);
253 	}
254 
255 	public void writeBoolean(boolean v) throws IOException {
256 		dos.writeBoolean(v);
257 	}
258 
259 	public void writeByte(int v) throws IOException {
260 		dos.writeByte(v);
261 	}
262 
263 	public void writeBytes(String s) throws IOException {
264 		dos.writeBytes(s);
265 	}
266 
267 	public void writeChar(int v) throws IOException {
268 		dos.writeChar(v);
269 	}
270 
271 	public void writeChars(String v) throws IOException {
272 		dos.writeChars(v);
273 	}
274 
275 	public void writeDouble(double v) throws IOException {
276 		dos.writeDouble(v);
277 	}
278 
279 	public void writeFloat(float v) throws IOException {
280 		dos.writeFloat(v);
281 	}
282 
283 	public void writeInt(int v) throws IOException {
284 		dos.writeInt(v);
285 	}
286 
287 	public void writeLong(long v) throws IOException {
288 		dos.writeLong(v);
289 	}
290 
291 	public void writeShort(int v) throws IOException {
292 		dos.writeShort(v);
293 	}
294 
295 	public void writeUTF(String str) throws IOException {
296 		dos.writeUTF(str);
297 	}
298 
299 	/**
300 	 * Answers the underlying {@link DatagramPacket}.
301 	 * 
302 	 * @return the encapsulated packet
303 	 */
304 	DatagramPacket getDatagramPacket() {
305 		return packet;
306 	}
307 }