com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.java

Source

/*
 * 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 java.util.ArrayList;

import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamReader;

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

    protected 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 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 void rememberDecodedObject(int index, Object o) {
        // index is 1-based
        seenArray.set(index - 1, o);
    }

    protected int reserveDecodedObjectIndex() {
        seenArray.add(null);
        // index is 1-based
        return seenArray.size();
    }
}