/*
 * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
 *
 * The Apache Software License, Version 1.1
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Caucho Technology (http://www.caucho.com/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
 *    endorse or promote products derived from this software without prior
 *    written permission. For written permission, please contact
 *    info@caucho.com.
 *
 * 5. Products derived from this software may not be called "Resin"
 *    nor may "Resin" appear in their names without prior written
 *    permission of Caucho Technology.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author Scott Ferguson
 */

package com.caucho.hessian.io;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

Serializing an object for known object types.
/** * Serializing an object for known object types. */
public class BasicDeserializer extends AbstractDeserializer { public static final int NULL = BasicSerializer.NULL; public static final int BOOLEAN = BasicSerializer.BOOLEAN; public static final int BYTE = BasicSerializer.BYTE; public static final int SHORT = BasicSerializer.SHORT; public static final int INTEGER = BasicSerializer.INTEGER; public static final int LONG = BasicSerializer.LONG; public static final int FLOAT = BasicSerializer.FLOAT; public static final int DOUBLE = BasicSerializer.DOUBLE; public static final int CHARACTER = BasicSerializer.CHARACTER; public static final int CHARACTER_OBJECT = BasicSerializer.CHARACTER_OBJECT; public static final int STRING = BasicSerializer.STRING; public static final int DATE = BasicSerializer.DATE; public static final int NUMBER = BasicSerializer.NUMBER; public static final int OBJECT = BasicSerializer.OBJECT; public static final int BOOLEAN_ARRAY = BasicSerializer.BOOLEAN_ARRAY; public static final int BYTE_ARRAY = BasicSerializer.BYTE_ARRAY; public static final int SHORT_ARRAY = BasicSerializer.SHORT_ARRAY; public static final int INTEGER_ARRAY = BasicSerializer.INTEGER_ARRAY; public static final int LONG_ARRAY = BasicSerializer.LONG_ARRAY; public static final int FLOAT_ARRAY = BasicSerializer.FLOAT_ARRAY; public static final int DOUBLE_ARRAY = BasicSerializer.DOUBLE_ARRAY; public static final int CHARACTER_ARRAY = BasicSerializer.CHARACTER_ARRAY; public static final int STRING_ARRAY = BasicSerializer.STRING_ARRAY; public static final int OBJECT_ARRAY = BasicSerializer.OBJECT_ARRAY; private int _code; public BasicDeserializer(int code) { _code = code; } public Class getType() { switch (_code) { case NULL: return void.class; case BOOLEAN: return Boolean.class; case BYTE: return Byte.class; case SHORT: return Short.class; case INTEGER: return Integer.class; case LONG: return Long.class; case FLOAT: return Float.class; case DOUBLE: return Double.class; case CHARACTER: return Character.class; case CHARACTER_OBJECT: return Character.class; case STRING: return String.class; case DATE: return Date.class; case NUMBER: return Number.class; case OBJECT: return Object.class; case BOOLEAN_ARRAY: return boolean[].class; case BYTE_ARRAY: return byte[].class; case SHORT_ARRAY: return short[].class; case INTEGER_ARRAY: return int[].class; case LONG_ARRAY: return long[].class; case FLOAT_ARRAY: return float[].class; case DOUBLE_ARRAY: return double[].class; case CHARACTER_ARRAY: return char[].class; case STRING_ARRAY: return String[].class; case OBJECT_ARRAY: return Object[].class; default: throw new UnsupportedOperationException(); } } @Override public Object readObject(AbstractHessianInput in) throws IOException { switch (_code) { case NULL: // hessian/3490 in.readObject(); return null; case BOOLEAN: return Boolean.valueOf(in.readBoolean()); case BYTE: return Byte.valueOf((byte) in.readInt()); case SHORT: return Short.valueOf((short) in.readInt()); case INTEGER: return Integer.valueOf(in.readInt()); case LONG: return Long.valueOf(in.readLong()); case FLOAT: return Float.valueOf((float) in.readDouble()); case DOUBLE: return Double.valueOf(in.readDouble()); case STRING: return in.readString(); case OBJECT: return in.readObject(); case CHARACTER: { String s = in.readString(); if (s == null || s.equals("")) return Character.valueOf((char) 0); else return Character.valueOf(s.charAt(0)); } case CHARACTER_OBJECT: { String s = in.readString(); if (s == null || s.equals("")) return null; else return Character.valueOf(s.charAt(0)); } case DATE: return new Date(in.readUTCDate()); case NUMBER: return in.readObject(); case BYTE_ARRAY: return in.readBytes(); case CHARACTER_ARRAY: { String s = in.readString(); if (s == null) return null; else { int len = s.length(); char []chars = new char[len]; s.getChars(0, len, chars, 0); return chars; } } case BOOLEAN_ARRAY: case SHORT_ARRAY: case INTEGER_ARRAY: case LONG_ARRAY: case FLOAT_ARRAY: case DOUBLE_ARRAY: case STRING_ARRAY: { int code = in.readListStart(); switch (code) { case 'N': return null; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: int length = code - 0x10; in.readInt(); return readLengthList(in, length); default: String type = in.readType(); length = in.readLength(); return readList(in, length); } } default: throw new UnsupportedOperationException(); } } @Override public Object readList(AbstractHessianInput in, int length) throws IOException { switch (_code) { case BOOLEAN_ARRAY: { if (length >= 0) { boolean []data = new boolean[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readBoolean(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(Boolean.valueOf(in.readBoolean())); in.readEnd(); boolean []data = new boolean[list.size()]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = ((Boolean) list.get(i)).booleanValue(); return data; } } case SHORT_ARRAY: { if (length >= 0) { short []data = new short[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = (short) in.readInt(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(Short.valueOf((short) in.readInt())); in.readEnd(); short []data = new short[list.size()]; for (int i = 0; i < data.length; i++) data[i] = ((Short) list.get(i)).shortValue(); in.addRef(data); return data; } } case INTEGER_ARRAY: { if (length >= 0) { int []data = new int[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readInt(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(Integer.valueOf(in.readInt())); in.readEnd(); int []data = new int[list.size()]; for (int i = 0; i < data.length; i++) data[i] = ((Integer) list.get(i)).intValue(); in.addRef(data); return data; } } case LONG_ARRAY: { if (length >= 0) { long []data = new long[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readLong(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(Long.valueOf(in.readLong())); in.readEnd(); long []data = new long[list.size()]; for (int i = 0; i < data.length; i++) data[i] = ((Long) list.get(i)).longValue(); in.addRef(data); return data; } } case FLOAT_ARRAY: { if (length >= 0) { float []data = new float[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = (float) in.readDouble(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(new Float(in.readDouble())); in.readEnd(); float []data = new float[list.size()]; for (int i = 0; i < data.length; i++) data[i] = ((Float) list.get(i)).floatValue(); in.addRef(data); return data; } } case DOUBLE_ARRAY: { if (length >= 0) { double []data = new double[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readDouble(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(new Double(in.readDouble())); in.readEnd(); double []data = new double[list.size()]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = ((Double) list.get(i)).doubleValue(); return data; } } case STRING_ARRAY: { if (length >= 0) { String []data = new String[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readString(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); while (! in.isEnd()) list.add(in.readString()); in.readEnd(); String []data = new String[list.size()]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = (String) list.get(i); return data; } } case OBJECT_ARRAY: { if (length >= 0) { Object []data = new Object[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readObject(); in.readEnd(); return data; } else { ArrayList list = new ArrayList(); in.addRef(list); // XXX: potential issues here while (! in.isEnd()) list.add(in.readObject()); in.readEnd(); Object []data = new Object[list.size()]; for (int i = 0; i < data.length; i++) data[i] = (Object) list.get(i); return data; } } default: throw new UnsupportedOperationException(String.valueOf(this)); } } public Object readLengthList(AbstractHessianInput in, int length) throws IOException { switch (_code) { case BOOLEAN_ARRAY: { boolean []data = new boolean[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readBoolean(); return data; } case SHORT_ARRAY: { short []data = new short[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = (short) in.readInt(); return data; } case INTEGER_ARRAY: { int []data = new int[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readInt(); return data; } case LONG_ARRAY: { long []data = new long[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readLong(); return data; } case FLOAT_ARRAY: { float []data = new float[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = (float) in.readDouble(); return data; } case DOUBLE_ARRAY: { double []data = new double[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readDouble(); return data; } case STRING_ARRAY: { String []data = new String[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readString(); return data; } case OBJECT_ARRAY: { Object []data = new Object[length]; in.addRef(data); for (int i = 0; i < data.length; i++) data[i] = in.readObject(); return data; } default: throw new UnsupportedOperationException(String.valueOf(this)); } } public String toString() { return getClass().getSimpleName() + "[" + _code + "]"; } }