1 /*======================================================================*
2 * Copyright (c) 2008, Yahoo! Inc. All rights reserved. *
4 * Licensed under the New BSD License (the "License"); you may not use *
5 * this file except in compliance with the License. Unless required *
6 * by applicable law or agreed to in writing, software distributed *
7 * under the License is distributed on an "AS IS" BASIS, WITHOUT *
8 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
9 * See the License for the specific language governing permissions and *
10 * limitations under the License. See accompanying LICENSE file. *
11 *======================================================================*/
13 package org
.lwes
.serializer
;
15 import org
.apache
.commons
.logging
.Log
;
16 import org
.apache
.commons
.logging
.LogFactory
;
17 import org
.lwes
.Event
;
18 import org
.lwes
.util
.EncodedString
;
19 import org
.lwes
.util
.NumberCodec
;
21 import java
.net
.Inet4Address
;
22 import java
.net
.InetAddress
;
23 import java
.net
.UnknownHostException
;
24 import java
.util
.ArrayList
;
25 import java
.util
.List
;
28 * This encapuslates the information needed to deserialize the base types
29 * of the event system.
31 * @author Anthony Molinaro
32 * @author Michael P. Lum
33 * @author Frank Maritato
35 public class Deserializer
{
37 private static transient Log log
= LogFactory
.getLog(Deserializer
.class);
40 * Deserialize a byte out of the byte array <tt>bytes</tt>
42 * @param myState the DeserializeState object giving the current index
43 * in the byte array <tt>bytes</tt>
44 * @param bytes the bytes to deserialize
47 public static byte deserializeBYTE(DeserializerState myState
, byte[] bytes
) {
48 byte aByte
= bytes
[myState
.currentIndex()];
54 * Deserialize a boolean value out of the byte array <tt>bytes</tt>
56 * @param myState the DeserializeState object giving the current index
57 * in the byte array <tt>bytes</tt>
58 * @param bytes the bytes to deserialize
61 public static boolean deserializeBOOLEAN(DeserializerState myState
,
63 byte aBooleanAsByte
= Deserializer
.deserializeBYTE(myState
, bytes
);
64 return aBooleanAsByte
!= (byte) 0x00;
68 * Deserialize an int16 out of the byte array <tt>bytes</tt>
70 * @param myState the DeserializeState object giving the current index
71 * in the byte array <tt>bytes</tt>
72 * @param bytes the bytes to deserialize
75 public static short deserializeINT16(DeserializerState myState
, byte[] bytes
) {
76 /* deserialize in net order (i.e. Big Endian) */
77 int off
= myState
.currentIndex();
78 short aShort
= (short) (((bytes
[off
+ 1] & 0xFF) << 0) +
79 ((bytes
[off
+ 0]) << 8));
85 * Deserialize a uint16 out of the byte array <tt>bytes</tt>
87 * @param myState the DeserializeState object giving the current index
88 * in the byte array <tt>bytes</tt>
89 * @param bytes the bytes to deserialize
90 * @return an int containing the unsigned short.
92 public static int deserializeUINT16(DeserializerState myState
, byte[] bytes
) {
94 /* deserialize in net order (i.e. Big Endian) */
95 int anUnsignedShort
= (int)
96 ((((int) bytes
[myState
.currentIndex()] << 8) & 0x0000ff00)
97 | (((int) bytes
[myState
.currentIndex() + 1] << 0) & 0x000000ff));
100 return anUnsignedShort
;
104 * Deserialize an int32 out of the byte array <tt>bytes</tt>
106 * @param myState the DeserializeState object giving the current index
107 * in the byte array <tt>bytes</tt>
108 * @param bytes the bytes to deserialize
111 public static int deserializeINT32(DeserializerState myState
, byte[] bytes
) {
112 int off
= myState
.currentIndex();
113 int anInt
= ((bytes
[off
+ 3] & 0xFF) << 0) +
114 ((bytes
[off
+ 2] & 0xFF) << 8) +
115 ((bytes
[off
+ 1] & 0xFF) << 16) +
116 ((bytes
[off
+ 0]) << 24);
123 * Deserialize a uint32 out of the byte array <tt>bytes</tt>
125 * @param myState the DeserializeState object giving the current index
126 * in the byte array <tt>bytes</tt>
127 * @param bytes the bytes to deserialize
128 * @return a long because java doesn't have unsigned types.
130 public static long deserializeUINT32(DeserializerState myState
, byte[] bytes
) {
133 ((((long) bytes
[myState
.currentIndex()] << 24) & 0x00000000ff000000L
)
134 | (((long) bytes
[myState
.currentIndex() + 1] << 16) & 0x0000000000ff0000L
)
135 | (((long) bytes
[myState
.currentIndex() + 2] << 8) & 0x000000000000ff00L
)
136 | (((long) bytes
[myState
.currentIndex() + 3] << 0) & 0x00000000000000ffL
)
140 return anUnsignedInt
;
144 * Deserialize a int64 out of the byte array <tt>bytes</tt>
146 * @param myState the DeserializeState object giving the current index
147 * in the byte array <tt>bytes</tt>
148 * @param bytes the bytes to deserialize
151 public static long deserializeINT64(DeserializerState myState
, byte[] bytes
) {
152 int off
= myState
.currentIndex();
153 long aLong
= ((bytes
[off
+ 7] & 0xFFL
) << 0) +
154 ((bytes
[off
+ 6] & 0xFFL
) << 8) +
155 ((bytes
[off
+ 5] & 0xFFL
) << 16) +
156 ((bytes
[off
+ 4] & 0xFFL
) << 24) +
157 ((bytes
[off
+ 3] & 0xFFL
) << 32) +
158 ((bytes
[off
+ 2] & 0xFFL
) << 40) +
159 ((bytes
[off
+ 1] & 0xFFL
) << 48) +
160 (((long) bytes
[off
+ 0]) << 56);
166 * Deserialize a uint64 out of the byte array <tt>bytes</tt>
168 * @param myState the DeserializeState object giving the current index
169 * in the byte array <tt>bytes</tt>
170 * @param bytes the bytes to deserialize
171 * @return a long (because java doesn't have unsigned types do not expect
172 * to do any math on this).
174 public static long deserializeUINT64(DeserializerState myState
, byte[] bytes
) {
175 long aLong
= NumberCodec
.decodeLongUnchecked(bytes
, myState
.currentIndex());
180 public static String
deserializeUINT64toHexString(DeserializerState myState
,
183 NumberCodec
.byteArrayToHexString(bytes
, myState
.currentIndex(), 8);
188 public static InetAddress
deserializeIPV4(DeserializerState myState
, byte[] bytes
)
189 throws UnknownHostException
{
190 int offset
= myState
.currentIndex();
191 byte[] b
= new byte[4];
192 b
[0] = bytes
[offset
];
193 b
[1] = bytes
[offset
+ 1];
194 b
[2] = bytes
[offset
+ 2];
195 b
[3] = bytes
[offset
+ 3];
197 return Inet4Address
.getByAddress(b
);
200 public static Double
deserializeDOUBLE(DeserializerState myState
, byte[] bytes
) {
201 int off
= myState
.currentIndex();
202 long j
= ((bytes
[off
+ 7] & 0xFFL
) << 0) +
203 ((bytes
[off
+ 6] & 0xFFL
) << 8) +
204 ((bytes
[off
+ 5] & 0xFFL
) << 16) +
205 ((bytes
[off
+ 4] & 0xFFL
) << 24) +
206 ((bytes
[off
+ 3] & 0xFFL
) << 32) +
207 ((bytes
[off
+ 2] & 0xFFL
) << 40) +
208 ((bytes
[off
+ 1] & 0xFFL
) << 48) +
209 (((long) bytes
[off
+ 0]) << 56);
211 return Double
.longBitsToDouble(j
);
214 public static Float
deserializeFLOAT(DeserializerState myState
, byte[] bytes
) {
215 int off
= myState
.currentIndex();
216 int i
= ((bytes
[off
+ 3] & 0xFF) << 0) +
217 ((bytes
[off
+ 2] & 0xFF) << 8) +
218 ((bytes
[off
+ 1] & 0xFF) << 16) +
219 ((bytes
[off
+ 0]) << 24);
221 return Float
.intBitsToFloat(i
);
225 * Deserialize an ip_addr out of the byte array <tt>bytes</tt>
227 * @param myState the DeserializeState object giving the current index
228 * in the byte array <tt>bytes</tt>
229 * @param bytes the bytes to deserialize
230 * @return a byte array with the ip_addr with byte order 1234.
232 public static byte[] deserializeIPADDR(DeserializerState myState
, byte[] bytes
) {
233 byte[] inetaddr
= new byte[4];
234 inetaddr
[0] = bytes
[myState
.currentIndex() + 3];
235 inetaddr
[1] = bytes
[myState
.currentIndex() + 2];
236 inetaddr
[2] = bytes
[myState
.currentIndex() + 1];
237 inetaddr
[3] = bytes
[myState
.currentIndex()];
242 public static String
deserializeIPADDRtoHexString(DeserializerState myState
,
245 NumberCodec
.byteArrayToHexString(bytes
, myState
.currentIndex(), 4);
250 public static List
deserializeStringArray(DeserializerState state
,
253 int length
= deserializeUINT16(state
, bytes
);
254 List
<String
> rtn
= new ArrayList
<String
>(length
);
255 for (int i
= 0; i
< length
; i
++) {
256 rtn
.add(deserializeSTRING(state
, bytes
, encoding
));
261 public static List
deserializeInt16Array(DeserializerState state
,
263 int length
= deserializeUINT16(state
, bytes
);
264 List
<Short
> rtn
= new ArrayList
<Short
>(length
);
265 for (int i
= 0; i
< length
; i
++) {
266 rtn
.add(deserializeINT16(state
, bytes
));
271 public static List
deserializeInt32Array(DeserializerState state
,
273 int length
= deserializeUINT16(state
, bytes
);
274 List
<Integer
> rtn
= new ArrayList
<Integer
>(length
);
275 for (int i
= 0; i
< length
; i
++) {
276 rtn
.add(deserializeINT32(state
, bytes
));
281 public static List
deserializeInt64Array(DeserializerState state
,
283 int length
= deserializeUINT16(state
, bytes
);
284 List
<Long
> rtn
= new ArrayList
<Long
>(length
);
285 for (int i
= 0; i
< length
; i
++) {
286 rtn
.add(deserializeINT64(state
, bytes
));
291 public static List
deserializeUInt16Array(DeserializerState state
,
293 int length
= deserializeUINT16(state
, bytes
);
294 List
<Integer
> rtn
= new ArrayList
<Integer
>(length
);
295 for (int i
= 0; i
< length
; i
++) {
296 rtn
.add(deserializeUINT16(state
, bytes
));
301 public static List
deserializeUInt32Array(DeserializerState state
,
303 int length
= deserializeUINT16(state
, bytes
);
304 List
<Long
> rtn
= new ArrayList
<Long
>(length
);
305 for (int i
= 0; i
< length
; i
++) {
306 rtn
.add(deserializeUINT32(state
, bytes
));
311 public static List
deserializeUInt64Array(DeserializerState state
,
313 int length
= deserializeUINT16(state
, bytes
);
314 List
<Long
> rtn
= new ArrayList
<Long
>(length
);
315 for (int i
= 0; i
< length
; i
++) {
316 rtn
.add(deserializeUINT64(state
, bytes
));
321 public static List
deserializeBooleanArray(DeserializerState state
,
323 int length
= deserializeUINT16(state
, bytes
);
324 List
<Boolean
> rtn
= new ArrayList
<Boolean
>(length
);
325 for (int i
= 0; i
< length
; i
++) {
326 rtn
.add(deserializeBOOLEAN(state
, bytes
));
331 public static List
deserializeByteArray(DeserializerState state
,
333 int length
= deserializeUINT16(state
, bytes
);
334 List
<Byte
> rtn
= new ArrayList
<Byte
>(length
);
335 for (int i
= 0; i
< length
; i
++) {
336 rtn
.add(deserializeBYTE(state
, bytes
));
341 public static List
deserializeDoubleArray(DeserializerState state
,
343 int length
= deserializeUINT16(state
, bytes
);
344 List
<Double
> rtn
= new ArrayList
<Double
>(length
);
345 for (int i
= 0; i
< length
; i
++) {
346 rtn
.add(deserializeDOUBLE(state
, bytes
));
351 public static List
deserializeFloatArray(DeserializerState state
,
353 int length
= deserializeUINT16(state
, bytes
);
354 List
<Float
> rtn
= new ArrayList
<Float
>(length
);
355 for (int i
= 0; i
< length
; i
++) {
356 rtn
.add(deserializeFLOAT(state
, bytes
));
361 public static List
deserializeIPV4Array(DeserializerState state
,
363 int length
= deserializeUINT16(state
, bytes
);
364 List
<InetAddress
> rtn
= new ArrayList
<InetAddress
>(length
);
365 for (int i
= 0; i
< length
; i
++) {
367 rtn
.add(deserializeIPV4(state
, bytes
));
369 catch (UnknownHostException e
) {
370 log
.error(e
.getMessage(), e
);
377 * Deserialize a String out of the byte array <tt>bytes</tt>
379 * @param myState the DeserializeState object giving the current index
380 * in the byte array <tt>bytes</tt>
381 * @param bytes the bytes to deserialize
385 public static String
deserializeSTRING(DeserializerState myState
, byte[] bytes
) {
386 return deserializeSTRING(myState
, bytes
, Event
.DEFAULT_ENCODING
);
389 public static String
deserializeSTRING(DeserializerState myState
,
390 byte[] bytes
, short encoding
) {
391 String aString
= null;
394 len
= deserializeUINT16(myState
, bytes
);
396 if (log
.isDebugEnabled()) {
397 log
.debug("Datagram Bytes: " +
398 NumberCodec
.byteArrayToHexString(bytes
, 0, bytes
.length
));
399 log
.debug("String Length: " + len
);
400 log
.debug("State: " + myState
);
403 aString
= EncodedString
.bytesToString(bytes
, myState
.currentIndex(), len
,
404 Event
.ENCODING_STRINGS
[encoding
]);
407 catch (ArrayIndexOutOfBoundsException aioobe
) {
408 if (log
.isInfoEnabled()) {
409 log
.info("Exception: " + aioobe
.toString());
410 log
.info("Datagram Bytes: " +
411 NumberCodec
.byteArrayToHexString(bytes
, 0, bytes
.length
));
412 log
.info("String Length: " + len
);
413 log
.info("State: " + myState
);
420 * Deserialize a String out of the byte array <tt>bytes</tt> which
421 * represents an Event name.
423 * @param myState the DeserializeState object giving the current index
424 * in the byte array <tt>bytes</tt>
425 * @param bytes the bytes to deserialize
428 public static String
deserializeEVENTWORD(DeserializerState myState
,
430 return deserializeEVENTWORD(myState
, bytes
, Event
.DEFAULT_ENCODING
);
433 public static String
deserializeEVENTWORD(DeserializerState myState
,
434 byte[] bytes
, short encoding
) {
435 String aString
= null;
438 len
= (int) deserializeBYTE(myState
, bytes
);
440 if (log
.isDebugEnabled()) {
441 log
.debug("Datagram Bytes: " +
442 NumberCodec
.byteArrayToHexString(bytes
, 0, bytes
.length
));
443 log
.debug("String Length: " + len
);
444 log
.debug("State: " + myState
);
447 aString
= EncodedString
.bytesToString(bytes
, myState
.currentIndex(), len
,
448 Event
.ENCODING_STRINGS
[encoding
]);
451 catch (ArrayIndexOutOfBoundsException aioobe
) {
452 if (log
.isInfoEnabled()) {
453 log
.info("Exception: " + aioobe
.toString());
454 log
.info("Datagram Bytes: " +
455 NumberCodec
.byteArrayToHexString(bytes
, 0, bytes
.length
));
456 log
.info("String Length: " + len
);
457 log
.info("State: " + myState
);
464 * Deserialize a String out of the byte array <tt>bytes</tt> which
465 * represents an Attribute name.
467 * @param myState the DeserializeState object giving the current index
468 * in the byte array <tt>bytes</tt>
469 * @param bytes the bytes to deserialize
472 public static String
deserializeATTRIBUTEWORD(DeserializerState myState
,
474 return deserializeEVENTWORD(myState
, bytes
, Event
.DEFAULT_ENCODING
);