blob: 3766b5d106d564b46032a4699f4183c7f79ff87d [file] [log] [blame]
/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.user.client.rpc.impl;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;
import java.util.ArrayList;
/**
* Base class for the client and server serialization streams. This class
* handles the basic serialization and deserialization formatting for primitive
* types since these are common between the client and the server.
*/
public abstract class AbstractSerializationStreamReader extends
AbstractSerializationStream implements SerializationStreamReader {
private static final double TWO_PWR_15_DBL = 0x8000;
private static final double TWO_PWR_16_DBL = 0x10000;
private static final double TWO_PWR_22_DBL = 0x400000;
private static final double TWO_PWR_31_DBL = TWO_PWR_16_DBL * TWO_PWR_15_DBL;
private static final double TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
private static final double TWO_PWR_44_DBL = TWO_PWR_22_DBL * TWO_PWR_22_DBL;
private static final double TWO_PWR_63_DBL = TWO_PWR_32_DBL * TWO_PWR_31_DBL;
/**
* Return a long from a pair of doubles { low, high } such that the
* actual value is equal to high + low.
*/
public static long fromDoubles(double lowDouble, double highDouble) {
long high = fromDouble(highDouble);
long low = fromDouble(lowDouble);
return high + low;
}
private static long fromDouble(double value) {
if (Double.isNaN(value)) {
return 0L;
}
if (value < -TWO_PWR_63_DBL) {
return Long.MIN_VALUE;
}
if (value >= TWO_PWR_63_DBL) {
return Long.MAX_VALUE;
}
boolean negative = false;
if (value < 0) {
negative = true;
value = -value;
}
int a2 = 0;
if (value >= TWO_PWR_44_DBL) {
a2 = (int) (value / TWO_PWR_44_DBL);
value -= a2 * TWO_PWR_44_DBL;
}
int a1 = 0;
if (value >= TWO_PWR_22_DBL) {
a1 = (int) (value / TWO_PWR_22_DBL);
value -= a1 * TWO_PWR_22_DBL;
}
int a0 = (int) value;
long result = ((long) a2 << 44) | ((long) a1 << 22) | a0;
if (negative) {
result = -result;
}
return result;
}
private ArrayList<Object> seenArray = new ArrayList<Object>();
/**
* Prepare to read the stream.
*
* @param encoded unused true if the stream is encoded
*/
public void prepareToRead(String encoded) throws SerializationException {
seenArray.clear();
// Read the stream version number
//
setVersion(readInt());
// Read the flags from the stream
//
setFlags(readInt());
}
public final Object readObject() throws SerializationException {
int token = readInt();
if (token < 0) {
// Negative means a previous object
// Transform negative 1-based to 0-based.
return seenArray.get(-(token + 1));
}
// Positive means a new object
String typeSignature = getString(token);
if (typeSignature == null) {
// a null string means a null instance
return null;
}
return deserialize(typeSignature);
}
/**
* Deserialize an object with the given type signature.
*
* @param typeSignature the type signature to deserialize
* @return the deserialized object
* @throws SerializationException
*/
protected abstract Object deserialize(String typeSignature)
throws SerializationException;
/**
* Gets a string out of the string table.
*
* @param index the index of the string to get
* @return the string
*/
protected abstract String getString(int index);
protected final void rememberDecodedObject(int index, Object o) {
// index is 1-based
seenArray.set(index - 1, o);
}
protected final int reserveDecodedObjectIndex() {
seenArray.add(null);
// index is 1-based
return seenArray.size();
}
}