changing license to BSD, assigning Yahoo copyrights where appropriate
[lwes-java.git] / src / main / java / org / lwes / serializer / Deserializer.java
blob54ea062ece56852c7c0a27ed99344497b77f19df
1 /*======================================================================*
2 * Copyright (c) 2008, Yahoo! Inc. All rights reserved. *
3 * *
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;
27 /**
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);
39 /**
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
45 * @return a byte.
47 public static byte deserializeBYTE(DeserializerState myState, byte[] bytes) {
48 byte aByte = bytes[myState.currentIndex()];
49 myState.incr(1);
50 return aByte;
53 /**
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
59 * @return a boolean.
61 public static boolean deserializeBOOLEAN(DeserializerState myState,
62 byte[] bytes) {
63 byte aBooleanAsByte = Deserializer.deserializeBYTE(myState, bytes);
64 return aBooleanAsByte != (byte) 0x00;
67 /**
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
73 * @return a short.
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));
80 myState.incr(2);
81 return aShort;
84 /**
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));
99 myState.incr(2);
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
109 * @return an int.
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);
117 myState.incr(4);
118 return anInt;
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) {
131 long anUnsignedInt =
132 ((long)
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)
139 myState.incr(4);
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
149 * @return a long.
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);
161 myState.incr(8);
162 return aLong;
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());
176 myState.incr(8);
177 return aLong;
180 public static String deserializeUINT64toHexString(DeserializerState myState,
181 byte[] bytes) {
182 String aString =
183 NumberCodec.byteArrayToHexString(bytes, myState.currentIndex(), 8);
184 myState.incr(8);
185 return aString;
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];
196 myState.incr(4);
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);
210 myState.incr(8);
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);
220 myState.incr(4);
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()];
238 myState.incr(4);
239 return inetaddr;
242 public static String deserializeIPADDRtoHexString(DeserializerState myState,
243 byte[] bytes) {
244 String aString =
245 NumberCodec.byteArrayToHexString(bytes, myState.currentIndex(), 4);
246 myState.incr(4);
247 return aString;
250 public static List deserializeStringArray(DeserializerState state,
251 byte[] bytes,
252 short encoding) {
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));
258 return rtn;
261 public static List deserializeInt16Array(DeserializerState state,
262 byte[] bytes) {
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));
268 return rtn;
271 public static List deserializeInt32Array(DeserializerState state,
272 byte[] bytes) {
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));
278 return rtn;
281 public static List deserializeInt64Array(DeserializerState state,
282 byte[] bytes) {
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));
288 return rtn;
291 public static List deserializeUInt16Array(DeserializerState state,
292 byte[] bytes) {
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));
298 return rtn;
301 public static List deserializeUInt32Array(DeserializerState state,
302 byte[] bytes) {
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));
308 return rtn;
311 public static List deserializeUInt64Array(DeserializerState state,
312 byte[] bytes) {
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));
318 return rtn;
321 public static List deserializeBooleanArray(DeserializerState state,
322 byte[] bytes) {
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));
328 return rtn;
331 public static List deserializeByteArray(DeserializerState state,
332 byte[] bytes) {
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));
338 return rtn;
341 public static List deserializeDoubleArray(DeserializerState state,
342 byte[] bytes) {
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));
348 return rtn;
351 public static List deserializeFloatArray(DeserializerState state,
352 byte[] bytes) {
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));
358 return rtn;
361 public static List deserializeIPV4Array(DeserializerState state,
362 byte[] bytes) {
363 int length = deserializeUINT16(state, bytes);
364 List<InetAddress> rtn = new ArrayList<InetAddress>(length);
365 for (int i = 0; i < length; i++) {
366 try {
367 rtn.add(deserializeIPV4(state, bytes));
369 catch (UnknownHostException e) {
370 log.error(e.getMessage(), e);
373 return rtn;
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
382 * @return a String.
383 * @deprecated
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;
392 int len = -1;
393 try {
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]);
405 myState.incr(len);
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);
416 return aString;
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
426 * @return a String.
428 public static String deserializeEVENTWORD(DeserializerState myState,
429 byte[] bytes) {
430 return deserializeEVENTWORD(myState, bytes, Event.DEFAULT_ENCODING);
433 public static String deserializeEVENTWORD(DeserializerState myState,
434 byte[] bytes, short encoding) {
435 String aString = null;
436 int len = -1;
437 try {
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]);
449 myState.incr(len);
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);
460 return aString;
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
470 * @return a String.
472 public static String deserializeATTRIBUTEWORD(DeserializerState myState,
473 byte[] bytes) {
474 return deserializeEVENTWORD(myState, bytes, Event.DEFAULT_ENCODING);