org.apache.accumulo.core.util.ThriftMessageUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.accumulo.core.util.ThriftMessageUtil.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.accumulo.core.util;

import static java.util.Objects.requireNonNull;

import java.io.IOException;
import java.nio.ByteBuffer;

import org.apache.thrift.TBase;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.AutoExpandingBufferWriteTransport;
import org.apache.thrift.transport.TMemoryInputTransport;

/**
 * Serializes and deserializes Thrift messages to and from byte arrays. This class is not thread-safe, external synchronization is necessary if it is used
 * concurrently.
 */
public class ThriftMessageUtil {

    private final AutoExpandingBufferWriteTransport transport;
    private final TProtocol protocol;

    public ThriftMessageUtil() {
        this(64, 1.5);
    }

    public ThriftMessageUtil(int initialCapacity, double growthCoefficient) {
        // TODO does this make sense? better to push this down to the serialize method (accept the transport as an argument)?
        this.transport = new AutoExpandingBufferWriteTransport(initialCapacity, growthCoefficient);
        this.protocol = new TCompactProtocol(transport);
    }

    /**
     * Convert the {@code msg} to a byte array representation
     *
     * @param msg
     *          The message to serialize
     * @return The serialized message
     * @throws IOException
     *           When serialization fails
     */
    public ByteBuffer serialize(TBase<?, ?> msg) throws IOException {
        requireNonNull(msg);
        transport.reset();
        try {
            msg.write(protocol);
            // We should flush(), but we know its a noop
        } catch (TException e) {
            throw new IOException(e);
        }
        return ByteBuffer.wrap(transport.getBuf().array(), 0, transport.getPos());
    }

    /**
     * Assumes the entire contents of the byte array compose the serialized {@code instance}
     *
     * @see #deserialize(byte[], int, int, TBase)
     */
    public <T extends TBase<?, ?>> T deserialize(byte[] serialized, T instance) throws IOException {
        return deserialize(serialized, 0, serialized.length, instance);
    }

    /**
     * Deserializes a message into the provided {@code instance} from {@code serialized}
     *
     * @param serialized
     *          The serialized representation of the object
     * @param instance
     *          An instance of the object to reconstitute
     * @return The reconstituted instance provided
     * @throws IOException
     *           When deserialization fails
     */
    public <T extends TBase<?, ?>> T deserialize(byte[] serialized, int offset, int length, T instance)
            throws IOException {
        requireNonNull(instance);
        TCompactProtocol proto = new TCompactProtocol(new TMemoryInputTransport(serialized, offset, length));
        try {
            instance.read(proto);
        } catch (TException e) {
            throw new IOException(e);
        }
        return instance;
    }
}