1 /***
2 *
3 * Copyright 2004 Hiram Chirino
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * 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 **/
18 package org.activeio;
19
20 import java.io.EOFException;
21 import java.io.IOException;
22
23
24 /***
25 * Used to write and read primitives to and from a Packet.
26 */
27 final public class PacketData {
28
29 final private Packet packet;
30 private final boolean bigEndian;
31
32 public PacketData(Packet packet) {
33 this(packet, true);
34 }
35
36 public PacketData(Packet packet, boolean bigEndian) {
37 this.packet = packet;
38 this.bigEndian = bigEndian;
39 }
40
41 private void spaceNeeded(int space) throws IOException {
42 if (packet.remaining() < space)
43 throw new EOFException("Not enough space left in the packet.");
44 }
45
46 public void readFully(byte[] b) throws IOException {
47 readFully(b, 0, b.length);
48 }
49
50 public void readFully(byte[] b, int off, int len) throws IOException {
51 spaceNeeded(len);
52 packet.read(b, off, len);
53 }
54
55 public int skipBytes(int n) throws IOException {
56 int rc = Math.min(n, packet.remaining());
57 packet.position(packet.position() + rc);
58 return rc;
59 }
60
61 public boolean readBoolean() throws IOException {
62 spaceNeeded(1);
63 return packet.read() != 0;
64 }
65
66 public byte readByte() throws IOException {
67 spaceNeeded(1);
68 return (byte) packet.read();
69 }
70
71 public int readUnsignedByte() throws IOException {
72 spaceNeeded(1);
73 return packet.read();
74 }
75
76 public short readShort() throws IOException {
77 spaceNeeded(2);
78 if( bigEndian ) {
79 return (short) ((packet.read() << 8) + (packet.read() << 0));
80 } else {
81 return (short) ((packet.read() << 0) + (packet.read() << 8) );
82 }
83 }
84
85 public int readUnsignedShort() throws IOException {
86 spaceNeeded(2);
87 if( bigEndian ) {
88 return ((packet.read() << 8) + (packet.read() << 0));
89 } else {
90 return ((packet.read() << 0) + (packet.read() << 8) );
91 }
92 }
93
94 public char readChar() throws IOException {
95 spaceNeeded(2);
96 if( bigEndian ) {
97 return (char) ((packet.read() << 8) + (packet.read() << 0));
98 } else {
99 return (char) ((packet.read() << 0) + (packet.read() << 8) );
100 }
101 }
102
103 public int readInt() throws IOException {
104 spaceNeeded(4);
105 if( bigEndian ) {
106 return ((packet.read() << 24) +
107 (packet.read() << 16) +
108 (packet.read() << 8) +
109 (packet.read() << 0));
110 } else {
111 return ((packet.read() << 0) +
112 (packet.read() << 8) +
113 (packet.read() << 16) +
114 (packet.read() << 24));
115 }
116 }
117
118 public long readLong() throws IOException {
119 spaceNeeded(8);
120 if( bigEndian ) {
121 return (((long) packet.read() << 56) +
122 ((long) packet.read() << 48) +
123 ((long) packet.read() << 40) +
124 ((long) packet.read() << 32) +
125 ((long) packet.read() << 24) +
126 ((packet.read()) << 16) +
127 ((packet.read()) << 8) +
128 ((packet.read()) << 0));
129 } else {
130 return ((packet.read() << 0) +
131 (packet.read() << 8) +
132 (packet.read() << 16) +
133 ((long) packet.read() << 24) +
134 ((long) packet.read() << 32) +
135 ((long) packet.read() << 40) +
136 ((long) packet.read() << 48) +
137 ((long) packet.read() << 56));
138 }
139 }
140
141 public double readDouble() throws IOException {
142 return Double.longBitsToDouble(readLong());
143 }
144
145 public float readFloat() throws IOException {
146 return Float.intBitsToFloat(readInt());
147 }
148
149 public void write(int b) throws IOException {
150 spaceNeeded(1);
151 packet.write(b);
152 }
153
154 public void write(byte[] b) throws IOException {
155 write(b, 0, b.length);
156 }
157
158 public void write(byte[] b, int off, int len) throws IOException {
159 spaceNeeded(len);
160 packet.write(b, off, len);
161 }
162
163 public void writeBoolean(boolean v) throws IOException {
164 spaceNeeded(1);
165 packet.write(v ? 1 : 0);
166 }
167
168 public void writeByte(int v) throws IOException {
169 spaceNeeded(1);
170 packet.write(v);
171 }
172
173 public void writeShort(int v) throws IOException {
174 spaceNeeded(2);
175
176 if (bigEndian) {
177 packet.write((v >>> 8) & 0xFF);
178 packet.write((v >>> 0) & 0xFF);
179 } else {
180 packet.write((v >>> 0) & 0xFF);
181 packet.write((v >>> 8) & 0xFF);
182 }
183 }
184
185 public void writeChar(int v) throws IOException {
186 spaceNeeded(2);
187 if (bigEndian) {
188 packet.write((v >>> 8) & 0xFF);
189 packet.write((v >>> 0) & 0xFF);
190 } else {
191 packet.write((v >>> 0) & 0xFF);
192 packet.write((v >>> 8) & 0xFF);
193 }
194 }
195
196 public void writeInt(int v) throws IOException {
197 spaceNeeded(4);
198 if (bigEndian) {
199 packet.write((v >>> 24) & 0xFF);
200 packet.write((v >>> 16) & 0xFF);
201 packet.write((v >>> 8) & 0xFF);
202 packet.write((v >>> 0) & 0xFF);
203 } else {
204 packet.write((v >>> 0) & 0xFF);
205 packet.write((v >>> 8) & 0xFF);
206 packet.write((v >>> 16) & 0xFF);
207 packet.write((v >>> 24) & 0xFF);
208 }
209 }
210
211 public void writeLong(long v) throws IOException {
212 spaceNeeded(8);
213 if (bigEndian) {
214 packet.write((int) (v >>> 56) & 0xFF);
215 packet.write((int) (v >>> 48) & 0xFF);
216 packet.write((int) (v >>> 40) & 0xFF);
217 packet.write((int) (v >>> 32) & 0xFF);
218 packet.write((int) (v >>> 24) & 0xFF);
219 packet.write((int) (v >>> 16) & 0xFF);
220 packet.write((int) (v >>> 8) & 0xFF);
221 packet.write((int) (v >>> 0) & 0xFF);
222 } else {
223 packet.write((int) (v >>> 0) & 0xFF);
224 packet.write((int) (v >>> 8) & 0xFF);
225 packet.write((int) (v >>> 16) & 0xFF);
226 packet.write((int) (v >>> 24) & 0xFF);
227 packet.write((int) (v >>> 32) & 0xFF);
228 packet.write((int) (v >>> 40) & 0xFF);
229 packet.write((int) (v >>> 48) & 0xFF);
230 packet.write((int) (v >>> 56) & 0xFF);
231 }
232 }
233
234 public void writeDouble(double v) throws IOException {
235 writeLong(Double.doubleToLongBits(v));
236 }
237
238 public void writeFloat(float v) throws IOException {
239 writeInt(Float.floatToIntBits(v));
240 }
241
242 public void writeRawDouble(double v) throws IOException {
243 writeLong(Double.doubleToRawLongBits(v));
244 }
245
246 public void writeRawFloat(float v) throws IOException {
247 writeInt(Float.floatToRawIntBits(v));
248 }
249
250 }