diff options
Diffstat (limited to 'qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java')
-rw-r--r-- | qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java | 215 |
1 files changed, 41 insertions, 174 deletions
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java index 22205d49f8..721c821bab 100644 --- a/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java +++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java @@ -20,12 +20,16 @@ */ package org.apache.qpid.framing; -import org.apache.mina.common.ByteBuffer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.qpid.AMQPInvalidClassException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.math.BigDecimal; import java.util.Collections; import java.util.Enumeration; @@ -43,8 +47,8 @@ public class FieldTable private static final String STRICT_AMQP = "STRICT_AMQP"; private final boolean _strictAMQP = Boolean.valueOf(System.getProperty(STRICT_AMQP, "false")); - private ByteBuffer _encodedForm; - private LinkedHashMap<AMQShortString, AMQTypedValue> _properties; + private byte[] _encodedForm; + private LinkedHashMap<AMQShortString, AMQTypedValue> _properties = null; private long _encodedSize; private static final int INITIAL_HASHMAP_CAPACITY = 16; private static final int INITIAL_ENCODED_FORM_SIZE = 256; @@ -52,9 +56,6 @@ public class FieldTable public FieldTable() { super(); - // _encodedForm = ByteBuffer.allocate(INITIAL_ENCODED_FORM_SIZE); - // _encodedForm.setAutoExpand(true); - // _encodedForm.limit(0); } /** @@ -63,16 +64,12 @@ public class FieldTable * @param buffer the buffer from which to read data. The length byte must be read already * @param length the length of the field table. Must be > 0. */ - public FieldTable(ByteBuffer buffer, long length) + public FieldTable(DataInputStream buffer, long length) throws IOException { this(); - ByteBuffer encodedForm = buffer.slice(); - encodedForm.limit((int) length); - _encodedForm = ByteBuffer.allocate((int)length); - _encodedForm.put(encodedForm); - _encodedForm.flip(); + _encodedForm = new byte[(int) length]; + buffer.read(_encodedForm); _encodedSize = length; - buffer.skip((int) length); } public AMQTypedValue getProperty(AMQShortString string) @@ -108,13 +105,19 @@ public class FieldTable { try { - setFromBuffer(_encodedForm, _encodedSize); + setFromBuffer(); } catch (AMQFrameDecodingException e) { _logger.error("Error decoding FieldTable in deferred decoding mode ", e); throw new IllegalArgumentException(e); } + catch (IOException e) + { + _logger.error("Unexpected IO exception decoding field table"); + throw new IllegalArgumentException(e); + + } } private AMQTypedValue setProperty(AMQShortString key, AMQTypedValue val) @@ -766,7 +769,7 @@ public class FieldTable // ************************* Byte Buffer Processing - public void writeToBuffer(ByteBuffer buffer) + public void writeToBuffer(DataOutputStream buffer) throws IOException { final boolean trace = _logger.isDebugEnabled(); @@ -786,17 +789,21 @@ public class FieldTable public byte[] getDataAsBytes() { - final int encodedSize = (int) getEncodedSize(); - final ByteBuffer buffer = ByteBuffer.allocate(encodedSize); // FIXME XXX: Is cast a problem? - - putDataInBuffer(buffer); - - final byte[] result = new byte[encodedSize]; - buffer.flip(); - buffer.get(result); - buffer.release(); + if(_encodedForm == null) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + putDataInBuffer(new DataOutputStream(baos)); + return baos.toByteArray(); + } + catch (IOException e) + { + throw new IllegalArgumentException("IO Exception should never be thrown here"); + } - return result; + } + return _encodedForm.clone(); } public long getEncodedSize() @@ -926,15 +933,8 @@ public class FieldTable public Iterator<Map.Entry<AMQShortString, AMQTypedValue>> iterator() { - if(_encodedForm != null) - { - return new FieldTableIterator(_encodedForm.duplicate().rewind(),(int)_encodedSize); - } - else - { - initMapIfNecessary(); - return _properties.entrySet().iterator(); - } + initMapIfNecessary(); + return _properties.entrySet().iterator(); } public Object get(String key) @@ -1002,26 +1002,12 @@ public class FieldTable return _properties.keySet(); } - private void putDataInBuffer(ByteBuffer buffer) + private void putDataInBuffer(DataOutputStream buffer) throws IOException { if (_encodedForm != null) { - if(buffer.isDirect() || buffer.isReadOnly()) - { - ByteBuffer encodedForm = _encodedForm.duplicate(); - - if (encodedForm.position() != 0) - { - encodedForm.flip(); - } - - buffer.put(encodedForm); - } - else - { - buffer.put(_encodedForm.array(),_encodedForm.arrayOffset(),(int)_encodedSize); - } + buffer.write(_encodedForm); } else if (_properties != null) { @@ -1035,41 +1021,27 @@ public class FieldTable final Map.Entry<AMQShortString, AMQTypedValue> me = it.next(); try { - if (_logger.isDebugEnabled()) - { - _logger.debug("Writing Property:" + me.getKey() + " Type:" + me.getValue().getType() + " Value:" - + me.getValue().getValue()); - _logger.debug("Buffer Position:" + buffer.position() + " Remaining:" + buffer.remaining()); - } - // Write the actual parameter name EncodingUtils.writeShortStringBytes(buffer, me.getKey()); me.getValue().writeToBuffer(buffer); } catch (Exception e) { - if (_logger.isDebugEnabled()) - { - _logger.debug("Exception thrown:" + e); - _logger.debug("Writing Property:" + me.getKey() + " Type:" + me.getValue().getType() + " Value:" - + me.getValue().getValue()); - _logger.debug("Buffer Position:" + buffer.position() + " Remaining:" + buffer.remaining()); - } - throw new RuntimeException(e); } } } } - private void setFromBuffer(ByteBuffer buffer, long length) throws AMQFrameDecodingException + private void setFromBuffer() throws AMQFrameDecodingException, IOException { + final ByteArrayInputStream in = new ByteArrayInputStream(_encodedForm); + DataInputStream buffer = new DataInputStream(in); final boolean trace = _logger.isDebugEnabled(); - if (length > 0) + if (_encodedSize > 0) { - final int expectedRemaining = buffer.remaining() - (int) length; _properties = new LinkedHashMap<AMQShortString, AMQTypedValue>(INITIAL_HASHMAP_CAPACITY); @@ -1077,121 +1049,16 @@ public class FieldTable { final AMQShortString key = EncodingUtils.readAMQShortString(buffer); - - _logger.debug("FieldTable::PropFieldTable(buffer," + length + "): Read key '" + key); - AMQTypedValue value = AMQTypedValue.readFromBuffer(buffer); - - if (trace) - { - _logger.debug("FieldTable::PropFieldTable(buffer," + length + "): Read type '" + value.getType() - + "', key '" + key + "', value '" + value.getValue() + "'"); - } - _properties.put(key, value); } - while (buffer.remaining() > expectedRemaining); - - } - - _encodedSize = length; - - if (trace) - { - _logger.debug("FieldTable::FieldTable(buffer," + length + "): Done."); - } - } - - private static final class FieldTableEntry implements Map.Entry<AMQShortString, AMQTypedValue> - { - private final AMQTypedValue _value; - private final AMQShortString _key; - - public FieldTableEntry(final AMQShortString key, final AMQTypedValue value) - { - _key = key; - _value = value; - } - - public AMQShortString getKey() - { - return _key; - } - - public AMQTypedValue getValue() - { - return _value; - } - - public AMQTypedValue setValue(final AMQTypedValue value) - { - throw new UnsupportedOperationException(); - } - - public boolean equals(Object o) - { - if(o instanceof FieldTableEntry) - { - FieldTableEntry other = (FieldTableEntry) o; - return (_key == null ? other._key == null : _key.equals(other._key)) - && (_value == null ? other._value == null : _value.equals(other._value)); - } - else - { - return false; - } - } - - public int hashCode() - { - return (getKey()==null ? 0 : getKey().hashCode()) - ^ (getValue()==null ? 0 : getValue().hashCode()); - } - - } - - - private static final class FieldTableIterator implements Iterator<Map.Entry<AMQShortString, AMQTypedValue>> - { + while (in.available() > 0); - private final ByteBuffer _buffer; - private int _expectedRemaining; - - public FieldTableIterator(ByteBuffer buffer, int length) - { - _buffer = buffer; - _expectedRemaining = buffer.remaining() - length; - } - - public boolean hasNext() - { - return (_buffer.remaining() > _expectedRemaining); } - public Map.Entry<AMQShortString, AMQTypedValue> next() - { - if(hasNext()) - { - final AMQShortString key = EncodingUtils.readAMQShortString(_buffer); - AMQTypedValue value = AMQTypedValue.readFromBuffer(_buffer); - return new FieldTableEntry(key, value); - } - else - { - return null; - } - } - - public void remove() - { - throw new UnsupportedOperationException(); - } } - - - public int hashCode() { initMapIfNecessary(); |