All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectfabric.UnknownObjectSerializer Maven / Gradle / Ivy

The newest version!
/**
 * This file is part of ObjectFabric (http://objectfabric.org).
 *
 * ObjectFabric is licensed under the Apache License, Version 2.0, the terms
 * of which may be found at http://www.apache.org/licenses/LICENSE-2.0.html.
 * 
 * Copyright ObjectFabric Inc.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

package org.objectfabric;

import org.objectfabric.Continuation.ByteBox;

/**
 * Reads and writes objects of unknown types.
 */
final class UnknownObjectSerializer {

    static final byte NULL = Immutable.COUNT;

    private static final byte REMOVAL = Immutable.COUNT + 1;

    private static final byte CUSTOM = Immutable.COUNT + 2;

    private static final byte MAX = CUSTOM;

    static {
        if (Debug.ENABLED)
            Debug.assertion(MAX < Writer.IMMUTABLE_MAX_COUNT);
    }

    private UnknownObjectSerializer() {
        throw new IllegalStateException();
    }

    // TODO: hash map of serializers based on class?
    @SuppressWarnings("fallthrough")
    static void write(ImmutableWriter writer, Object object) {
        if (Debug.ENABLED)
            Debug.assertion(!(object instanceof TObject.Version));

        if (object instanceof TObject) {
            ((Writer) writer).writeTObject((TObject) object);
            return;
        }

        boolean writtenCode = false;
        byte[] bytes = null;
        boolean resumed = false;

        if (writer.interrupted()) {
            writtenCode = writer.resumeBoolean();
            bytes = (byte[]) writer.resume();
            resumed = true;
        }

        if (!writtenCode) {
            if (!writer.canWriteByte()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(false);
                return;
            }
        }

        if (object == null) {
            writer.writeByte(NULL, Writer.DEBUG_TAG_CODE);
            return;
        }

        if (object == TKeyedEntry.REMOVAL) {
            writer.writeByte(REMOVAL, Writer.DEBUG_TAG_CODE);
            return;
        }

        if (object instanceof String) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.STRING_INDEX, Writer.DEBUG_TAG_CODE);

            writer.writeString((String) object);

            if (writer.interrupted()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
            }

            return;
        }

        if (object instanceof java.util.Date) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.DATE_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteDate()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeDate((java.util.Date) object);
            return;
        }

        if (object instanceof byte[]) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.BINARY_INDEX, Writer.DEBUG_TAG_CODE);

            writer.writeBinary((byte[]) object);

            if (writer.interrupted()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
            }

            return;
        }

        if (object instanceof Integer) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.INTEGER_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteInteger()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeInteger(((Integer) object).intValue());
            return;
        }

        if (object instanceof Long) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.LONG_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteLong()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeLong(((Long) object).longValue());
            return;
        }

        if (object instanceof Float) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.FLOAT_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteFloat()) {
                writer.interrupt(bytes);
                writer.interrupt(true);
                return;
            }

            writer.writeFloat(((Float) object).floatValue());
            return;
        }

        if (object instanceof Double) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.DOUBLE_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteDouble()) {
                writer.interrupt(bytes);
                writer.interrupt(true);
                return;
            }

            writer.writeDouble(((Double) object).doubleValue());
            return;
        }

        if (object instanceof java.math.BigInteger) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.BIG_INTEGER_INDEX, Writer.DEBUG_TAG_CODE);

            writer.writeBigInteger((java.math.BigInteger) object);

            if (writer.interrupted()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
            }

            return;
        }

        if (object instanceof java.math.BigDecimal) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.DECIMAL_INDEX, Writer.DEBUG_TAG_CODE);

            writer.writeDecimal((java.math.BigDecimal) object);

            if (writer.interrupted()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
            }

            return;
        }

        if (object instanceof Boolean) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.BOOLEAN_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteBoolean()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeBoolean(((Boolean) object).booleanValue());
            return;
        }

        if (object instanceof Byte) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.BYTE_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteByte()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeByte(((Byte) object).byteValue());
            return;
        }

        if (object instanceof Short) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.SHORT_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteShort()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeShort(((Short) object).shortValue());
            return;
        }

        if (object instanceof Character) {
            if (!writtenCode)
                writer.writeByte((byte) Immutable.CHARACTER_INDEX, Writer.DEBUG_TAG_CODE);

            if (!writer.canWriteCharacter()) {
                writer.interrupt(bytes);
                writer.interruptBoolean(true);
                return;
            }

            writer.writeCharacter(((Character) object).charValue());
            return;
        }

        Serializer serializer = Workspace.getSerializer();

        if (serializer == null)
            throw new RuntimeException(Strings.UNSUPPORTED_TYPE + object);

        if (!writtenCode)
            writer.writeByte(CUSTOM, Writer.DEBUG_TAG_CODE);

        if (!resumed)
            bytes = serializer.serialize(object);

        writer.writeBinary(bytes);

        if (writer.interrupted()) {
            writer.interrupt(bytes);
            writer.interruptBoolean(true);
        }
    }

    static Object read(ImmutableReader reader) {
        byte code;
        ByteBox resumed = null;

        if (reader.interrupted())
            resumed = (ByteBox) reader.resume();

        if (resumed != null)
            code = resumed.Value;
        else {
            if (!reader.canReadByte()) {
                reader.interrupt(null);
                return null;
            }

            code = reader.readByte(Writer.DEBUG_TAG_CODE);
        }

        Object value = read(reader, code);

        if (reader.interrupted()) {
            ByteBox box = new ByteBox();
            box.Value = code;
            reader.interrupt(box);
        }

        return value;
    }

    private static Object read(ImmutableReader reader, byte code) {
        if ((code & Writer.VALUE_IS_TOBJECT) != 0)
            return ((Reader) reader).readTObject(code);

        if (reader.interrupted())
            reader.resume();

        switch (code) {
            case Immutable.BOOLEAN_INDEX: {
                if (!reader.canReadBoolean()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readBoolean();
            }
            case Immutable.BOOLEAN_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.BYTE_INDEX: {
                if (!reader.canReadByte()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readByte();
            }
            case Immutable.BYTE_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.CHARACTER_INDEX: {
                if (!reader.canReadCharacter()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readCharacter();
            }
            case Immutable.CHARACTER_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.SHORT_INDEX: {
                if (!reader.canReadShort()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readShort();
            }
            case Immutable.SHORT_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.INTEGER_INDEX: {
                if (!reader.canReadInteger()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readInteger();
            }
            case Immutable.INTEGER_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.LONG_INDEX: {
                if (!reader.canReadLong()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readLong();
            }
            case Immutable.LONG_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.FLOAT_INDEX: {
                if (!reader.canReadFloat()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readFloat();
            }
            case Immutable.FLOAT_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.DOUBLE_INDEX: {
                if (!reader.canReadDouble()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readDouble();
            }
            case Immutable.DOUBLE_BOXED_INDEX:
                throw new IllegalStateException();
            case Immutable.STRING_INDEX: {
                String value = reader.readString();

                if (reader.interrupted())
                    reader.interrupt(null);

                return value;
            }
            case Immutable.DATE_INDEX: {
                if (!reader.canReadDate()) {
                    reader.interrupt(null);
                    return null;
                }

                return reader.readDate();
            }
            case Immutable.BIG_INTEGER_INDEX: {
                java.math.BigInteger value = reader.readBigInteger();

                if (reader.interrupted())
                    reader.interrupt(null);

                return value; // BigInteger
            }
            case Immutable.DECIMAL_INDEX: {
                java.math.BigDecimal value = reader.readDecimal();

                if (reader.interrupted())
                    reader.interrupt(null);

                return value; // BigDecimal
            }
            case Immutable.BINARY_INDEX: {
                byte[] value = reader.readBinary();

                if (reader.interrupted())
                    reader.interrupt(null);

                return value;
            }
            case NULL:
                return null;
            case REMOVAL:
                return TKeyedEntry.REMOVAL;
            case CUSTOM: {
                byte[] value = reader.readBinary();

                if (reader.interrupted())
                    reader.interrupt(null);

                Serializer serializer = Workspace.getSerializer();

                if (serializer == null)
                    throw new RuntimeException(Strings.MISSING_CUSTOM_SERIALIZER);

                return serializer.deserialize(value);
            }
            default:
                throw new IllegalStateException();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy