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