Package com.rabbitmq.client.impl

Source Code of com.rabbitmq.client.impl.ValueReader

//  The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (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.mozilla.org/MPL/
//
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
//  the License for the specific language governing rights and
//  limitations under the License.
//
//  The Original Code is RabbitMQ.
//
//  The Initial Developer of the Original Code is VMware, Inc.
//  Copyright (c) 2007-2012 VMware, Inc.  All rights reserved.
//


package com.rabbitmq.client.impl;

import java.io.DataInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

import com.rabbitmq.client.LongString;
import com.rabbitmq.client.MalformedFrameException;

/**
* Helper class to read AMQP wire-protocol encoded values.
*/
public class ValueReader
{
    private static final long INT_MASK = 0xffffffff;

    /**
     * Protected API - Cast an int to a long without extending the
     * sign bit of the int out into the high half of the long.
     */
    private static final long unsignedExtend(int value)
    {
        long extended = value;
        return extended & INT_MASK;
    }

    /** The stream we are reading from. */
    private final DataInputStream in;

    /**
     * Construct a MethodArgumentReader streaming over the given DataInputStream.
     */
    public ValueReader(DataInputStream in)
    {
        this.in = in;
    }

    /** Convenience method - reads a short string from a DataInput
     * Stream.
     */
    private static final String readShortstr(DataInputStream in)
        throws IOException
    {
        byte [] b = new byte[in.readUnsignedByte()];
        in.readFully(b);
        return new String(b, "utf-8");
    }

    /** Public API - reads a short string. */
    public final String readShortstr()
        throws IOException
    {
        return readShortstr(this.in);
    }

    /** Convenience method - reads a 32-bit-length-prefix
     * byte vector from a DataInputStream.
     */
    private static final byte[] readBytes(final DataInputStream in)
        throws IOException
    {
        final long contentLength = unsignedExtend(in.readInt());
        if(contentLength < Integer.MAX_VALUE) {
            final byte [] buffer = new byte[(int)contentLength];
            in.readFully(buffer);
            return buffer;
        } else {
            throw new UnsupportedOperationException
                ("Very long byte vectors and strings not currently supported");
        }
    }

    /** Convenience method - reads a long string argument
     * from a DataInputStream.
     */
    private static final LongString readLongstr(final DataInputStream in)
        throws IOException
    {
        return LongStringHelper.asLongString(readBytes(in));
    }


    /** Public API - reads a long string. */
    public final LongString readLongstr()
        throws IOException
    {
        return readLongstr(this.in);
    }

    /** Public API - reads a short integer. */
    public final int readShort()
        throws IOException
    {
        return in.readUnsignedShort();
    }

    /** Public API - reads an integer. */
    public final int readLong()
        throws IOException
    {
        return in.readInt();
    }

    /** Public API - reads a long integer. */
    public final long readLonglong()
        throws IOException
    {
        return in.readLong();
    }

    /**
     * Reads a table argument from a given stream. Also
     * called by {@link ContentHeaderPropertyReader}.
     */
    private static final Map<String, Object> readTable(DataInputStream in)
        throws IOException
    {
        long tableLength = unsignedExtend(in.readInt());
        if (tableLength == 0) return Collections.emptyMap();
       
        Map<String, Object> table = new HashMap<String, Object>();
        DataInputStream tableIn = new DataInputStream
            (new TruncatedInputStream(in, tableLength));
        while(tableIn.available() > 0) {
            String name = readShortstr(tableIn);
            Object value = readFieldValue(tableIn);
            if(!table.containsKey(name))
                table.put(name, value);
        }
        return table;
    }

    private static final Object readFieldValue(DataInputStream in)
        throws IOException {
        Object value = null;
        switch(in.readUnsignedByte()) {
          case 'S':
              value = readLongstr(in);
              break;
          case 'I':
              value = in.readInt();
              break;
          case 'D':
              int scale = in.readUnsignedByte();
              byte [] unscaled = new byte[4];
              in.readFully(unscaled);
              value = new BigDecimal(new BigInteger(unscaled), scale);
              break;
          case 'T':
              value = readTimestamp(in);
              break;
          case 'F':
              value = readTable(in);
              break;
          case 'A':
              value = readArray(in);
              break;
          case 'b':
              value = in.readByte();
              break;
          case 'd':
              value = in.readDouble();
              break;
          case 'f':
              value = in.readFloat();
              break;
          case 'l':
              value = in.readLong();
              break;
          case 's':
              value = in.readShort();
              break;
          case 't':
              value = in.readBoolean();
              break;
          case 'x':
              value = readBytes(in);
              break;
          case 'V':
              value = null;
              break;
          default:
              throw new MalformedFrameException
                  ("Unrecognised type in table");
        }
        return value;
    }

    /** Read a field-array */
    private static final List<Object> readArray(DataInputStream in)
        throws IOException
    {
        long length = unsignedExtend(in.readInt());
        DataInputStream arrayIn = new DataInputStream
            (new TruncatedInputStream(in, length));
        List<Object> array = new ArrayList<Object>();
        while(arrayIn.available() > 0) {
            Object value = readFieldValue(arrayIn);
            array.add(value);
        }
        return array;
    }

    /** Public API - reads a table. */
    public final Map<String, Object> readTable()
        throws IOException
    {
        return readTable(this.in);
    }

    /** Public API - reads an octet. */
    public final int readOctet()
        throws IOException
    {
        return in.readUnsignedByte();
    }

    /** Convenience method - reads a timestamp argument from the DataInputStream. */
    private static final Date readTimestamp(DataInputStream in)
        throws IOException
    {
        return new Date(in.readLong()*1000);
    }


    /** Public API - reads an timestamp. */
    public final Date readTimestamp()
        throws IOException
    {
        return readTimestamp(this.in);
    }

}
TOP

Related Classes of com.rabbitmq.client.impl.ValueReader

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.