| /* |
| * 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(); |
| } |
| } |