1 package org.djutils.serialization;
2
3 import java.io.UnsupportedEncodingException;
4 import java.nio.ByteOrder;
5
6
7
8
9
10
11
12
13
14
15
16
17 public final class EndianUtil
18 {
19
20 private final boolean bigEndian;
21
22
23 private static final boolean PLATFORM_BIG_ENDIAN = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
24
25
26
27
28
29 public static boolean isPlatformBigEndian()
30 {
31 return PLATFORM_BIG_ENDIAN;
32 }
33
34
35 public static final EndianUtil BIG_ENDIAN = new EndianUtil(true);
36
37
38 public static final EndianUtil LITTLE_ENDIAN = new EndianUtil(false);
39
40
41
42
43
44
45 private EndianUtil(final boolean bigEndian)
46 {
47 this.bigEndian = bigEndian;
48 }
49
50
51
52
53
54 public static EndianUtil bigEndian()
55 {
56 return BIG_ENDIAN;
57 }
58
59
60
61
62
63 public static EndianUtil littleEndian()
64 {
65 return LITTLE_ENDIAN;
66 }
67
68
69
70
71
72 public boolean isBigEndian()
73 {
74 return this.bigEndian;
75 }
76
77
78
79
80
81
82
83 public short decodeShort(final byte[] message, final int pointer)
84 {
85 if (this.bigEndian)
86 {
87 return (short) (((message[pointer] & 0xff) << 8) | ((message[pointer + 1] & 0xff)));
88 }
89 else
90 {
91 return (short) (((message[pointer + 1] & 0xff) << 8) | ((message[pointer] & 0xff)));
92 }
93 }
94
95
96
97
98
99
100
101 public int decodeInt(final byte[] message, final int pointer)
102 {
103 if (this.bigEndian)
104 {
105 return (((message[pointer] & 0xff) << 24) | ((message[pointer + 1] & 0xff) << 16)
106 | ((message[pointer + 2] & 0xff) << 8) | ((message[pointer + 3] & 0xff)));
107 }
108 else
109 {
110 return (((message[pointer + 3] & 0xff) << 24) | ((message[pointer + 2] & 0xff) << 16)
111 | ((message[pointer + 1] & 0xff) << 8) | ((message[pointer] & 0xff)));
112 }
113 }
114
115
116
117
118
119
120
121 public long decodeLong(final byte[] message, final int pointer)
122 {
123 if (this.bigEndian)
124 {
125 return ((((long) message[pointer]) << 56) | (((long) message[pointer + 1] & 0xff) << 48)
126 | (((long) message[pointer + 2] & 0xff) << 40) | (((long) message[pointer + 3] & 0xff) << 32)
127 | (((long) message[pointer + 4] & 0xff) << 24) | (((long) message[pointer + 5] & 0xff) << 16)
128 | (((long) message[pointer + 6] & 0xff) << 8) | (((long) message[pointer + 7] & 0xff)));
129 }
130 else
131 {
132 return ((((long) message[pointer + 7]) << 56) | (((long) message[pointer + 6] & 0xff) << 48)
133 | (((long) message[pointer + 5] & 0xff) << 40) | (((long) message[pointer + 4] & 0xff) << 32)
134 | (((long) message[pointer + 3] & 0xff) << 24) | (((long) message[pointer + 2] & 0xff) << 16)
135 | (((long) message[pointer + 1] & 0xff) << 8) | (((long) message[pointer] & 0xff)));
136 }
137 }
138
139
140
141
142
143
144
145 public float decodeFloat(final byte[] message, final int pointer)
146 {
147 int bits = decodeInt(message, pointer);
148 return Float.intBitsToFloat(bits);
149 }
150
151
152
153
154
155
156
157 public double decodeDouble(final byte[] message, final int pointer)
158 {
159 long bits = decodeLong(message, pointer);
160 return Double.longBitsToDouble(bits);
161 }
162
163
164
165
166
167
168
169 public char decodeChar(final byte[] message, final int pointer)
170 {
171 return (char) decodeShort(message, pointer);
172 }
173
174
175
176
177
178
179
180
181 public String decodeUTF8String(final byte[] message, final int pointer) throws SerializationException
182 {
183 int len = decodeInt(message, pointer);
184 byte[] c = new byte[len];
185 for (int i = 0; i < len; i++)
186 {
187 c[i] = message[pointer + i + 4];
188 }
189 try
190 {
191 return new String(c, "UTF-8");
192 }
193 catch (UnsupportedEncodingException e)
194 {
195 throw new SerializationException(e);
196 }
197 }
198
199
200
201
202
203
204
205 public String decodeUTF16String(final byte[] message, final int pointer)
206 {
207 int len = decodeInt(message, pointer);
208 char[] c = new char[len];
209 for (int i = 0; i < len; i++)
210 {
211 c[i] = decodeChar(message, pointer + 2 * i + 4);
212 }
213 return String.copyValueOf(c);
214 }
215
216
217
218
219
220
221
222
223 public int encodeShort(final short v, final byte[] message, final int pointer)
224 {
225 int p = pointer;
226 if (this.bigEndian)
227 {
228 message[p++] = (byte) (v >> 8);
229 message[p++] = (byte) (v);
230 }
231 else
232 {
233 message[p++] = (byte) (v);
234 message[p++] = (byte) (v >> 8);
235 }
236 return p;
237 }
238
239
240
241
242
243
244
245
246 public int encodeChar(final char v, final byte[] message, final int pointer)
247 {
248 return encodeShort((short) v, message, pointer);
249 }
250
251
252
253
254
255
256
257 public void encodeInt(final int v, final byte[] message, final int pointer)
258 {
259 int p = pointer;
260 if (this.bigEndian)
261 {
262 message[p++] = (byte) ((v >> 24) & 0xFF);
263 message[p++] = (byte) ((v >> 16) & 0xFF);
264 message[p++] = (byte) ((v >> 8) & 0xFF);
265 message[p++] = (byte) (v & 0xFF);
266 }
267 else
268 {
269 message[p++] = (byte) (v & 0xFF);
270 message[p++] = (byte) ((v >> 8) & 0xFF);
271 message[p++] = (byte) ((v >> 16) & 0xFF);
272 message[p++] = (byte) ((v >> 24) & 0xFF);
273 }
274 }
275
276
277
278
279
280
281
282
283 public int encodeLong(final long v, final byte[] message, final int pointer)
284 {
285 int p = pointer;
286 if (this.bigEndian)
287 {
288 message[p++] = (byte) ((v >> 56) & 0xFF);
289 message[p++] = (byte) ((v >> 48) & 0xFF);
290 message[p++] = (byte) ((v >> 40) & 0xFF);
291 message[p++] = (byte) ((v >> 32) & 0xFF);
292 message[p++] = (byte) ((v >> 24) & 0xFF);
293 message[p++] = (byte) ((v >> 16) & 0xFF);
294 message[p++] = (byte) ((v >> 8) & 0xFF);
295 message[p++] = (byte) (v & 0xFF);
296 }
297 else
298 {
299 message[p++] = (byte) (v & 0xFF);
300 message[p++] = (byte) ((v >> 8) & 0xFF);
301 message[p++] = (byte) ((v >> 16) & 0xFF);
302 message[p++] = (byte) ((v >> 24) & 0xFF);
303 message[p++] = (byte) ((v >> 32) & 0xFF);
304 message[p++] = (byte) ((v >> 40) & 0xFF);
305 message[p++] = (byte) ((v >> 48) & 0xFF);
306 message[p++] = (byte) ((v >> 56) & 0xFF);
307 }
308 return p;
309 }
310
311
312
313
314
315
316
317 public void encodeFloat(final float v, final byte[] message, final int pointer)
318 {
319 int vint = Float.floatToIntBits(v);
320 encodeInt(vint, message, pointer);
321 }
322
323
324
325
326
327
328
329
330 public int encodeDouble(final double v, final byte[] message, final int pointer)
331 {
332 long vlong = Double.doubleToLongBits(v);
333 return encodeLong(vlong, message, pointer);
334 }
335
336 @Override
337 public String toString()
338 {
339 return "EndianUtil [bigEndian=" + this.bigEndian + "]";
340 }
341
342 }