Package org.infinispan.schematic.internal.document

Source Code of org.infinispan.schematic.internal.document.BsonReader$Reader

/*
* ModeShape (http://www.modeshape.org)
*
* 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 org.infinispan.schematic.internal.document;

import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import org.infinispan.schematic.document.Array;
import org.infinispan.schematic.document.Bson;
import org.infinispan.schematic.document.Bson.BinaryType;
import org.infinispan.schematic.document.Document;
import org.infinispan.schematic.document.MaxKey;
import org.infinispan.schematic.document.MinKey;
import org.infinispan.schematic.document.ThreadSafe;
import org.infinispan.schematic.internal.io.BsonDataInput;

/**
* A component that reads BSON representations and constructs the in-memory {@link Document} representation.
*
* @author Randall Hauch <rhauch@redhat.com> (C) 2011 Red Hat Inc.
*/
@ThreadSafe
public class BsonReader {

    protected static final DocumentValueFactory VALUE_FACTORY = new DefaultDocumentValueFactory();

    /**
     * Read the binary BSON representation from supplied input stream and construct the {@link Document} representation.
     *
     * @param stream the input stream; may not be null
     * @return the in-memory {@link Document} representation
     * @throws IOException if there was a problem reading from the stream
     */
    public Document read( InputStream stream ) throws IOException {
        // Create an object so that this reader is thread safe ...
        DocumentValueFactory valueFactory = VALUE_FACTORY;
        Reader reader = new Reader(new BsonDataInput(new DataInputStream(stream)), valueFactory);
        reader.startDocument();
        return reader.endDocument();
    }

    /**
     * Read the binary BSON representation from supplied input stream and construct the {@link Document} representation.
     *
     * @param input the input stream; may not be null
     * @return the in-memory {@link Document} representation
     * @throws IOException if there was a problem reading from the stream
     */
    public Document read( DataInput input ) throws IOException {
        // Create an object so that this reader is thread safe ...
        DocumentValueFactory valueFactory = VALUE_FACTORY;
        Reader reader = new Reader(new BsonDataInput(input), valueFactory);
        reader.startDocument();
        return reader.endDocument();
    }

    /**
     * Read the binary BSON representation from supplied input stream and construct the {@link Array} representation.
     *
     * @param stream the input stream; may not be null
     * @return the in-memory {@link Document} representation
     * @throws IOException if there was a problem reading from the stream
     */
    public Array readArray( InputStream stream ) throws IOException {
        // Create an object so that this reader is thread safe ...
        DocumentValueFactory valueFactory = VALUE_FACTORY;
        Reader reader = new Reader(new BsonDataInput(new DataInputStream(stream)), valueFactory);
        reader.startArray();
        return (Array)reader.endDocument();
    }

    /**
     * Read the binary BSON representation from supplied input stream and construct the {@link Document} representation.
     *
     * @param input the input stream; may not be null
     * @return the in-memory {@link Document} representation
     * @throws IOException if there was a problem reading from the stream
     */
    public Array readArray( DataInput input ) throws IOException {
        // Create an object so that this reader is thread safe ...
        DocumentValueFactory valueFactory = VALUE_FACTORY;
        Reader reader = new Reader(new BsonDataInput(input), valueFactory);
        reader.startArray();
        return (Array)reader.endDocument();
    }

    protected static class Reader {
        private final BsonDataInput data;
        private MutableDocument object;
        private DocumentValueFactory values;

        // private final BsonEditor editor;

        protected Reader( BsonDataInput data,
                          DocumentValueFactory valueFactory ) {
            this.data = data;
            this.values = valueFactory;
        }

        protected void startDocument() throws IOException {
            object = readDocument(false);
        }

        protected void startArray() throws IOException {
            object = readDocument(true);
        }

        protected MutableDocument readDocument( boolean array ) throws IOException {
            // Read the size int32, but we don't care about the value 'cuz it's in bytes ...
            int length = data.readInt();
            int startingIndex = data.getTotalBytesRead();
            int endingIndex = startingIndex + length;
            MutableDocument doc = array ? new BasicArray() : new BasicDocument();
            // Read the elements ...
            while (data.getTotalBytesRead() < endingIndex) {
                byte type = data.readByte();
                if (type == Bson.END_OF_DOCUMENT) break;
                readElement(type, doc);
            }
            return doc;
        }

        protected void readElement( byte type,
                                    MutableDocument bson ) throws IOException {
            String name = readCString();
            Object value = null;
            switch (type) {
                case Bson.Type.ARRAY:
                    value = readDocument(true);
                    break;
                case Bson.Type.BINARY:
                    int length = data.readInt();
                    byte subtype = data.readByte();
                    if (subtype == BinaryType.UUID) {
                        long mostSig = data.readLong();
                        long leastSig = data.readLong();
                        value = new UUID(mostSig, leastSig);
                    } else {
                        byte[] bytes = new byte[length];
                        data.readFully(bytes);
                        value = values.createBinary(subtype, bytes);
                    }
                    break;
                case Bson.Type.BOOLEAN:
                    value = values.createBoolean(data.readBoolean());
                    break;
                case Bson.Type.DATETIME:
                    value = values.createDate(data.readLong());
                    break;
                case Bson.Type.DBPOINTER:
                    // Deprecated, so ignore ...
                    break;
                case Bson.Type.DOCUMENT:
                    value = readDocument(false);
                    break;
                case Bson.Type.DOUBLE:
                    value = values.createDouble(data.readDouble());
                    break;
                case Bson.Type.INT32:
                    value = values.createInt(data.readInt());
                    break;
                case Bson.Type.INT64:
                    value = values.createLong(data.readLong());
                    break;
                case Bson.Type.JAVASCRIPT:
                    value = values.createCode(readString());
                    break;
                case Bson.Type.JAVASCRIPT_WITH_SCOPE:
                    data.readInt(); // the length, but we don't use this
                    String code = readString();
                    Document scope = readDocument(false);
                    value = values.createCode(code, scope);
                    break;
                case Bson.Type.MAXKEY:
                    value = MaxKey.getInstance();
                    break;
                case Bson.Type.MINKEY:
                    value = MinKey.getInstance();
                    break;
                case Bson.Type.NULL:
                    value = values.createNull();
                    break;
                case Bson.Type.OBJECTID:
                    byte[] objectIdBytes = new byte[12];
                    data.readFully(objectIdBytes);
                    value = values.createObjectId(objectIdBytes);
                    break;
                case Bson.Type.REGEX:
                    value = values.createRegex(readCString(), readCString());
                    break;
                case Bson.Type.STRING:
                    value = readString();
                    break;
                case Bson.Type.SYMBOL:
                    value = readString();
                    break;
                case Bson.Type.TIMESTAMP:
                    int inc = data.readInt();
                    int time = data.readInt();
                    value = values.createTimestamp(time, inc);
                    break;
                case Bson.Type.UNDEFINED:
                    // ignore ...
                    break;
            }
            bson.put(name, value);
        }

        protected String readCString() throws IOException {
            return data.readUTF(-1); // this reads the zero-byte terminator
        }

        protected String readString() throws IOException {
            int length = data.readInt();
            String result = values.createString(data.readUTF(length - 1)); // don't read the zero-byte
            data.readByte(); // reads the zero-byte terminator
            return result;
        }

        protected Document endDocument() {
            return object;
        }

    }

}
TOP

Related Classes of org.infinispan.schematic.internal.document.BsonReader$Reader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.