/*
* 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.
*/
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();
}
}
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();
}
}
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)).intValue();
in.readEnd();
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);
in.readEnd();
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 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));
}
}
}