com.rabbitmq.client.impl.ValueWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.rabbitmq.client.impl.ValueWriter.java

Source

//  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-2011 VMware, Inc.  All rights reserved.
//

package com.rabbitmq.client.impl;

import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.Map;
import java.util.List;

import org.apache.commons.io.IOUtils;

import com.rabbitmq.client.LongString;

/**
 * Helper class to generate AMQP wire-protocol encoded values.
 */
public class ValueWriter {
    private final DataOutputStream out;

    public ValueWriter(DataOutputStream out) {
        this.out = out;
    }

    /** Public API - encodes a short string. */
    public final void writeShortstr(String str) throws IOException {
        byte[] bytes = str.getBytes("utf-8");
        int length = bytes.length;
        if (length > 255) {
            throw new IllegalArgumentException(
                    "Short string too long; utf-8 encoded length = " + length + ", max = 255.");
        }
        out.writeByte(bytes.length);
        out.write(bytes);
    }

    /** Public API - encodes a long string from a LongString. */
    public final void writeLongstr(LongString str) throws IOException {
        writeLong((int) str.length());
        IOUtils.copy(str.getStream(), out);
    }

    /** Public API - encodes a long string from a String. */
    public final void writeLongstr(String str) throws IOException {
        byte[] bytes = str.getBytes("utf-8");
        writeLong(bytes.length);
        out.write(bytes);
    }

    /** Public API - encodes a short integer. */
    public final void writeShort(int s) throws IOException {
        out.writeShort(s);
    }

    /** Public API - encodes an integer. */
    public final void writeLong(int l) throws IOException {
        // java's arithmetic on this type is signed, however it's
        // reasonable to use ints to represent the unsigned long
        // type - for values < Integer.MAX_VALUE everything works
        // as expected
        out.writeInt(l);
    }

    /** Public API - encodes a long integer. */
    public final void writeLonglong(long ll) throws IOException {
        out.writeLong(ll);
    }

    /** Public API - encodes a table. */
    public final void writeTable(Map<String, Object> table) throws IOException {
        if (table == null) {
            // Convenience.
            out.writeInt(0);
        } else {
            out.writeInt((int) Frame.tableSize(table));
            for (Map.Entry<String, Object> entry : table.entrySet()) {
                writeShortstr(entry.getKey());
                Object value = entry.getValue();
                writeFieldValue(value);
            }
        }
    }

    public final void writeFieldValue(Object value) throws IOException {
        if (value instanceof String) {
            writeOctet('S');
            writeLongstr((String) value);
        } else if (value instanceof LongString) {
            writeOctet('S');
            writeLongstr((LongString) value);
        } else if (value instanceof Integer) {
            writeOctet('I');
            writeLong((Integer) value);
        } else if (value instanceof BigDecimal) {
            writeOctet('D');
            BigDecimal decimal = (BigDecimal) value;
            writeOctet(decimal.scale());
            BigInteger unscaled = decimal.unscaledValue();
            if (unscaled.bitLength() > 32) /*Integer.SIZE in Java 1.5*/
                throw new IllegalArgumentException("BigDecimal too large to be encoded");
            writeLong(decimal.unscaledValue().intValue());
        } else if (value instanceof Date) {
            writeOctet('T');
            writeTimestamp((Date) value);
        } else if (value instanceof Map) {
            writeOctet('F');
            // Ignore the warnings here.  We hate erasure
            // (not even a little respect)
            // (We even have trouble recognising it.)
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) value;
            writeTable(map);
        } else if (value instanceof Byte) {
            writeOctet('b');
            out.writeByte((Byte) value);
        } else if (value instanceof Double) {
            writeOctet('d');
            out.writeDouble((Double) value);
        } else if (value instanceof Float) {
            writeOctet('f');
            out.writeFloat((Float) value);
        } else if (value instanceof Long) {
            writeOctet('l');
            out.writeLong((Long) value);
        } else if (value instanceof Short) {
            writeOctet('s');
            out.writeShort((Short) value);
        } else if (value instanceof Boolean) {
            writeOctet('t');
            out.writeBoolean((Boolean) value);
        } else if (value instanceof byte[]) {
            writeOctet('x');
            writeLong(((byte[]) value).length);
            out.write((byte[]) value);
        } else if (value == null) {
            writeOctet('V');
        } else if (value instanceof List) {
            writeOctet('A');
            writeArray((List<?>) value);
        } else {
            throw new IllegalArgumentException("Invalid value type: " + value.getClass().getName());
        }
    }

    public final void writeArray(List<?> value) throws IOException {
        if (value == null) {
            out.write(0);
        } else {
            out.writeInt((int) Frame.arraySize(value));
            for (Object item : value) {
                writeFieldValue(item);
            }
        }
    }

    /** Public API - encodes an octet from an int. */
    public final void writeOctet(int octet) throws IOException {
        out.writeByte(octet);
    }

    /** Public API - encodes an octet from a byte. */
    public final void writeOctet(byte octet) throws IOException {
        out.writeByte(octet);
    }

    /** Public API - encodes a timestamp. */
    public final void writeTimestamp(Date timestamp) throws IOException {
        // AMQP uses POSIX time_t which is in seconds since the epoch began
        writeLonglong(timestamp.getTime() / 1000);
    }

    /**
     * Public API - call this to ensure all accumulated
     * values are correctly written to the output stream.
     */
    public void flush() throws IOException {
        out.flush();
    }
}