From a019367dc582d61fa3739f385592c0baf9b972b8 Mon Sep 17 00:00:00 2001 From: Robert Greig Date: Mon, 26 Feb 2007 17:46:07 +0000 Subject: (Patch submitted by Tomas Restrepo) QPID-ByteBuffer.diff. Completely refactors the byte buffer implementation, doing away with a complex inheritance hierarchy. Fixes reading and writing of field table to permit interop with Java client. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@511923 13f79535-47bb-0310-9956-ffa450edef68 --- .../Qpid.Buffer.Tests/Properties/AssemblyInfo.cs | 35 + .../Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj | 59 + .../Qpid.Buffer.Tests/SimpleByteBufferTests.cs | 328 ++ .../Qpid.Buffer.Tests/SlicedByteBufferTests.cs | 133 + qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs | 460 --- qpid/dotnet/Qpid.Buffer/BufferDataException.cs | 54 - qpid/dotnet/Qpid.Buffer/ByteBuffer.cs | 3317 ++++++-------------- qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs | 5 +- qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs | 190 -- qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs | 367 --- qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs | 474 --- qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs | 25 +- qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj | 7 +- qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs | 120 + .../Qpid.Buffer/SimpleByteBufferAllocator.cs | 181 +- qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs | 86 + qpid/dotnet/Qpid.Client/Client/AmqChannel.cs | 6 +- .../Client/Message/AMQMessageFactory.cs | 10 +- .../Client/Message/AbstractQmsMessage.cs | 37 +- .../Qpid.Client/Client/Message/QpidBytesMessage.cs | 78 +- .../Qpid.Client/Client/Message/QpidHeaders.cs | 547 ++-- .../Qpid.Client/Client/Message/QpidTextMessage.cs | 10 +- .../Socket/Blocking/BlockingSocketProcessor.cs | 9 +- .../dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs | 22 +- .../Demux/DemuxingProtocolCodecFactory.cs | 13 +- .../Qpid.Common.Tests/Qpid.Common.Tests.csproj | 1 + .../Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs | 66 +- .../Qpid/Framing/TestEncodingUtils.cs | 60 + .../Qpid.Common/Framing/AMQDataBlockDecoder.cs | 22 +- .../Qpid.Common/Framing/AMQDataBlockEncoder.cs | 4 +- qpid/dotnet/Qpid.Common/Framing/AMQFrame.cs | 8 +- qpid/dotnet/Qpid.Common/Framing/AMQMethodBody.cs | 4 +- .../Qpid.Common/Framing/AMQMethodBodyFactory.cs | 2 +- qpid/dotnet/Qpid.Common/Framing/AMQType.cs | 6 +- qpid/dotnet/Qpid.Common/Framing/AMQTypedValue.cs | 2 +- .../Framing/BasicContentHeaderProperties.cs | 18 +- qpid/dotnet/Qpid.Common/Framing/ContentBody.cs | 4 +- .../Qpid.Common/Framing/ContentHeaderBody.cs | 16 +- qpid/dotnet/Qpid.Common/Framing/EncodingUtils.cs | 99 +- qpid/dotnet/Qpid.Common/Framing/FieldTable.cs | 29 +- qpid/dotnet/Qpid.Common/Framing/HeartbeatBody.cs | 2 +- .../Qpid.Common/Framing/ProtocolInitiation.cs | 28 +- qpid/dotnet/Qpid.Common/Qpid.Common.csproj | 1 + qpid/dotnet/Qpid.Common/stylesheets/utils.xsl | 18 +- qpid/dotnet/Qpid.Messaging/IHeaders.cs | 3 + qpid/dotnet/Qpid.NET.sln | 6 + 46 files changed, 2295 insertions(+), 4677 deletions(-) create mode 100644 qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs create mode 100644 qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj create mode 100644 qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs create mode 100644 qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs delete mode 100644 qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs delete mode 100644 qpid/dotnet/Qpid.Buffer/BufferDataException.cs delete mode 100644 qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs delete mode 100644 qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs delete mode 100644 qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs create mode 100644 qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs create mode 100644 qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs create mode 100644 qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs diff --git a/qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..d97f8278b5 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Qpid.Buffer.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Qpid.Buffer.Tests")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9d967d0b-9454-4f00-8f53-fa86fd62b696")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj b/qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj new file mode 100644 index 0000000000..ac9e2f5229 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj @@ -0,0 +1,59 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {74640962-99D0-4D06-B57A-9CD66517CF52} + Library + Properties + Qpid.Buffer.Tests + Qpid.Buffer.Tests + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\Qpid.Client.Tests\lib\nunit\nunit.framework.dll + + + + + + + + + + + + + {44384DF2-B0A4-4580-BDBC-EE4BAA87D995} + Qpid.Buffer + + + + + diff --git a/qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs b/qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs new file mode 100644 index 0000000000..290e908a0d --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs @@ -0,0 +1,328 @@ +/* + * + * 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. + * + */ + +using NUnit.Framework; +using Qpid.Buffer; + +namespace Qpid.Buffer.Tests +{ + /// + /// Tests for the SimpleByteBuffer class + /// + [TestFixture] + public class SimpleByteBufferTests + { + [Test] + public void CanCreateNewBuffer() + { + const int size = 10; + ByteBuffer buffer = ByteBuffer.Allocate(size); + Assert.AreEqual(size, buffer.Capacity); + Assert.AreEqual(0, buffer.Position); + Assert.AreEqual(size, buffer.Remaining); + Assert.AreEqual(true, buffer.HasRemaining); + } + + [Test] + public void CanWrapArray() + { + byte[] array = new byte[10]; + for ( int i=0; i < array.Length; i++ ) + { + array[i] = (byte) i; + } + ByteBuffer buffer = ByteBuffer.Wrap(array); + // the buffer should be the same size, + // and positioned at the end + Assert.AreEqual(array.Length, buffer.Capacity); + Assert.AreEqual(array.Length, buffer.Position); + Assert.AreEqual(array.Length, buffer.Limit); + } + + #region Base Read/Write tests + // + // Base Read/Write tests + // + [Test] + public void CanReadWriteBytes() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer.Rewind(); + Assert.AreEqual(0x01, buffer.GetByte()); + Assert.AreEqual(0x02, buffer.GetByte()); + Assert.AreEqual(0x03, buffer.GetByte()); + } + + [Test] + [ExpectedException(typeof(BufferUnderflowException))] + public void ThrowOnReadByteWithNoSpace() + { + ByteBuffer buffer = ByteBuffer.Allocate(1); + buffer.Put((byte)0x01); + buffer.GetByte(); + } + + [Test] + [ExpectedException(typeof(BufferOverflowException))] + public void ThrowOnWriteByteWithNoSpace() + { + ByteBuffer buffer = ByteBuffer.Allocate(1); + buffer.Put((byte)0x01).Put((byte)0x02); + } + + #endregion Base Read/Write tests + + #region Other Buffer Operations + // + // Other Buffer Operations + // + + [Test] + public void CanFlipBuffer() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer.Flip(); + Assert.AreEqual(10, buffer.Capacity); + Assert.AreEqual(3, buffer.Limit); + Assert.AreEqual(0, buffer.Position); + Assert.AreEqual(3, buffer.Remaining); + } + + [Test] + public void CanCompactBuffer() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer.Flip(); + buffer.Position = 1; + buffer.Compact(); + Assert.AreEqual(10, buffer.Capacity); + Assert.AreEqual(10, buffer.Limit); + Assert.AreEqual(2, buffer.Position); + Assert.AreEqual(8, buffer.Remaining); + } + + [Test] + public void CanClearBuffer() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer.Flip(); + buffer.Position = 2; + buffer.Clear(); + Assert.AreEqual(10, buffer.Capacity); + Assert.AreEqual(10, buffer.Limit); + Assert.AreEqual(0, buffer.Position); + Assert.AreEqual(10, buffer.Remaining); + } + + [Test] + public void CanExpandBuffer() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer.Flip(); + buffer.Position = 2; + int pos = buffer.Position; + buffer.Expand(20); + + Assert.AreEqual(pos, buffer.Position); + Assert.IsTrue(buffer.Remaining >= 20); + buffer.Rewind(); + Assert.AreEqual(0x01, buffer.GetByte()); + } + + [Test] + public void CanAutoExpand() + { + ByteBuffer buffer = ByteBuffer.Allocate(2); + buffer.IsAutoExpand = true; + // should cause autoexpand + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + Assert.IsTrue(buffer.Capacity > 2); + } + + [Test] + public void CanGetArray() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer.Flip(); + + byte[] array = buffer.Array; + for ( int i=0; i < buffer.Limit; i++ ) + { + Assert.AreEqual(buffer.GetByte(), array[i]); + } + } + + [Test] + public void CanSkip() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Skip(4); + Assert.AreEqual(4, buffer.Position); + } + + #endregion // Base Read/Write tests + + #region Typed Accessors + // + // Typed Accessors + // + [Test] + public void CanReadWriteSByte() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + sbyte value = -12; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetSByte()); + } + [Test] + public void CanReadWriteUInt16() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + ushort value = 41233; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetUInt16()); + } + [Test] + public void CanReadWriteInt16() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + short value = -21233; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetInt16()); + } + [Test] + public void CanReadWriteUInt32() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + uint value = 41233211; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetUInt32()); + } + [Test] + public void CanReadWriteInt32() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + int value = -22221233; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetInt32()); + } + [Test] + public void CanReadWriteUInt64() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + ulong value = 41233218871; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetUInt64()); + } + [Test] + public void CanReadWriteInt64() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + long value = -9887335411; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetInt64()); + } + [Test] + public void CanReadWriteFloat() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + float value = -1.2331f; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetFloat()); + } + + [Test] + public void CanReadWriteDouble() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + double value = -1.2331E12; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetDouble()); + } + + [Test] + public void CanReadWriteChar() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + char value = 'H'; + buffer.Put(value); + buffer.Flip(); + Assert.AreEqual(value, buffer.GetChar()); + } + + [Test] + public void CanReadWriteByteArray() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put(new byte[] { 0x01, 0x02, 0x03}); + buffer.Flip(); + byte[] data = new byte[3]; + buffer.GetBytes(data); + Assert.AreEqual(0x01, data[0]); + Assert.AreEqual(0x02, data[1]); + Assert.AreEqual(0x03, data[2]); + } + + [Test] + public void CanReadWriteByteArrayWithOffset() + { + ByteBuffer buffer = ByteBuffer.Allocate(10); + buffer.Put(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 }, 1, 4); + buffer.Flip(); + byte[] data = new byte[3]; + buffer.GetBytes(data, 2, 1); + Assert.AreEqual(0x00, data[0]); + Assert.AreEqual(0x00, data[1]); + Assert.AreEqual(0x02, data[2]); + } + + [Test] + public void CanWriteByteBuffer() + { + ByteBuffer buffer1 = ByteBuffer.Allocate(10); + buffer1.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03); + buffer1.Flip(); + + ByteBuffer buffer2 = ByteBuffer.Allocate(10); + buffer2.Put(buffer1); + buffer2.Flip(); + Assert.AreEqual(buffer1.Limit, buffer2.Limit); + Assert.AreEqual(0x01, buffer2.GetByte()); + } + #endregion // Typed Accessors + + } // class SimpleByteBufferTests +} diff --git a/qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs b/qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs new file mode 100644 index 0000000000..07c7e14a48 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs @@ -0,0 +1,133 @@ +/* + * + * 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. + * + */ + +using System; +using NUnit.Framework; +using Qpid.Buffer; + +namespace Qpid.Buffer.Tests +{ + /// + /// Tests for the SlicedByteBuffer class + /// + [TestFixture] + public class SlicedByteBufferTests + { + private ByteBuffer _baseBuffer; + + [SetUp] + public void Setup() + { + const int size = 50; + _baseBuffer = ByteBuffer.Allocate(size); + for ( byte b = 0; b < 10; b++ ) + { + _baseBuffer.Put(b); + } + _baseBuffer.Flip(); + } + + [Test] + public void CanSliceBuffer() + { + _baseBuffer.Position = 5; + + ByteBuffer slice = _baseBuffer.Slice(); + Assert.AreEqual(5, slice.Capacity); + Assert.AreEqual(0, slice.Position); + Assert.AreEqual(5, slice.Remaining); + Assert.AreEqual(5, slice.Limit); + } + + [Test] + public void CanReadWriteSlice() + { + _baseBuffer.Position = 5; + + ByteBuffer slice = _baseBuffer.Slice(); + slice.Put((byte) 0xFF).Put((byte) 0xF0).Put((byte) 0xA0); + slice.Flip(); + + Assert.AreEqual(3, slice.Limit); + Assert.AreEqual(0xFF, slice.GetByte()); + Assert.AreEqual(0xF0, slice.GetByte()); + Assert.AreEqual(0xA0, slice.GetByte()); + } + + [Test] + public void WriteModifiesBaseBufferOnCorrectPosition() + { + _baseBuffer.Position = 5; + + ByteBuffer slice = _baseBuffer.Slice(); + slice.Put((byte) 0xFF); + slice.Flip(); + // reading the _baseBuffer at position 5 should yield 0xFF + _baseBuffer.Position = 5; + Assert.AreEqual(0xFF, _baseBuffer.GetByte()); + + } + + [Test] + public void CanReadWriteByteArray() + { + _baseBuffer.Position = 5; + + ByteBuffer slice = _baseBuffer.Slice(); + byte[] data = {0xFF, 0xF0, 0xF2, 0xEE, 0x23}; + slice.Put(data, 2, 2); + slice.Flip(); + + Assert.AreEqual(2, slice.Limit); + Assert.AreEqual(0xF2, slice.GetByte()); + Assert.AreEqual(0xEE, slice.GetByte()); + } + + [Test] + [ExpectedException(typeof(BufferOverflowException))] + public void ThrowWhenWritePastLimit() + { + _baseBuffer.Position = 5; + + ByteBuffer slice = _baseBuffer.Slice(); + slice.Put(0x01).Put(0x02); + } + + + [Test] + [ExpectedException(typeof(NotSupportedException))] + public void ThrowOnCompact() + { + // we don't support compacting + ByteBuffer slice = _baseBuffer.Slice(); + slice.Compact(); + } + + [Test] + [ExpectedException(typeof(NotSupportedException))] + public void ThrowOnResize() + { + // we don't support resizing + ByteBuffer slice = _baseBuffer.Slice(); + slice.Expand(50); + } + } // class SlicedByteBufferTests +} diff --git a/qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs deleted file mode 100644 index 3a6beabae8..0000000000 --- a/qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs +++ /dev/null @@ -1,460 +0,0 @@ -/* - * - * 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.mina.common.support; -// -//import java.nio.ByteOrder; -//import java.nio.CharBuffer; -//import java.nio.DoubleBuffer; -//import java.nio.FloatBuffer; -//import java.nio.IntBuffer; -//import java.nio.LongBuffer; -//import java.nio.ShortBuffer; -// -//import org.apache.mina.common.ByteBuffer; -//import org.apache.mina.common.ByteBufferAllocator; - -namespace Qpid.Buffer -{ - /// - /// A base implementation of . This implementation - /// assumes that always returns a correct NIO - /// instance. Most implementations could - /// extend this class and implement their own buffer management mechanism. - /// - /// - public abstract class BaseByteBuffer : ByteBuffer - { - private bool _autoExpand; - - /// - /// We don't have any access to Buffer.markValue(), - /// so we need to track it down, which will cause small extra overhead. - /// - private int _mark = -1; - - protected BaseByteBuffer() - { - } - - public override bool isDirect() - { - return buf().isDirect(); - } - - public override bool isReadOnly() - { - return buf().isReadOnly(); - } - - public override int capacity() - { - return buf().capacity(); - } - - public override ByteBuffer capacity(int newCapacity) - { - if( newCapacity > capacity() ) - { - // Allocate a new buffer and transfer all settings to it. - int pos = position(); - int lim = limit(); - ByteOrder bo = order(); - - capacity0( newCapacity ); - buf().limit( lim ); - if( _mark >= 0 ) - { - buf().position( _mark ); - buf().mark(); - } - buf().position( pos ); - buf().order( bo ); - } - - return this; - } - - - /// - /// Implement this method to increase the capacity of this buffer. - /// - /// is always greater than the current capacity. - protected abstract void capacity0( int newCapacity ); - - public override bool isAutoExpand() - { - return _autoExpand; - } - - public override ByteBuffer setAutoExpand(bool autoExpand) - { - _autoExpand = autoExpand; - return this; - } - - public override ByteBuffer expand(int pos, int expectedRemaining) - { - int end = pos + expectedRemaining; - if( end > capacity() ) - { - // The buffer needs expansion. - capacity( end ); - } - - if( end > limit() ) - { - // We call limit() directly to prevent StackOverflowError - buf().limit( end ); - } - return this; - } - - public override int position() - { - return buf().position(); - } - - public override ByteBuffer position(int newPosition) - { - autoExpand( newPosition, 0 ); - buf().position( newPosition ); - if( _mark > newPosition ) - { - _mark = -1; - } - return this; - } - - public override int limit() - { - return buf().limit(); - } - - public override ByteBuffer limit(int newLimit) - { - autoExpand( newLimit, 0 ); - buf().limit( newLimit ); - if( _mark > newLimit ) - { - _mark = -1; - } - return this; - } - - public override ByteBuffer mark() - { - buf().mark(); - _mark = position(); - return this; - } - - public override int markValue() - { - return _mark; - } - - public override ByteBuffer reset() - { - buf().reset(); - return this; - } - - public override ByteBuffer clear() - { - buf().clear(); - _mark = -1; - return this; - } - - public override ByteBuffer flip() - { - buf().flip(); - _mark = -1; - return this; - } - - public override ByteBuffer rewind() - { - buf().rewind(); - _mark = -1; - return this; - } - - public override byte get() - { - return buf().get(); - } - - public override ByteBuffer put(byte b) - { - autoExpand( 1 ); - buf().put( b ); - return this; - } - - public override byte get(int index) - { - return buf().get( index ); - } - - public override ByteBuffer put(int index, byte b) - { - autoExpand( index, 1 ); - buf().put( index, b ); - return this; - } - - public override ByteBuffer get(byte[] dst, int offset, int length) - { - buf().get( dst, offset, length ); - return this; - } - - public override ByteBuffer get(byte[] dst) - { - buf().get(dst); - return this; - } - - public override ByteBuffer put(FixedByteBuffer src) - { - autoExpand( src.remaining() ); - buf().put( src ); - return this; - } - - public override ByteBuffer put(byte[] src, int offset, int length) - { - autoExpand( length ); - buf().put( src, offset, length ); - return this; - } - - public override ByteBuffer compact() - { - buf().compact(); - _mark = -1; - return this; - } - - public override ByteOrder order() - { - return buf().order(); - } - - public override ByteBuffer order(ByteOrder bo) - { - buf().order( bo ); - return this; - } - - public override char getChar() - { - return buf().getChar(); - } - - public override ByteBuffer putChar(char value) - { - autoExpand( 2 ); - buf().putChar( value ); - return this; - } - - public override char getChar(int index) - { - return buf().getChar( index ); - } - - public override ByteBuffer putChar(int index, char value) - { - autoExpand( index, 2 ); - buf().putChar( index, value ); - return this; - } - -// public CharBuffer asCharBuffer() -// { -// return buf().asCharBuffer(); -// } - - public override short getShort() - { - return buf().getShort(); - } - - public override ByteBuffer putShort(short value) - { - autoExpand( 2 ); - buf().putShort( value ); - return this; - } - - public override short getShort(int index) - { - return buf().getShort( index ); - } - - public override ByteBuffer putShort(int index, short value) - { - autoExpand( index, 2 ); - buf().putShort( index, value ); - return this; - } - - public override ushort GetUnsignedShort() - { - return buf().getUnsignedShort(); - } - - -// public ShortBuffer asShortBuffer() -// { -// return buf().asShortBuffer(); -// } - - public override int getInt() - { - return buf().getInt(); - } - - public override uint GetUnsignedInt() - { - return buf().getUnsignedInt(); - } - - public override ByteBuffer putInt(int value) - { - autoExpand( 4 ); - buf().putInt( value ); - return this; - } - - public override int getInt(int index) - { - return buf().getInt( index ); - } - - public override ByteBuffer putInt(int index, int value) - { - autoExpand( index, 4 ); - buf().putInt( index, value ); - return this; - } - -// public IntBuffer asIntBuffer() -// { -// return buf().asIntBuffer(); -// } - - public override long getLong() - { - return buf().getLong(); - } - - public override ByteBuffer putLong(long value) - { - autoExpand( 8 ); - buf().putLong( value ); - return this; - } - - public override long getLong(int index) - { - return buf().getLong( index ); - } - - public override ByteBuffer putLong(int index, long value) - { - autoExpand( index, 8 ); - buf().putLong( index, value ); - return this; - } - -// public LongBuffer asLongBuffer() -// { -// return buf().asLongBuffer(); -// } - - public override float getFloat() - { - return buf().getFloat(); - } - - public override ByteBuffer putFloat(float value) - { - autoExpand( 4 ); - buf().putFloat( value ); - return this; - } - - public override float getFloat(int index) - { - return buf().getFloat( index ); - } - - public override ByteBuffer putFloat(int index, float value) - { - autoExpand( index, 4 ); - buf().putFloat( index, value ); - return this; - } - -// public FloatBuffer asFloatBuffer() -// { -// return buf().asFloatBuffer(); -// } - - public override double getDouble() - { - return buf().getDouble(); - } - - public override ByteBuffer putDouble(double value) - { - autoExpand( 8 ); - buf().putDouble( value ); - return this; - } - - public override double getDouble(int index) - { - return buf().getDouble( index ); - } - - public override ByteBuffer putDouble(int index, double value) - { - autoExpand( index, 8 ); - buf().putDouble( index, value ); - return this; - } - - public override ByteBuffer put(byte[] src) - { - buf().put(src); - return this; - } - -// public DoubleBuffer asDoubleBuffer() -// { -// return buf().asDoubleBuffer(); -// } - } -} diff --git a/qpid/dotnet/Qpid.Buffer/BufferDataException.cs b/qpid/dotnet/Qpid.Buffer/BufferDataException.cs deleted file mode 100644 index c76441dde0..0000000000 --- a/qpid/dotnet/Qpid.Buffer/BufferDataException.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * 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. - * - */ -using System; -using System.Runtime.Serialization; - -namespace Qpid.Buffer -{ - /// - /// An exception thrown when the data the - /// contains is corrupt - /// - [Serializable] - public class BufferDataException : Exception - { - public BufferDataException() - { - } - - public BufferDataException( String message ) : base(message) - { - } - - public BufferDataException( String message, Exception cause ) : base(message, cause) - { - } - - public BufferDataException( Exception cause ) : base("", cause) - { - } - - protected BufferDataException(SerializationInfo info, StreamingContext ctxt) - : base(info, ctxt) - { - } - } -} diff --git a/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs index 1a4f0072d6..1bfc749746 100644 --- a/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs +++ b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs @@ -19,2367 +19,964 @@ * */ using System; -using System.Text; namespace Qpid.Buffer { - public enum ByteOrder { BigEndian, LittleEndian } -// /// -// /// A buffer that manages an underlying byte oriented stream, and writes and reads to and from it in -// /// BIG ENDIAN order. -// /// -// public abstract class ByteBuffer -// { -// protected const int MINIMUM_CAPACITY = 1; -// -// protected static Stack _containerStack = new Stack(); -// -// protected static Stack[] _heapBufferStacks = new Stack[] -// { -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack(), -// new Stack(), new Stack(), new Stack(), new Stack() -// }; -// -// /// -// /// Returns the direct or heap buffer which is capable of the specified size. -// /// Currently does not support direct buffers but this will be an option in future. -// /// -// /// The capacity. -// /// -// public static ByteBuffer Allocate(int capacity) -// { -// // for now, just allocate a heap buffer but in future could do an optimised "direct" buffer -// // that is implemented natively -// return Allocate(capacity, false); -// } -// -// public static ByteBuffer Allocate(int capacity, bool direct) -// { -// ByteBuffer buffer = Allocate0(capacity, direct); -// RefCountingByteBuffer buf = AllocateContainer(); -// buf.Init(buffer); -// return buf; -// } -// -// private static RefCountingByteBuffer AllocateContainer() -// { -// RefCountingByteBuffer buf = null; -// lock (_containerStack) -// { -// if (_containerStack.Count > 0) -// { -// buf = (RefCountingByteBuffer) _containerStack.Pop(); -// } -// } -// -// if (buf == null) -// { -// buf = new RefCountingByteBuffer(); -// } -// return buf; -// } -// -// protected static ByteBuffer Allocate0(int capacity, bool direct) -// { -// if (direct) -// { -// throw new NotSupportedException("Direct buffers not currently implemented"); -// } -// int idx = GetBufferStackIndex(_heapBufferStacks, capacity); -// Stack stack = _heapBufferStacks[idx]; -// ByteBuffer buf = null; -// lock (stack) -// { -// if (stack.Count > 0) -// { -// buf = (ByteBuffer) stack.Pop(); -// } -// } -// -// if (buf == null) -// { -// buf = new HeapByteBuffer(MINIMUM_CAPACITY << idx); -// } -// -// return buf; -// } -// -// protected static void Release0(ByteBuffer buf) -// { -// Stack stack = _heapBufferStacks[GetBufferStackIndex(_heapBufferStacks, buf.Capacity)]; -// lock (stack) -// { -// stack.Push(buf); -// } -// } -// -// private static int GetBufferStackIndex(Stack[] bufferStacks, int size) -// { -// int targetSize = MINIMUM_CAPACITY; -// int stackIdx = 0; -// // each bucket contains buffers that are double the size of the previous bucket -// while (size > targetSize) -// { -// targetSize <<= 1; -// stackIdx++; -// if (stackIdx >= bufferStacks.Length) -// { -// throw new ArgumentOutOfRangeException("size", "Buffer size is too big: " + size); -// } -// } -// return stackIdx; -// } -// -// /// -// /// Increases the internal reference count of this buffer to defer automatic release. You have -// /// to invoke release() as many times as you invoked this method to release this buffer. -// /// -// public abstract void Acquire(); -// -// /// -// /// Releases the specified buffer to the buffer pool. -// /// -// public abstract void Release(); -// -// public abstract int Capacity -// { -// get; -// } -// -// public abstract bool IsAutoExpand -// { -// get; -// set; -// } -// -// /// -// /// Changes the capacity and limit of this buffer sot his buffer gets the specified -// /// expectedRemaining room from the current position. This method works even if you didn't set -// /// autoExpand to true. -// /// -// /// Room you want from the current position -// public abstract void Expand(int expectedRemaining); -// -// /// -// /// Changes the capacity and limit of this buffer sot his buffer gets the specified -// /// expectedRemaining room from the specified position. -// /// -// /// The pos you want the room to be available from. -// /// The expected room you want available. -// public abstract void Expand(int pos, int expectedRemaining); -// -// /// -// /// Returns true if and only if this buffer is returned back to the buffer pool when released. -// /// -// /// true if pooled; otherwise, false. -// public abstract bool Pooled -// { -// get; -// set; -// } -// -// public abstract int Position -// { -// get; -// set; -// } -// -// public abstract int Limit -// { -// get; -// set; -// } -// -// //public abstract void Mark(); -// -// //public abstract void Reset(); -// -// public abstract void Clear(); -// -// /// -// /// Clears this buffer and fills its content with NULL. The position is set to zero, the limit is set to -// /// capacity and the mark is discarded. -// /// -// public void Sweep() -// { -// Clear(); -// FillAndReset(Remaining); -// } -// -// public void Sweep(byte value) -// { -// Clear(); -// FillAndReset(value, Remaining); -// } -// -// public abstract void Flip(); -// -// public abstract void Rewind(); -// -// public abstract int Remaining -// { -// get; -// } -// -// public bool HasRemaining() -// { -// return Remaining > 0; -// } -// -// public abstract byte Get(); -// -// public abstract byte Get(int index); -// -// public abstract void Get(byte[] destination); -// -// public abstract ushort GetUnsignedShort(); -// -// public abstract uint GetUnsignedInt(); -// -// public abstract ulong GetUnsignedLong(); -// -// public abstract string GetString(uint length, Encoding encoder); -// -// public abstract void Put(byte data); -// -// public abstract void Put(byte[] data); -// public abstract void Put(byte[] data, int offset, int size); -// -// public abstract void Put(ushort data); -// -// public abstract void Put(uint data); -// -// public abstract void Put(ulong data); -// -// public abstract void Put(ByteBuffer buf); -// -// public abstract void Compact(); -// -// public abstract byte[] ToByteArray(); -// -// public override string ToString() -// { -// StringBuilder buf = new StringBuilder(); -// buf.Append("HeapBuffer"); -// buf.AppendFormat("[pos={0} lim={1} cap={2} : {3}]", Position, Limit, Capacity, HexDump); -// return buf.ToString(); -// } -// -// public override int GetHashCode() -// { -// int h = 1; -// int p = Position; -// for (int i = Limit - 1; i >= p; i--) -// { -// h = 31 * h + Get(i); -// } -// -// return h; -// } -// -// public override bool Equals(object obj) -// { -// if (!(obj is ByteBuffer)) -// { -// return false; -// } -// ByteBuffer that = (ByteBuffer) obj; -// -// if (Remaining != that.Remaining) -// { -// return false; -// } -// int p = Position; -// for (int i = Limit - 1, j = that.Limit - 1; i >= p; i--, j--) -// { -// byte v1 = this.Get(i); -// byte v2 = that.Get(j); -// if (v1 != v2) -// { -// return false; -// } -// } -// return true; -// } -// -// public string HexDump -// { -// get -// { -// return ByteBufferHexDumper.GetHexDump(this); -// } -// } -// -// /// -// /// Fills the buffer with the specified specified value. This method moves the buffer position forward. -// /// -// /// The value. -// /// The size. -// public void Fill(byte value, int size) -// { -// AutoExpand(size); -// int q = size >> 3; -// int r = size & 7; -// -// if (q > 0) -// { -// int intValue = value | (value << 8) | (value << 16) | (value << 24); -// long longValue = intValue; -// longValue <<= 32; -// longValue |= (ushort)intValue; -// -// for (int i = q; i > 0; i--) -// { -// Put((ulong)longValue); -// } -// } -// -// q = r >> 2; -// r = r & 3; -// -// if (q > 0) -// { -// int intValue = value | (value << 8) | (value << 16) | (value << 24); -// Put((uint)intValue); -// } -// -// q = r >> 1; -// r = r & 1; -// -// if (q > 0) -// { -// short shortValue = (short) (value | (value << 8)); -// Put((ushort) shortValue); -// } -// if (r > 0) -// { -// Put(value); -// } -// } -// -// public void FillAndReset(byte value, int size) -// { -// AutoExpand(size); -// int pos = Position; -// try -// { -// Fill(value, size); -// } -// finally -// { -// Position = pos; -// } -// } -// -// public void Fill(int size) -// { -// AutoExpand(size); -// int q = size >> 3; -// int r = size & 7; -// -// for (int i = q; i > 0; i--) -// { -// Put(0L); -// } -// -// q = r >> 2; -// r = r & 3; -// -// if (q > 0) -// { -// Put(0); -// } -// -// q = r >> 1; -// r = r & 1; -// -// if(q > 0) -// { -// Put((ushort) 0); -// } -// -// if (r > 0) -// { -// Put((byte) 0); -// } -// } -// -// public void FillAndReset(int size) -// { -// AutoExpand(size); -// int pos = Position; -// try -// { -// Fill(size); -// } -// finally -// { -// Position = pos; -// } -// } -// -// public void Skip(int size) -// { -// AutoExpand(size); -// Position = Position + size; -// } -// -// protected void AutoExpand(int expectedRemaining) -// { -// if (IsAutoExpand) -// { -// Expand(expectedRemaining); -// } -// } -// -// protected void AutoExpand(int pos, int expectedRemaining) -// { -// if (IsAutoExpand) -// { -// Expand(pos, expectedRemaining); -// } -// } -// } - - /* - * 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.mina.common; -// -//import java.io.IOException; -//import java.io.InputStream; -//import java.io.ObjectInputStream; -//import java.io.ObjectOutputStream; -//import java.io.ObjectStreamClass; -//import java.io.OutputStream; -//import java.nio.BufferOverflowException; -//import java.nio.BufferUnderflowException; -//import java.nio.ByteOrder; -//import java.nio.CharBuffer; -//import java.nio.DoubleBuffer; -//import java.nio.FloatBuffer; -//import java.nio.IntBuffer; -//import java.nio.LongBuffer; -//import java.nio.ShortBuffer; -//import java.nio.charset.CharacterCodingException; -//import java.nio.charset.CharsetDecoder; -//import java.nio.charset.CharsetEncoder; -//import java.nio.charset.CoderResult; -// -//import org.apache.mina.common.support.ByteBufferHexDumper; -//import org.apache.mina.filter.codec.ProtocolEncoderOutput; - - /** - * A byte buffer used by MINA applications. - *

- * This is a replacement for {@link FixedByteBuffer}. Please refer to - * {@link FixedByteBuffer} and {@link java.nio.Buffer} documentation for - * usage. MINA does not use NIO {@link FixedByteBuffer} directly for two - * reasons: - *

- *

- * - *

Allocation

- *

- * You can get a heap buffer from buffer pool: - *

-     * ByteBuffer buf = ByteBuffer.allocate(1024, false);
-     * 
- * you can also get a direct buffer from buffer pool: - *
-     * ByteBuffer buf = ByteBuffer.allocate(1024, true);
-     * 
- * or you can let MINA choose: - *
-     * ByteBuffer buf = ByteBuffer.allocate(1024);
-     * 
- *

- * - *

Acquire/Release

- *

- * Please note that you never need to release the allocated buffer - * because MINA will release it automatically when: - *

- * And, you don't need to release any {@link ByteBuffer} which is passed as a parameter - * of {@link IoHandler#messageReceived(IoSession, Object)} method. They are released - * automatically when the method returns. - *

- * You have to release buffers manually by calling {@link #release()} when: - *

- *

- * - *

Wrapping existing NIO buffers and arrays

- *

- * This class provides a few wrap(...) methods that wraps - * any NIO buffers and byte arrays. Wrapped MINA buffers are not returned - * to the buffer pool by default to prevent unexpected memory leakage by default. - * In case you want to make it pooled, you can call {@link #setPooled(bool)} - * with true flag to enable pooling. - * - *

AutoExpand

- *

- * Writing variable-length data using NIO ByteBuffers is not really - * easy, and it is because its size is fixed. MINA ByteBuffer - * introduces autoExpand property. If autoExpand property - * is true, you never get {@link BufferOverflowException} or - * {@link IndexOutOfBoundsException} (except when index is negative). - * It automatically expands its capacity and limit value. For example: - *

-     * String greeting = messageBundle.getMessage( "hello" );
-     * ByteBuffer buf = ByteBuffer.allocate( 16 );
-     * // Turn on autoExpand (it is off by default)
-     * buf.setAutoExpand( true );
-     * buf.putString( greeting, utf8encoder );
-     * 
- * NIO ByteBuffer is reallocated by MINA ByteBuffer behind - * the scene if the encoded data is larger than 16 bytes. Its capacity will - * increase by two times, and its limit will increase to the last position - * the string is written. - *

- * - *

Derived Buffers

- *

- * Derived buffers are the buffers which were created by - * {@link #duplicate()}, {@link #slice()}, or {@link #asReadOnlyBuffer()}. - * They are useful especially when you broadcast the same messages to - * multiple {@link IoSession}s. Please note that the derived buffers are - * neither pooled nor auto-expandable. Trying to expand a derived buffer will - * raise {@link IllegalStateException}. - *

- * - *

Changing Buffer Allocation and Management Policy

- *

- * MINA provides a {@link ByteBufferAllocator} interface to let you override - * the default buffer management behavior. There are two allocators provided - * out-of-the-box: - *

- * You can change the allocator by calling {@link #setAllocator(ByteBufferAllocator)}. - *

- * - * @author The Apache Directory Project (mina-dev@directory.apache.org) - * @version $Rev: 451854 $, $Date: 2006-10-02 11:30:11 +0900 (월, 02 10월 2006) $ - * @noinspection StaticNonFinalField - * @see ByteBufferAllocator - */ - public abstract class ByteBuffer : IComparable - { - //private static ByteBufferAllocator allocator = new PooledByteBufferAllocator(); - private static IByteBufferAllocator allocator = new SimpleByteBufferAllocator(); - - private static bool _useDirectBuffers = false; - - public string HexDump - { - get - { - return ByteBufferHexDumper.GetHexDump(this); - } - } - - /** - * Returns the current allocator which manages the allocated buffers. - */ - public static IByteBufferAllocator getAllocator() - { - return allocator; - } - - /** - * Changes the current allocator with the specified one to manage - * the allocated buffers from now. - */ - public static void setAllocator( IByteBufferAllocator newAllocator ) - { - if( newAllocator == null ) - { - throw new NullReferenceException("allocator cannot be null"); - } - - IByteBufferAllocator oldAllocator = allocator; - - allocator = newAllocator; - - if( null != oldAllocator ) - { - oldAllocator.Dispose(); - } - } - - public static bool isUseDirectBuffers() - { - return _useDirectBuffers; - } - - public static void setUseDirectBuffers( bool useDirectBuffers ) - { - _useDirectBuffers = useDirectBuffers; - } - - /** - * Returns the direct or heap buffer which is capable of the specified - * size. This method tries to allocate direct buffer first, and then - * tries heap buffer if direct buffer memory is exhausted. Please use - * {@link #allocate(int, bool)} to allocate buffers of specific type. - * - * @param capacity the capacity of the buffer - */ - public static ByteBuffer allocate( int capacity ) - { - if( _useDirectBuffers ) - { - try - { - // first try to allocate direct buffer - return allocate( capacity, true ); - } - catch (OutOfMemoryException) - { - // fall through to heap buffer - } - } - - return allocate( capacity, false ); - } - - /** - * Returns the buffer which is capable of the specified size. - * - * @param capacity the capacity of the buffer - * @param direct true to get a direct buffer, - * false to get a heap buffer. - */ - public static ByteBuffer allocate( int capacity, bool direct ) - { - return allocator.Allocate( capacity, direct ); - } - - /** - * Wraps the specified NIO {@link FixedByteBuffer} into MINA buffer. - */ - public static ByteBuffer wrap( FixedByteBuffer nioBuffer ) - { - return allocator.Wrap( nioBuffer ); - } - - /** - * Wraps the specified byte array into MINA heap buffer. - */ - public static ByteBuffer wrap( byte[] byteArray ) - { - return wrap( FixedByteBuffer.wrap( byteArray ) ); - } - - /** - * Wraps the specified byte array into MINA heap buffer. - * Please note that MINA buffers are going to be pooled, and - * therefore there can be waste of memory if you wrap - * your byte array specifying offset and length. - */ - public static ByteBuffer wrap( byte[] byteArray, int offset, int length ) - { - return wrap( FixedByteBuffer.wrap( byteArray, offset, length ) ); - } - - protected ByteBuffer() - { - } - - /** - * Increases the internal reference count of this buffer to defer - * automatic release. You have to invoke {@link #release()} as many - * as you invoked this method to release this buffer. - * - * @throws IllegalStateException if you attempt to acquire already - * released buffer. - */ - public abstract void acquire(); - - /** - * Releases the specified buffer to buffer pool. - * - * @throws IllegalStateException if you attempt to release already - * released buffer. - */ - public abstract void release(); - - /** - * Returns the underlying NIO buffer instance. - */ - public abstract FixedByteBuffer buf(); - - /** - * @see FixedByteBuffer#isDirect() - */ - public abstract bool isDirect(); - - /** - * @see FixedByteBuffer#isReadOnly() - */ - public abstract bool isReadOnly(); - - /** - * @see FixedByteBuffer#capacity() - */ - public abstract int capacity(); - - /** - * Changes the capacity of this buffer. - */ - public abstract ByteBuffer capacity( int newCapacity ); - - /** - * Returns true if and only if autoExpand is turned on. - */ - public abstract bool isAutoExpand(); - - /** - * Turns on or off autoExpand. - */ - public abstract ByteBuffer setAutoExpand( bool autoExpand ); - - /** - * Changes the capacity and limit of this buffer so this buffer get - * the specified expectedRemaining room from the current position. - * This method works even if you didn't set autoExpand to - * true. - */ - public ByteBuffer expand( int expectedRemaining ) - { - return expand( position(), expectedRemaining ); - } - - /** - * Changes the capacity and limit of this buffer so this buffer get - * the specified expectedRemaining room from the specified - * pos. - * This method works even if you didn't set autoExpand to - * true. - */ - public abstract ByteBuffer expand( int pos, int expectedRemaining ); - - /** - * Returns true if and only if this buffer is returned back - * to the buffer pool when released. - *

- * The default value of this property is true if and only if you - * allocated this buffer using {@link #allocate(int)} or {@link #allocate(int, bool)}, - * or false otherwise. (i.e. {@link #wrap(byte[])}, {@link #wrap(byte[], int, int)}, - * and {@link #wrap(FixedByteBuffer)}) - */ - public abstract bool isPooled(); - - /** - * Sets whether this buffer is returned back to the buffer pool when released. - *

- * The default value of this property is true if and only if you - * allocated this buffer using {@link #allocate(int)} or {@link #allocate(int, bool)}, - * or false otherwise. (i.e. {@link #wrap(byte[])}, {@link #wrap(byte[], int, int)}, - * and {@link #wrap(FixedByteBuffer)}) - */ - public abstract void setPooled( bool pooled ); - - /** - * @see java.nio.Buffer#position() - */ - public abstract int position(); - - /** - * @see java.nio.Buffer#position(int) - */ - public abstract ByteBuffer position( int newPosition ); - - /** - * @see java.nio.Buffer#limit() - */ - public abstract int limit(); - - /** - * @see java.nio.Buffer#limit(int) - */ - public abstract ByteBuffer limit( int newLimit ); - - /** - * @see java.nio.Buffer#mark() - */ - public abstract ByteBuffer mark(); - - /** - * Returns the position of the current mark. This method returns -1 if no - * mark is set. - */ - public abstract int markValue(); - - /** - * @see java.nio.Buffer#reset() - */ - public abstract ByteBuffer reset(); - - /** - * @see java.nio.Buffer#clear() - */ - public abstract ByteBuffer clear(); - - /** - * Clears this buffer and fills its content with NUL. - * The position is set to zero, the limit is set to the capacity, - * and the mark is discarded. - */ -// public ByteBuffer sweep() -// { -// clear(); -// return fillAndReset( remaining() ); -// } - - /** - * Clears this buffer and fills its content with value. - * The position is set to zero, the limit is set to the capacity, - * and the mark is discarded. - */ -// public ByteBuffer sweep( byte value ) -// { -// clear(); -// return fillAndReset( value, remaining() ); -// } - - /** - * @see java.nio.Buffer#flip() - */ - public abstract ByteBuffer flip(); - - /** - * @see java.nio.Buffer#rewind() - */ - public abstract ByteBuffer rewind(); - - /** - * @see java.nio.Buffer#remaining() - */ - public int remaining() - { - return limit() - position(); - } - - /** - * @see java.nio.Buffer#hasRemaining() - */ - public bool hasRemaining() - { - return remaining() > 0; - } - - /** - * @see FixedByteBuffer#duplicate() - */ - public abstract ByteBuffer duplicate(); - - /** - * @see FixedByteBuffer#slice() - */ - public abstract ByteBuffer slice(); - - /** - * @see FixedByteBuffer#asReadOnlyBuffer() - */ - public abstract ByteBuffer asReadOnlyBuffer(); - - /** - * @see FixedByteBuffer#array() - */ - public abstract byte[] array(); - - /** - * @see FixedByteBuffer#arrayOffset() - */ - public abstract int arrayOffset(); - - /** - * @see FixedByteBuffer#get() - */ - public abstract byte get(); - - /** - * Reads one unsigned byte as a short integer. - */ - public short getUnsigned() - { - return (short)( get() & 0xff ); - } - - /** - * @see FixedByteBuffer#put(byte) - */ - public abstract ByteBuffer put( byte b ); - - /** - * @see FixedByteBuffer#get(int) - */ - public abstract byte get( int index ); - - /** - * Reads one byte as an unsigned short integer. - */ - public short getUnsigned( int index ) - { - return (short)( get( index ) & 0xff ); - } - - /** - * @see FixedByteBuffer#put(int, byte) - */ - public abstract ByteBuffer put( int index, byte b ); - - /** - * @see FixedByteBuffer#get(byte[], int, int) - */ - public abstract ByteBuffer get( byte[] dst, int offset, int length ); - - /** - * @see FixedByteBuffer#get(byte[]) - */ - public abstract ByteBuffer get(byte[] dst); -// { -// return get( dst, 0, dst.Length ); -// } - - /** - * Writes the content of the specified src into this buffer. - */ - public abstract ByteBuffer put( FixedByteBuffer src ); - - /** - * Writes the content of the specified src into this buffer. - */ - public ByteBuffer put( ByteBuffer src ) - { - return put( src.buf() ); - } - - /** - * @see FixedByteBuffer#put(byte[], int, int) - */ - public abstract ByteBuffer put( byte[] src, int offset, int length ); - - /** - * @see FixedByteBuffer#put(byte[]) - */ - public abstract ByteBuffer put(byte[] src); -// { -// return put(src); -//// return put( src, 0, src.Length ); -// } - - /** - * @see FixedByteBuffer#compact() - */ - public abstract ByteBuffer compact(); - - public String toString() - { - StringBuilder buf = new StringBuilder(); - if( isDirect() ) - { - buf.Append( "DirectBuffer" ); - } - else - { - buf.Append( "HeapBuffer" ); - } - buf.Append( "[pos=" ); - buf.Append( position() ); - buf.Append( " lim=" ); - buf.Append( limit() ); - buf.Append( " cap=" ); - buf.Append( capacity() ); - buf.Append( ": " ); - buf.Append( getHexDump() ); - buf.Append( ']' ); - return buf.ToString(); - } - - public int hashCode() - { - int h = 1; - int p = position(); - for( int i = limit() - 1; i >= p; i -- ) - { - h = 31 * h + get( i ); - } - return h; - } - - public bool equals( Object o ) - { - if( !( o is ByteBuffer ) ) - { - return false; - } - - ByteBuffer that = (ByteBuffer)o; - if( this.remaining() != that.remaining() ) - { - return false; - } - - int p = this.position(); - for( int i = this.limit() - 1, j = that.limit() - 1; i >= p; i --, j -- ) - { - byte v1 = this.get( i ); - byte v2 = that.get( j ); - if( v1 != v2 ) - { - return false; - } - } - return true; - } - - public int CompareTo( Object o ) - { - ByteBuffer that = (ByteBuffer)o; - int n = this.position() + Math.Min( this.remaining(), that.remaining() ); - for( int i = this.position(), j = that.position(); i < n; i ++, j ++ ) - { - byte v1 = this.get( i ); - byte v2 = that.get( j ); - if( v1 == v2 ) - { - continue; - } - if( v1 < v2 ) - { - return -1; - } - - return +1; - } - return this.remaining() - that.remaining(); - } - - /** - * @see FixedByteBuffer#order() - */ - public abstract ByteOrder order(); - - /** - * @see FixedByteBuffer#order(ByteOrder) - */ - public abstract ByteBuffer order( ByteOrder bo ); - - /** - * @see FixedByteBuffer#getChar() - */ - public abstract char getChar(); - - /** - * @see FixedByteBuffer#putChar(char) - */ - public abstract ByteBuffer putChar( char value ); - - /** - * @see FixedByteBuffer#getChar(int) - */ - public abstract char getChar( int index ); - - /** - * @see FixedByteBuffer#putChar(int, char) - */ - public abstract ByteBuffer putChar( int index, char value ); - - /** - * @see FixedByteBuffer#asCharBuffer() - */ -// public abstract CharBuffer asCharBuffer(); - - /** - * @see FixedByteBuffer#getShort() - */ - public abstract short getShort(); - - /** - * Reads two bytes unsigned integer. - */ - public int getUnsignedShort() - { - return getShort() & 0xffff; - } - - /** - * @see FixedByteBuffer#putShort(short) - */ - public abstract ByteBuffer putShort( short value ); - - /** - * @see FixedByteBuffer#getShort() - */ - public abstract short getShort( int index ); - - /** - * Reads two bytes unsigned integer. - */ - public int getUnsignedShort( int index ) - { - return getShort( index ) & 0xffff; - } - - /** - * @see FixedByteBuffer#putShort(int, short) - */ - public abstract ByteBuffer putShort( int index, short value ); - - /** - * @see FixedByteBuffer#asShortBuffer() - */ -// public abstract ShortBuffer asShortBuffer(); - - /** - * @see FixedByteBuffer#getInt() - */ - public abstract int getInt(); - - /** - * Reads four bytes unsigned integer. - */ - public uint getUnsignedInt() - { -// return getInt() & 0xffffffffL; - - //CheckSpaceForReading(4); - byte b1 = get(); - byte b2 = get(); - byte b3 = get(); - byte b4 = get(); - return (uint)((b1 << 24) + (b2 << 16) + (b3 << 8) + b4); - } - - /** - * @see FixedByteBuffer#putInt(int) - */ - public abstract ByteBuffer putInt( int value ); - - /** - * @see FixedByteBuffer#getInt(int) - */ - public abstract int getInt( int index ); - - /** - * Reads four bytes unsigned integer. - */ - public long getUnsignedInt( int index ) - { - return getInt( index ) & 0xffffffffL; - } - - /** - * @see FixedByteBuffer#putInt(int, int) - */ - public abstract ByteBuffer putInt( int index, int value ); - - /** - * @see FixedByteBuffer#asIntBuffer() - */ -// public abstract IntBuffer asIntBuffer(); - - /** - * @see FixedByteBuffer#getLong() - */ - public abstract long getLong(); - - /** - * @see FixedByteBuffer#putLong(int, long) - */ - public abstract ByteBuffer putLong( long value ); - - /** - * @see FixedByteBuffer#getLong(int) - */ - public abstract long getLong( int index ); - - /** - * @see FixedByteBuffer#putLong(int, long) - */ - public abstract ByteBuffer putLong( int index, long value ); - - /** - * @see FixedByteBuffer#asLongBuffer() - */ -// public abstract LongBuffer asLongBuffer(); - - /** - * @see FixedByteBuffer#getFloat() - */ - public abstract float getFloat(); - - /** - * @see FixedByteBuffer#putFloat(float) - */ - public abstract ByteBuffer putFloat( float value ); - - /** - * @see FixedByteBuffer#getFloat(int) - */ - public abstract float getFloat( int index ); - - /** - * @see FixedByteBuffer#putFloat(int, float) - */ - public abstract ByteBuffer putFloat( int index, float value ); - - /** - * @see FixedByteBuffer#asFloatBuffer() - */ -// public abstract FloatBuffer asFloatBuffer(); - - /** - * @see FixedByteBuffer#getDouble() - */ - public abstract double getDouble(); - - /** - * @see FixedByteBuffer#putDouble(double) - */ - public abstract ByteBuffer putDouble( double value ); - - /** - * @see FixedByteBuffer#getDouble(int) - */ - public abstract double getDouble( int index ); - - /** - * @see FixedByteBuffer#putDouble(int, double) - */ - public abstract ByteBuffer putDouble( int index, double value ); - - /** - * @see FixedByteBuffer#asDoubleBuffer() - */ -// public abstract DoubleBuffer asDoubleBuffer(); - - /** - * Returns an {@link InputStream} that reads the data from this buffer. - * {@link InputStream#read()} returns -1 if the buffer position - * reaches to the limit. - */ -// public InputStream asInputStream() -// { -// // XXX: Use System.IO.Stream here? -// return new InputStream() -// { -// public int available() -// { -// return ByteBuffer.this.remaining(); -// } -// -// public synchronized void mark( int readlimit ) -// { -// ByteBuffer.this.mark(); -// } -// -// public bool markSupported() -// { -// return true; -// } -// -// public int read() -// { -// if( ByteBuffer.this.hasRemaining() ) -// { -// return ByteBuffer.this.get() & 0xff; -// } -// else -// { -// return -1; -// } -// } -// -// public int read( byte[] b, int off, int len ) -// { -// int remaining = ByteBuffer.this.remaining(); -// if( remaining > 0 ) -// { -// int readBytes = Math.min( remaining, len ); -// ByteBuffer.this.get( b, off, readBytes ); -// return readBytes; -// } -// else -// { -// return -1; -// } -// } -// -// public synchronized void reset() -// { -// ByteBuffer.this.reset(); -// } -// -// public long skip( long n ) -// { -// int bytes; -// if( n > Integer.MAX_VALUE ) -// { -// bytes = ByteBuffer.this.remaining(); -// } -// else -// { -// bytes = Math.min( ByteBuffer.this.remaining(), (int)n ); -// } -// ByteBuffer.this.skip( bytes ); -// return bytes; -// } -// }; -// } - - /** - * Returns an {@link OutputStream} that Appends the data into this buffer. - * Please note that the {@link OutputStream#write(int)} will throw a - * {@link BufferOverflowException} instead of an {@link IOException} - * in case of buffer overflow. Please set autoExpand property by - * calling {@link #setAutoExpand(bool)} to prevent the unexpected runtime - * exception. - */ -// public OutputStream asOutputStream() -// { -// return new OutputStream() -// { -// public void write( byte[] b, int off, int len ) -// { -// ByteBuffer.this.put( b, off, len ); -// } -// -// public void write( int b ) -// { -// ByteBuffer.this.put( (byte)b ); -// } -// }; -// } - - /** - * Returns hexdump of this buffer. - */ - public String getHexDump() - { - return ByteBufferHexDumper.GetHexDump(this); - } - - //////////////////////////////// - // String getters and putters // - //////////////////////////////// - - /** - * Reads a NUL-terminated string from this buffer using the - * specified decoder and returns it. This method reads - * until the limit of this buffer if no NUL is found. - */ -// public String getString( Encoding decoder ) -// { -// if( !hasRemaining() ) -// { -// return ""; -// } -// -// decoder. -// bool utf16 = decoder.charset().name().startsWith( "UTF-16" ); -// -// int oldPos = position(); -// int oldLimit = limit(); -// int end; -// -// if( !utf16 ) -// { -// while( hasRemaining() ) -// { -// if( get() == 0 ) -// { -// break; -// } -// } -// -// end = position(); -// if( end == oldLimit && get( end - 1 ) != 0 ) -// { -// limit( end ); -// } -// else -// { -// limit( end - 1 ); -// } -// } -// else -// { -// while( remaining() >= 2 ) -// { -// if( ( get() == 0 ) && ( get() == 0 ) ) -// { -// break; -// } -// } -// -// end = position(); -// if( end == oldLimit || end == oldLimit - 1 ) -// { -// limit( end ); -// } -// else -// { -// limit( end - 2 ); -// } -// } -// -// position( oldPos ); -// if( !hasRemaining() ) -// { -// limit( oldLimit ); -// position( end ); -// return ""; -// } -// decoder.reset(); -// -// int expectedLength = (int)( remaining() * decoder.averageCharsPerByte() ) + 1; -// CharBuffer out = CharBuffer.allocate( expectedLength ); -// for( ; ; ) -// { -// CoderResult cr; -// if( hasRemaining() ) -// { -// cr = decoder.decode( buf(), out, true ); -// } -// else -// { -// cr = decoder.flush( out ); -// } -// -// if( cr.isUnderflow() ) -// { -// break; -// } -// -// if( cr.isOverflow() ) -// { -// CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength ); -// out.flip(); -// o.put( out ); -// out = o; -// continue; -// } -// -// cr.throwException(); -// } -// -// limit( oldLimit ); -// position( end ); -// return out.flip().toString(); -// } - - /** - * Reads a NUL-terminated string from this buffer using the - * specified decoder and returns it. - * - * @param fieldSize the maximum number of bytes to read - */ -// public String getString( int fieldSize, CharsetDecoder decoder ) throws CharacterCodingException -// { -// checkFieldSize( fieldSize ); -// -// if( fieldSize == 0 ) -// { -// return ""; -// } -// -// if( !hasRemaining() ) -// { -// return ""; -// } -// -// bool utf16 = decoder.charset().name().startsWith( "UTF-16" ); -// -// if( utf16 && ( ( fieldSize & 1 ) != 0 ) ) -// { -// throw new IllegalArgumentException( "fieldSize is not even." ); -// } -// -// int oldPos = position(); -// int oldLimit = limit(); -// int end = position() + fieldSize; -// -// if( oldLimit < end ) -// { -// throw new BufferUnderflowException(); -// } -// -// int i; -// -// if( !utf16 ) -// { -// for( i = 0; i < fieldSize; i ++ ) -// { -// if( get() == 0 ) -// { -// break; -// } -// } -// -// if( i == fieldSize ) -// { -// limit( end ); -// } -// else -// { -// limit( position() - 1 ); -// } -// } -// else -// { -// for( i = 0; i < fieldSize; i += 2 ) -// { -// if( ( get() == 0 ) && ( get() == 0 ) ) -// { -// break; -// } -// } -// -// if( i == fieldSize ) -// { -// limit( end ); -// } -// else -// { -// limit( position() - 2 ); -// } -// } -// -// position( oldPos ); -// if( !hasRemaining() ) -// { -// limit( oldLimit ); -// position( end ); -// return ""; -// } -// decoder.reset(); -// -// int expectedLength = (int)( remaining() * decoder.averageCharsPerByte() ) + 1; -// CharBuffer out = CharBuffer.allocate( expectedLength ); -// for( ; ; ) -// { -// CoderResult cr; -// if( hasRemaining() ) -// { -// cr = decoder.decode( buf(), out, true ); -// } -// else -// { -// cr = decoder.flush( out ); -// } -// -// if( cr.isUnderflow() ) -// { -// break; -// } -// -// if( cr.isOverflow() ) -// { -// CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength ); -// out.flip(); -// o.put( out ); -// out = o; -// continue; -// } -// -// cr.throwException(); -// } -// -// limit( oldLimit ); -// position( end ); -// return out.flip().toString(); -// } - - /** - * Writes the content of in into this buffer using the - * specified encoder. This method doesn't terminate - * string with NUL. You have to do it by yourself. - * - * @throws BufferOverflowException if the specified string doesn't fit - */ -// public ByteBuffer putString( -// CharSequence val, CharsetEncoder encoder ) throws CharacterCodingException -// { -// if( val.length() == 0 ) -// { -// return this; -// } -// -// CharBuffer in = CharBuffer.wrap( val ); -// encoder.reset(); -// -// int expandedState = 0; -// -// for( ; ; ) -// { -// CoderResult cr; -// if( in.hasRemaining() ) -// { -// cr = encoder.encode( in, buf(), true ); -// } -// else -// { -// cr = encoder.flush( buf() ); -// } -// -// if( cr.isUnderflow() ) -// { -// break; -// } -// if( cr.isOverflow() ) -// { -// if( isAutoExpand() ) -// { -// switch( expandedState ) -// { -// case 0: -// autoExpand( (int)Math.ceil( in.remaining() * encoder.averageBytesPerChar() ) ); -// expandedState ++; -// break; -// case 1: -// autoExpand( (int)Math.ceil( in.remaining() * encoder.maxBytesPerChar() ) ); -// expandedState ++; -// break; -// default: -// throw new RuntimeException( "Expanded by " + -// (int)Math.ceil( in.remaining() * encoder.maxBytesPerChar() ) + -// " but that wasn't enough for '" + val + "'" ); -// } -// continue; -// } -// } -// else -// { -// expandedState = 0; -// } -// cr.throwException(); -// } -// return this; -// } - - /** - * Writes the content of in into this buffer as a - * NUL-terminated string using the specified - * encoder. - *

- * If the charset name of the encoder is UTF-16, you cannot specify - * odd fieldSize, and this method will Append two - * NULs as a terminator. - *

- * Please note that this method doesn't terminate with NUL - * if the input string is longer than fieldSize. - * - * @param fieldSize the maximum number of bytes to write - */ -// public ByteBuffer putString( -// CharSequence val, int fieldSize, CharsetEncoder encoder ) throws CharacterCodingException -// { -// checkFieldSize( fieldSize ); -// -// if( fieldSize == 0 ) -// return this; -// -// autoExpand( fieldSize ); -// -// bool utf16 = encoder.charset().name().startsWith( "UTF-16" ); -// -// if( utf16 && ( ( fieldSize & 1 ) != 0 ) ) -// { -// throw new IllegalArgumentException( "fieldSize is not even." ); -// } -// -// int oldLimit = limit(); -// int end = position() + fieldSize; -// -// if( oldLimit < end ) -// { -// throw new BufferOverflowException(); -// } -// -// if( val.length() == 0 ) -// { -// if( !utf16 ) -// { -// put( (byte)0x00 ); -// } -// else -// { -// put( (byte)0x00 ); -// put( (byte)0x00 ); -// } -// position( end ); -// return this; -// } -// -// CharBuffer in = CharBuffer.wrap( val ); -// limit( end ); -// encoder.reset(); -// -// for( ; ; ) -// { -// CoderResult cr; -// if( in.hasRemaining() ) -// { -// cr = encoder.encode( in, buf(), true ); -// } -// else -// { -// cr = encoder.flush( buf() ); -// } -// -// if( cr.isUnderflow() || cr.isOverflow() ) -// { -// break; -// } -// cr.throwException(); -// } -// -// limit( oldLimit ); -// -// if( position() < end ) -// { -// if( !utf16 ) -// { -// put( (byte)0x00 ); -// } -// else -// { -// put( (byte)0x00 ); -// put( (byte)0x00 ); -// } -// } -// -// position( end ); -// return this; -// } - - /** - * Reads a string which has a 16-bit length field before the actual - * encoded string, using the specified decoder and returns it. - * This method is a shortcut for getPrefixedString(2, decoder). - */ -// public String getPrefixedString( CharsetDecoder decoder ) throws CharacterCodingException -// { -// return getPrefixedString( 2, decoder ); -// } - - /** - * Reads a string which has a length field before the actual - * encoded string, using the specified decoder and returns it. - * - * @param prefixLength the length of the length field (1, 2, or 4) - */ -// public String getPrefixedString( int prefixLength, CharsetDecoder decoder ) throws CharacterCodingException -// { -// if( !prefixedDataAvailable( prefixLength ) ) -// { -// throw new BufferUnderflowException(); -// } -// -// int fieldSize = 0; -// -// switch( prefixLength ) -// { -// case 1: -// fieldSize = getUnsigned(); -// break; -// case 2: -// fieldSize = getUnsignedShort(); -// break; -// case 4: -// fieldSize = getInt(); -// break; -// } -// -// if( fieldSize == 0 ) -// { -// return ""; -// } -// -// bool utf16 = decoder.charset().name().startsWith( "UTF-16" ); -// -// if( utf16 && ( ( fieldSize & 1 ) != 0 ) ) -// { -// throw new BufferDataException( "fieldSize is not even for a UTF-16 string." ); -// } -// -// int oldLimit = limit(); -// int end = position() + fieldSize; -// -// if( oldLimit < end ) -// { -// throw new BufferUnderflowException(); -// } -// -// limit( end ); -// decoder.reset(); -// -// int expectedLength = (int)( remaining() * decoder.averageCharsPerByte() ) + 1; -// CharBuffer out = CharBuffer.allocate( expectedLength ); -// for( ; ; ) -// { -// CoderResult cr; -// if( hasRemaining() ) -// { -// cr = decoder.decode( buf(), out, true ); -// } -// else -// { -// cr = decoder.flush( out ); -// } -// -// if( cr.isUnderflow() ) -// { -// break; -// } -// -// if( cr.isOverflow() ) -// { -// CharBuffer o = CharBuffer.allocate( out.capacity() + expectedLength ); -// out.flip(); -// o.put( out ); -// out = o; -// continue; -// } -// -// cr.throwException(); -// } -// -// limit( oldLimit ); -// position( end ); -// return out.flip().toString(); -// } - - /** - * Writes the content of in into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified encoder. - * This method is a shortcut for putPrefixedString(in, 2, 0, encoder). - * - * @throws BufferOverflowException if the specified string doesn't fit - */ -// public ByteBuffer putPrefixedString( CharSequence in, CharsetEncoder encoder ) throws CharacterCodingException -// { -// return putPrefixedString( in, 2, 0, encoder ); -// } - - /** - * Writes the content of in into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified encoder. - * This method is a shortcut for putPrefixedString(in, prefixLength, 0, encoder). - * - * @param prefixLength the length of the length field (1, 2, or 4) - * - * @throws BufferOverflowException if the specified string doesn't fit - */ -// public ByteBuffer putPrefixedString( CharSequence in, int prefixLength, CharsetEncoder encoder ) -// throws CharacterCodingException -// { -// return putPrefixedString( in, prefixLength, 0, encoder ); -// } - - /** - * Writes the content of in into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified encoder. - * This method is a shortcut for putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder). - * - * @param prefixLength the length of the length field (1, 2, or 4) - * @param padding the number of padded NULs (1 (or 0), 2, or 4) - * - * @throws BufferOverflowException if the specified string doesn't fit - */ -// public ByteBuffer putPrefixedString( CharSequence in, int prefixLength, int padding, CharsetEncoder encoder ) -// throws CharacterCodingException -// { -// return putPrefixedString( in, prefixLength, padding, (byte)0, encoder ); -// } - - /** - * Writes the content of in into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified encoder. - * - * @param prefixLength the length of the length field (1, 2, or 4) - * @param padding the number of padded bytes (1 (or 0), 2, or 4) - * @param padValue the value of padded bytes - * - * @throws BufferOverflowException if the specified string doesn't fit - */ -// public ByteBuffer putPrefixedString( CharSequence val, -// int prefixLength, -// int padding, -// byte padValue, -// CharsetEncoder encoder ) throws CharacterCodingException -// { -// int maxLength; -// switch( prefixLength ) -// { -// case 1: -// maxLength = 255; -// break; -// case 2: -// maxLength = 65535; -// break; -// case 4: -// maxLength = Integer.MAX_VALUE; -// break; -// default: -// throw new IllegalArgumentException( "prefixLength: " + prefixLength ); -// } -// -// if( val.length() > maxLength ) -// { -// throw new IllegalArgumentException( "The specified string is too long." ); -// } -// if( val.length() == 0 ) -// { -// switch( prefixLength ) -// { -// case 1: -// put( (byte)0 ); -// break; -// case 2: -// putShort( (short)0 ); -// break; -// case 4: -// putInt( 0 ); -// break; -// } -// return this; -// } -// -// int padMask; -// switch( padding ) -// { -// case 0: -// case 1: -// padMask = 0; -// break; -// case 2: -// padMask = 1; -// break; -// case 4: -// padMask = 3; -// break; -// default: -// throw new IllegalArgumentException( "padding: " + padding ); -// } -// -// CharBuffer in = CharBuffer.wrap( val ); -// int expectedLength = (int)( in.remaining() * encoder.averageBytesPerChar() ) + 1; -// -// skip( prefixLength ); // make a room for the length field -// int oldPos = position(); -// encoder.reset(); -// -// for( ; ; ) -// { -// CoderResult cr; -// if( in.hasRemaining() ) -// { -// cr = encoder.encode( in, buf(), true ); -// } -// else -// { -// cr = encoder.flush( buf() ); -// } -// -// if( position() - oldPos > maxLength ) -// { -// throw new IllegalArgumentException( "The specified string is too long." ); -// } -// -// if( cr.isUnderflow() ) -// { -// break; -// } -// if( cr.isOverflow() && isAutoExpand() ) -// { -// autoExpand( expectedLength ); -// continue; -// } -// cr.throwException(); -// } -// -// // Write the length field -// fill( padValue, padding - ( ( position() - oldPos ) & padMask ) ); -// int length = position() - oldPos; -// switch( prefixLength ) -// { -// case 1: -// put( oldPos - 1, (byte)length ); -// break; -// case 2: -// putShort( oldPos - 2, (short)length ); -// break; -// case 4: -// putInt( oldPos - 4, length ); -// break; -// } -// return this; -// } - - /** - * Reads a Java object from the buffer using the context {@link ClassLoader} - * of the current thread. - */ -// public Object getObject() throws ClassNotFoundException -// { -// return getObject( Thread.currentThread().getContextClassLoader() ); -// } - - /** - * Reads a Java object from the buffer using the specified classLoader. - */ -// public Object getObject( final ClassLoader classLoader ) throws ClassNotFoundException -// { -// if( !prefixedDataAvailable( 4 ) ) -// { -// throw new BufferUnderflowException(); -// } -// -// int length = getInt(); -// if( length <= 4 ) -// { -// throw new BufferDataException( "Object length should be greater than 4: " + length ); -// } -// -// int oldLimit = limit(); -// limit( position() + length ); -// try -// { -// ObjectInputStream in = new ObjectInputStream( asInputStream() ) -// { -// protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException -// { -// String className = readUTF(); -// Class clazz = Class.forName( className, true, classLoader ); -// return ObjectStreamClass.lookup( clazz ); -// } -// }; -// return in.readObject(); -// } -// catch( IOException e ) -// { -// throw new BufferDataException( e ); -// } -// finally -// { -// limit( oldLimit ); -// } -// } - - /** - * Writes the specified Java object to the buffer. - */ -// public ByteBuffer putObject( Object o ) -// { -// int oldPos = position(); -// skip( 4 ); // Make a room for the length field. -// try -// { -// ObjectOutputStream out = new ObjectOutputStream( asOutputStream() ) -// { -// protected void writeClassDescriptor( ObjectStreamClass desc ) throws IOException -// { -// writeUTF( desc.getName() ); -// } -// }; -// out.writeObject( o ); -// out.flush(); -// } -// catch( IOException e ) -// { -// throw new BufferDataException( e ); -// } -// -// // Fill the length field -// int newPos = position(); -// position( oldPos ); -// putInt( newPos - oldPos - 4 ); -// position( newPos ); -// return this; -// } - - /** - * Returns true if this buffer contains a data which has a data - * length as a prefix and the buffer has remaining data as enough as - * specified in the data length field. This method is identical with - * prefixedDataAvailable( prefixLength, Integer.MAX_VALUE ). - * Please not that using this method can allow DoS (Denial of Service) - * attack in case the remote peer sends too big data length value. - * It is recommended to use {@link #prefixedDataAvailable(int, int)} - * instead. - * - * @param prefixLength the length of the prefix field (1, 2, or 4) - * - * @throws IllegalArgumentException if prefixLength is wrong - * @throws BufferDataException if data length is negative - */ - public bool prefixedDataAvailable( int prefixLength ) - { - return prefixedDataAvailable( prefixLength, int.MaxValue); - } - - /** - * Returns true if this buffer contains a data which has a data - * length as a prefix and the buffer has remaining data as enough as - * specified in the data length field. - * - * @param prefixLength the length of the prefix field (1, 2, or 4) - * @param maxDataLength the allowed maximum of the read data length - * - * @throws IllegalArgumentException if prefixLength is wrong - * @throws BufferDataException if data length is negative or greater then maxDataLength - */ - public bool prefixedDataAvailable( int prefixLength, int maxDataLength ) - { - if( remaining() < prefixLength ) - { - return false; - } - - int dataLength; - switch( prefixLength ) - { - case 1: - dataLength = getUnsigned( position() ); - break; - case 2: - dataLength = getUnsignedShort( position() ); - break; - case 4: - dataLength = getInt( position() ); - break; - default: - throw new ArgumentException("prefixLength: " + prefixLength); - } - - if( dataLength < 0 || dataLength > maxDataLength ) - { - throw new BufferDataException( "dataLength: " + dataLength ); - } - - return remaining() - prefixLength >= dataLength; - } - - ////////////////////////// - // Skip or fill methods // - ////////////////////////// - - /** - * Forwards the position of this buffer as the specified size - * bytes. - */ - public ByteBuffer skip( int size ) - { - autoExpand( size ); - return position( position() + size ); - } - - /** - * Fills this buffer with the specified value. - * This method moves buffer position forward. - */ -// public ByteBuffer fill( byte value, int size ) -// { -// autoExpand( size ); -// int q = size >>> 3; -// int r = size & 7; -// -// if( q > 0 ) -// { -// int intValue = value | ( value << 8 ) | ( value << 16 ) -// | ( value << 24 ); -// long longValue = intValue; -// longValue <<= 32; -// longValue |= intValue; -// -// for( int i = q; i > 0; i -- ) -// { -// putLong( longValue ); -// } -// } -// -// q = r >>> 2; -// r = r & 3; -// -// if( q > 0 ) -// { -// int intValue = value | ( value << 8 ) | ( value << 16 ) -// | ( value << 24 ); -// putInt( intValue ); -// } -// -// q = r >> 1; -// r = r & 1; -// -// if( q > 0 ) -// { -// short shortValue = (short)( value | ( value << 8 ) ); -// putShort( shortValue ); -// } -// -// if( r > 0 ) -// { -// put( value ); -// } -// -// return this; -// } - - /** - * Fills this buffer with the specified value. - * This method does not change buffer position. - */ -// public ByteBuffer fillAndReset( byte value, int size ) -// { -// autoExpand( size ); -// int pos = position(); -// try -// { -// fill( value, size ); -// } -// finally -// { -// position( pos ); -// } -// return this; -// } - - /** - * Fills this buffer with NUL (0x00). - * This method moves buffer position forward. - */ -// public ByteBuffer fill( int size ) -// { -// autoExpand( size ); -// int q = size >>> 3; -// int r = size & 7; -// -// for( int i = q; i > 0; i -- ) -// { -// putLong( 0L ); -// } -// -// q = r >>> 2; -// r = r & 3; -// -// if( q > 0 ) -// { -// putInt( 0 ); -// } -// -// q = r >> 1; -// r = r & 1; -// -// if( q > 0 ) -// { -// putShort( (short)0 ); -// } -// -// if( r > 0 ) -// { -// put( (byte)0 ); -// } -// -// return this; -// } - - /** - * Fills this buffer with NUL (0x00). - * This method does not change buffer position. - */ -// public ByteBuffer fillAndReset( int size ) -// { -// autoExpand( size ); -// int pos = position(); -// try -// { -// fill( size ); -// } -// finally -// { -// position( pos ); -// } -// -// return this; -// } - - /** - * This method forwards the call to {@link #expand(int)} only when - * autoExpand property is true. - */ - protected ByteBuffer autoExpand( int expectedRemaining ) - { - if( isAutoExpand() ) - { - expand( expectedRemaining ); - } - return this; - } - - /** - * This method forwards the call to {@link #expand(int)} only when - * autoExpand property is true. - */ - protected ByteBuffer autoExpand( int pos, int expectedRemaining ) - { - if( isAutoExpand() ) - { - expand( pos, expectedRemaining ); - } - return this; - } - - public abstract void put(ushort value); - public abstract ushort GetUnsignedShort(); - public abstract uint GetUnsignedInt(); - public abstract void put(uint max); - public abstract void put(ulong tag); - public abstract ulong GetUnsignedLong(); - } + ///

+ /// Abstract class implementing a byte buffer + /// + public abstract class ByteBuffer + { + private int _position; + private int _limit; + private bool _isAutoExpand; + private static IByteBufferAllocator _allocator = + new SimpleByteBufferAllocator(); + + #region Properties + // + // Properties + // + + /// + /// The maximum number of bytes the buffer can hold + /// + public abstract int Capacity + { + get; + } + + /// + /// Return the backing array of this buffer + /// + public abstract byte[] Array + { + get; + } + + /// + /// The current position inside this buffer + /// + public int Position + { + get { return _position; } + set { Seek(value); } + } + + /// + /// Index of the first element that should not be read or written. + /// A buffer's limit is never negative and is never greater than the its capacity. + /// + public int Limit + { + get { return _limit; } + set { SetLimit(value); } + } + + /// + /// Number of bytes remaining in the buffer from the current position + /// + public int Remaining + { + get { return Limit - Position; } + } + + /// + /// True if there are bytes remaining in the buffer + /// + public bool HasRemaining + { + get { return Remaining > 0; } + } + + /// + /// If true, the buffer will be resized as necessary + /// to allow space for writing. By default is false. + /// + public bool IsAutoExpand + { + get { return _isAutoExpand; } + set { _isAutoExpand = value; } + } + + #endregion // Properties + + #region Buffer Manipulation + // + // Buffer Manipulation + // + + /// + /// Move the buffer to Position 0 + /// + /// This instance + public ByteBuffer Rewind() + { + Seek(0); + return this; + } + + /// + /// Prepare the buffer to read back what's been written + /// + /// This instance + public ByteBuffer Flip() + { + Limit = Position; + Position = 0; + return this; + } + + /// + /// Compact this buffer. + /// + /// This instance + /// + /// The bytes between the buffer's current position and its limit, if any, + /// are copied to the beginning of the buffer. + /// + public ByteBuffer Compact() + { + DoCompact(); + return this; + } + + /// + /// Clears this buffer. The position is set to zero, the limit is set to the capacity + /// + /// This instance + public ByteBuffer Clear() + { + Limit = Capacity; + Position = 0; + return this; + } + + /// + /// Expands this buffer's capacity so that + /// Remaining == expectedRemaining + /// + /// Number of bytes that should be accessable after resizing + /// This instance + public ByteBuffer Expand(int expectedRemaining) + { + return Expand(Position, expectedRemaining); + } + + /// + /// Expands this buffer's capacity so that + /// Remaining == expectedRemaining + /// + /// Position from which to start the resize + /// Number of bytes that should be accessable after resizing + /// This instance + public ByteBuffer Expand(int position, int expectedRemaining) + { + if ( expectedRemaining <= 0 ) + throw new ArgumentException("expectedRemaining must be greater than 0"); + + int end = position + expectedRemaining; + if ( end > Capacity ) + { + DoResize(end); + } + if ( end > Limit ) + Limit = end; + return this; + } + + /// + /// Creates a new byte buffer whose content is a shared + /// subsequence of this buffer's content. + /// + /// + /// The content of the new buffer will start at this buffer's current position. + /// Changes to this buffer's content will be visible in the new buffer, + /// and vice versa; the two buffers' position and limit values will be independent. + /// + /// The new buffer's position will be zero, its capacity and its limit will + /// be the number of bytes remaining in this buffer. + /// + /// + /// A view on top of this instance + public ByteBuffer Slice() + { + return new SlicedByteBuffer(this); + } + + /// + /// Skip the specified number of bytes + /// + /// Number of bytes to move forward by + /// This instance + public ByteBuffer Skip(int numBytes) + { + Position += numBytes; + return this; + } + + /// + /// Acquire this buffer to keep it alive. + /// + public virtual void Acquire() + { + // override in subclass if supported + } + + /// + /// Release this buffer instance + /// + public virtual void Release() + { + // override in subclass if supported + } + + /// + /// Return a string with a Hex Dump of this buffer's contents + /// + /// The hex dump + public string GetHexDump() + { + return ByteBufferHexDumper.GetHexDump(this); + } + + public override string ToString() + { + return GetHexDump(); + } + #endregion // Buffer Manipulation + + #region Static Operations + // + // Static Operations + // + /// + /// Replaces the default allocator with your own implementation + /// + /// New allocator + public static void SetAllocator(IByteBufferAllocator allocator) + { + if ( allocator == null ) + throw new ArgumentNullException("allocator"); + _allocator = allocator; + } + + /// + /// Allocate a new buffer with the specified capacity + /// using the default allocator + /// + /// Desired capacity + /// The new buffer + public static ByteBuffer Allocate(int capacity) + { + return _allocator.Allocate(capacity); + } + + /// + /// Wraps the specified arrat into a new buffer + /// + /// + /// + public static ByteBuffer Wrap(byte[] buffer) + { + return _allocator.Wrap(buffer); + } + #endregion // Static Operations + + #region Data Accessors + // + // Data Accessors + // + + // Byte Stuff + + /// + /// Read the next byte in the buffer + /// + /// The next byte available + public byte GetByte() + { + byte value = GetByte(Position); + Position += 1; + return value; + } + /// + /// Read the byte at the specified position + /// + /// Position to read from + /// The value at the position + public byte GetByte(int position) + { + CheckSpaceForReading(position, 1); + return ReadByte(position); + } + /// + /// Write a byte at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(byte value) + { + Put(Position, value); + Position++; + return this; + } + /// + /// Write a byte at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, byte value) + { + CheckSpaceForWriting(position, 1); + Write(position, value); + return this; + } + + // SByte Stuff + + /// + /// Read the next signed byte in the buffer + /// + /// The next signed byte available + public sbyte GetSByte() + { + sbyte value = GetSByte(Position); + Position += 1; + return value; + } + /// + /// Read the signed byte at the specified position + /// + /// Position to read from + /// The value at the position + public sbyte GetSByte(int position) + { + CheckSpaceForReading(position, 1); + return (sbyte)ReadByte(position); + } + + /// + /// Write a signed byte at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(sbyte value) + { + Put(Position, value); + Position += 1; + return this; + } + + /// + /// Write a signed byte at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, sbyte value) + { + CheckSpaceForWriting(position, 1); + Write(position, (byte)value); + return this; + } + + // UInt16 Stuff + + /// + /// Read the next uint16 in the buffer + /// + /// The next uint16 available + public ushort GetUInt16() + { + ushort value = GetUInt16(Position); + Position += 2; + return value; + } + /// + /// Read the uint16 at the specified position + /// + /// Position to read from + /// The value at the position + public ushort GetUInt16(int position) + { + CheckSpaceForReading(position, 2); + byte upper = ReadByte(position); + byte lower = ReadByte(position+1); + return (ushort)(((ushort)upper << 8) + lower); + } + + /// + /// Write a uint16 at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(ushort value) + { + Put(Position, value); + Position += 2; + return this; + } + + /// + /// Write a uint16 at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, ushort value) + { + CheckSpaceForWriting(position, 2); + Write(position, (byte)(value >> 8)); + Write(position+1, (byte)(value)); + return this; + } + + // Int16 Stuff + + /// + /// Read the next int16 in the buffer + /// + /// The next int16 available + public short GetInt16() + { + return (short) GetUInt16(); + } + /// + /// Read the int16 at the specified position + /// + /// Position to read from + /// The value at the position + public short GetInt16(int position) + { + return (short)GetUInt16(position); + } + + /// + /// Write a int16 at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(short value) + { + return Put((ushort) value); + } + + /// + /// Write a int16 at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, short value) + { + return Put(position, (ushort)value); + } + + + // UInt32 Stuff + + /// + /// Read the next uint32 in the buffer + /// + /// The next uint32 available + public uint GetUInt32() + { + uint value = GetUInt32(Position); + Position += 4; + return value; + } + /// + /// Read the uint32 at the specified position + /// + /// Position to read from + /// The value at the position + public uint GetUInt32(int position) + { + CheckSpaceForReading(position, 4); + byte b1 = ReadByte(position); + byte b2 = ReadByte(position + 1); + byte b3 = ReadByte(position + 2); + byte b4 = ReadByte(position + 3); + return (uint)((b1 << 24) + (b2 << 16) + (b3 << 8) + b4); + } + + /// + /// Write a uint32 at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(uint value) + { + Put(Position, value); + Position += 4; + return this; + } + + /// + /// Write a uint32 at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, uint value) + { + CheckSpaceForWriting(position, 4); + Write(position, (byte)(value >> 24)); + Write(position + 1, (byte)(value >> 16)); + Write(position + 2, (byte)(value >> 8)); + Write(position + 3, (byte)(value)); + return this; + } + + // Int32 Stuff + + /// + /// Read the next int32 in the buffer + /// + /// The next int32 available + public int GetInt32() + { + return (int)GetUInt32(); + } + /// + /// Read the int32 at the specified position + /// + /// Position to read from + /// The value at the position + public int GetInt32(int position) + { + return (int)GetUInt32(position); + } + + /// + /// Write a int32 at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(int value) + { + return Put((uint)value); + } + + /// + /// Write a int32 at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, int value) + { + return Put(position, (uint)value); + } + + // UInt64 Stuff + + /// + /// Read the next uint64 in the buffer + /// + /// The next uint64 available + public ulong GetUInt64() + { + ulong value = GetUInt64(Position); + Position += 8; + return value; + } + /// + /// Read the uint64 at the specified position + /// + /// Position to read from + /// The value at the position + public ulong GetUInt64(int position) + { + CheckSpaceForReading(position, 8); + byte b1 = ReadByte(position); + byte b2 = ReadByte(position + 1); + byte b3 = ReadByte(position + 2); + byte b4 = ReadByte(position + 3); + byte b5 = ReadByte(position + 4); + byte b6 = ReadByte(position + 5); + byte b7 = ReadByte(position + 6); + byte b8 = ReadByte(position + 7); + // all the casts necessary because otherwise each subexpression + // only gets promoted to uint and cause incorrect results + return (((ulong)b1 << 56) + ((ulong)b2 << 48) + ((ulong)b3 << 40) + + ((ulong)b4 << 32) + ((ulong)b5 << 24) + + ((ulong)b6 << 16) + ((ulong)b7 << 8) + b8); + } + + /// + /// Write a uint64 at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(ulong value) + { + Put(Position, value); + Position += 8; + return this; + } + + /// + /// Write a uint64 at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, ulong value) + { + CheckSpaceForWriting(position, 8); + Write(position, (byte)(value >> 56)); + Write(position + 1, (byte)(value >> 48)); + Write(position + 2, (byte)(value >> 40)); + Write(position + 3, (byte)(value >> 32)); + Write(position + 4, (byte)(value >> 24)); + Write(position + 5, (byte)(value >> 16)); + Write(position + 6, (byte)(value >> 8)); + Write(position + 7, (byte)(value)); + return this; + } + + // Int64 Stuff + + /// + /// Read the next int64 in the buffer + /// + /// The next int64 available + public long GetInt64() + { + return (long)GetUInt64(); + } + /// + /// Read the int64 at the specified position + /// + /// Position to read from + /// The value at the position + public long GetInt64(int position) + { + return (long)GetUInt64(position); + } + + /// + /// Write a int64 at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(long value) + { + return Put((ulong)value); + } + + /// + /// Write a int64 at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, long value) + { + return Put(position, (ulong)value); + } + + + // Float Stuff + + /// + /// Read the next float in the buffer + /// + /// The next float available + public float GetFloat() + { + unsafe + { + uint val = GetUInt32(); + return *((float*)&val); + } + } + /// + /// Read the float at the specified position + /// + /// Position to read from + /// The value at the position + public float GetFloat(int position) + { + unsafe + { + uint val = GetUInt32(position); + return *((float*)&val); + } + } + + /// + /// Write a float at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(float value) + { + unsafe + { + uint val = *((uint*)&value); + return Put(val); + } + } + + /// + /// Write a float at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, float value) + { + unsafe + { + uint val = *((uint*)&value); + return Put(position, val); + } + } + + // Double Stuff + + /// + /// Read the next double in the buffer + /// + /// The next double available + public double GetDouble() + { + unsafe + { + ulong val = GetUInt64(); + return *((double*)&val); + } + } + /// + /// Read the double at the specified position + /// + /// Position to read from + /// The value at the position + public double GetDouble(int position) + { + unsafe + { + ulong val = GetUInt64(position); + return *((double*)&val); + } + } + + /// + /// Write a double at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(double value) + { + unsafe + { + ulong val = *((ulong*)&value); + return Put(val); + } + } + + /// + /// Write a double at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, double value) + { + unsafe + { + ulong val = *((ulong*)&value); + return Put(position, val); + } + } + + // Char Stuff + + /// + /// Read the next char in the buffer + /// + /// The next char available + public char GetChar() + { + return (char)GetUInt16(); + } + /// + /// Read the char at the specified position + /// + /// Position to read from + /// The value at the position + public char getChar(int position) + { + return (char)GetUInt16(position); + } + + /// + /// Write a char at the current position + /// + /// Value to write + /// This instance + public ByteBuffer Put(char value) + { + return Put((ushort) value); + } + + /// + /// Write a char at the specified position + /// + /// Position to write to + /// Value to write + /// This instance + public ByteBuffer Put(int position, char value) + { + return Put(position, (ushort)value); + } + + // Byte[] stuff + + public void GetBytes(byte[] buffer) + { + GetBytes(buffer, 0, buffer.Length); + } + + public void GetBytes(byte[] buffer, int offset, int length) + { + GetBytes(Position, buffer, offset, length); + Position += length; + } + public void GetBytes(int position, byte[] buffer, int offset, int length) + { + CheckSpaceForReading(position, length); + if ( offset + length > buffer.Length ) + throw new ArgumentException("Invalid offset + length"); + ReadBytes(position, buffer, offset, length); + } + + public ByteBuffer Put(byte[] buffer) + { + return Put(buffer, 0, buffer.Length); + } + + public ByteBuffer Put(byte[] buffer, int offset, int length) + { + Put(Position, buffer, offset, length); + Position += length; + return this; + } + + public ByteBuffer Put(int position, byte[] buffer, int offset, int length) + { + CheckSpaceForWriting(position, length); + if ( offset + length > buffer.Length ) + throw new ArgumentException("Invalid offset + length"); + + Write(position, buffer, offset, length); + return this; + } + + public ByteBuffer Put(ByteBuffer data) + { + Put(Position, data); + Position += data.Remaining; + return this; + } + + public ByteBuffer Put(int position, ByteBuffer data) + { + CheckSpaceForWriting(position, data.Remaining); + Write(position, data.Array, data.Position, data.Remaining); + return this; + } + + #endregion // Data Accessors + + #region Core Overrides + // + // Core Overrides + // + + protected abstract void DoWrite(int position, byte value); + protected abstract void DoWrite(int position, byte[] src, int offset, int length); + protected abstract byte DoReadByte(int position); + protected abstract void DoReadBytes(int position, byte[] dest, int offset, int length); + protected abstract void DoCompact(); + protected abstract void DoResize(int newSize); + + #endregion // Core Overrides + + #region Private Methods + // + // Private Methods + // + + private void Seek(int offset) + { + if ( offset > Capacity ) + throw new ArgumentException("Cannot position beyond end of buffer"); + _position = offset; + AdjustLimit(); + } + + private void SetLimit(int newLimit) + { + if ( newLimit < 0 ) + throw new ArgumentOutOfRangeException("The new limit must be a positive value"); + if ( newLimit > Capacity ) + throw new ArgumentOutOfRangeException("The new limit must not be greater than the capacity"); + _limit = newLimit; + if ( _position > newLimit ) + _position = newLimit; + } + + private void AdjustLimit() + { + if ( _limit < _position ) + _limit = _position; + } + + private void CheckSpaceForReading(int position, int length) + { + if ( position + length > Limit ) + { + throw new BufferUnderflowException("Attempt to read " + length + " byte(s) to buffer where position is " + _position + + " and limit is " + Limit); + } + } + + private void CheckSpaceForWriting(int position, int length) + { + if ( IsAutoExpand ) + { + Expand(position, length); + } + if ( position + length > Limit ) + { + throw new BufferOverflowException("Attempt to write " + length + " byte(s) to buffer where position is " + _position + + " and limit is " + Limit); + } + } + + private void Write(int position, byte value) + { + DoWrite(position, value); + } + private void Write(int position, byte[] src, int offset, int length) + { + DoWrite(position, src, offset, length); + } + private byte ReadByte(int position) + { + return DoReadByte(position); + } + private void ReadBytes(int position, byte[] dest, int offset, int length) + { + DoReadBytes(position, dest, offset, length); + } + + #endregion // Private Methods + + } // class ByteBuffer } diff --git a/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs index 459abc56ef..bf7c738041 100644 --- a/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs +++ b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs @@ -49,7 +49,7 @@ namespace Qpid.Buffer public static string GetHexDump(ByteBuffer input) { - int size = input.limit() - input.position(); + int size = input.Remaining; if (size == 0) { return "empty"; @@ -57,7 +57,7 @@ namespace Qpid.Buffer StringBuilder output = new StringBuilder(size * 3 - 1); - byte[] data = input.array(); + byte[] data = input.Array; int byteValue = data[0] & 0xFF; output.Append((char) highDigits[byteValue]); output.Append((char) lowDigits[byteValue]); @@ -75,3 +75,4 @@ namespace Qpid.Buffer } } + diff --git a/qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs b/qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs deleted file mode 100644 index 6fc46ab156..0000000000 --- a/qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs +++ /dev/null @@ -1,190 +0,0 @@ -/* - * - * 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. - * - */ -using System; -using System.Text; - -namespace Qpid.Buffer -{ - public class ByteBufferProxy //: ByteBuffer - { - protected ByteBuffer _buf; - - protected ByteBufferProxy(ByteBuffer buf) - { - if (buf == null) - { - throw new ArgumentNullException("buf"); - } - _buf = buf; - } - - -// public /*override*/ void Acquire() -// { -// _buf.Acquire(); -// } -// -// public /*override*/ void Release() -// { -// _buf.Release(); -// } -// -// public /*override*/ int Capacity -// { -// get { return _buf.Capacity; } -// } -// -// public /*override*/ bool IsAutoExpand -// { -// get { return _buf.IsAutoExpand; } -// set { _buf.IsAutoExpand = value; } -// } -// -// public /*override*/ void Expand(int expectedRemaining) -// { -// _buf.Expand(expectedRemaining); -// } -// -// public /*override*/ void Expand(int pos, int expectedRemaining) -// { -// _buf.Expand(pos, expectedRemaining); -// } -// -// public /*override*/ bool Pooled -// { -// get { return _buf.Pooled; } -// set { _buf.Pooled = value; } -// } -// -// public /*override*/ int Position -// { -// get { return _buf.Position; } -// set { _buf.Position = value; } -// } -// -// public /*override*/ int Limit -// { -// get { return _buf.Limit; } -// set { _buf.Limit = value; } -// } -// -// public /*override*/ void Clear() -// { -// _buf.Clear(); -// } -// -// public /*override*/ void Flip() -// { -// _buf.Flip(); -// } -// -// public /*override*/ void Rewind() -// { -// _buf.Rewind(); -// } -// -// public /*override*/ int Remaining -// { -// get { return _buf.Remaining; } -// } -// -// public /*override*/ byte Get() -// { -// return _buf.Get(); -// } -// -// public /*override*/ byte Get(int index) -// { -// return _buf.Get(index); -// } -// -// public /*override*/ void Get(byte[] destination) -// { -// _buf.Get(destination); -// } -// -// public /*override*/ ushort GetUnsignedShort() -// { -// return _buf.GetUnsignedShort(); -// } -// -// public /*override*/ uint GetUnsignedInt() -// { -// return _buf.GetUnsignedInt(); -// } -// -// public /*override*/ ulong GetUnsignedLong() -// { -// return _buf.GetUnsignedLong(); -// } -// -// public /*override*/ string GetString(uint length, Encoding encoder) -// { -// return _buf.GetString(length, encoder); -// } -// -// public /*override*/ void Put(byte data) -// { -// _buf.Put(data); -// } -// -// public /*override*/ void Put(byte[] data, int offset, int size) -// { -// _buf.Put(data, offset, size); -// } -// -// public /*override*/ void Put(byte[] data) -// { -// _buf.Put(data); -// } -// -// public /*override*/ void Put(ushort data) -// { -// _buf.Put(data); -// } -// -// public /*override*/ void Put(uint data) -// { -// _buf.Put(data); -// } -// -// public /*override*/ void Put(ulong data) -// { -// _buf.Put(data); -// } -// -// public /*override*/ void Put(ByteBuffer buf) -// { -// _buf.Put(buf); -// } -// -// public /*override*/ void Compact() -// { -// _buf.Compact(); -// } -// -// public /*override*/ byte[] ToByteArray() -// { -// return _buf.ToByteArray(); -// } - } -} - diff --git a/qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs deleted file mode 100644 index d2f3ca8a3c..0000000000 --- a/qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs +++ /dev/null @@ -1,367 +0,0 @@ -/* - * - * 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. - * - */ -using System; - -namespace Qpid.Buffer -{ - public class FixedByteBuffer - { - private HeapByteBuffer _buf; - - public FixedByteBuffer(int capacity) - { - _buf = new HeapByteBuffer(capacity); - } - - public FixedByteBuffer(byte[] bytes) - { - _buf = HeapByteBuffer.wrap(bytes); - } - - public static FixedByteBuffer wrap(byte[] array) - { - return new FixedByteBuffer(array); - } - - public static FixedByteBuffer wrap(byte[] array, int offset, int length) - { - throw new NotImplementedException(); - } - - public ByteOrder order() - { - return ByteOrder.LittleEndian; - } - - public void order(ByteOrder bo) - { - // Ignore endianess. - } - - public void compact() - { - _buf.Compact(); - } - - public char getChar() - { - throw new NotImplementedException(); - } - - public char getChar(int index) - { - throw new NotImplementedException(); - } - - public void putChar(char value) - { - throw new NotImplementedException(); - } - - public void putChar(int index, char value) - { - throw new NotImplementedException(); - } - - public bool isDirect() - { - return false; - } - - public bool isReadOnly() - { - throw new NotImplementedException(); - } - - public int capacity() - { - return _buf.Capacity; - } - - public int limit() - { - return _buf.Limit; - } - - public int limit(int limit) - { - int previousLimit = _buf.Limit; - _buf.Limit = limit; - return previousLimit; - } - - public int position() - { - return _buf.Position; - } - - public int position(int newPosition) - { - int prev = _buf.Position; - _buf.Position = newPosition; - return prev; - } - - public void mark() - { - throw new NotImplementedException(); - } - - public static FixedByteBuffer allocateDirect(int capacity) - { - throw new NotImplementedException(); - } - - public static FixedByteBuffer allocate(int capacity) - { - return new FixedByteBuffer(capacity); - } - - public void clear() - { - _buf.Clear(); - } - - public void put(byte b) - { - _buf.Put(b); - } - - public void put(int index, byte b) - { - throw new NotImplementedException(); - } - - public void put(FixedByteBuffer buf) - { - _buf.Put(buf.array(), buf.position(), buf.limit() - buf.position()); - } - - public FixedByteBuffer duplicate() - { - throw new NotImplementedException(); - } - - public FixedByteBuffer slice() - { - throw new NotImplementedException(); - } - - public FixedByteBuffer asReadOnlyBuffer() - { - throw new NotImplementedException(); - } - - /// - /// Returns backing array. - /// - /// - public byte[] array() - { - return _buf.array(); - } - - public int arrayOffset() - { - throw new NotImplementedException(); - } - - public void reset() - { - throw new NotImplementedException(); - } - - public void flip() - { - _buf.Flip(); - } - - public void rewind() - { - _buf.Rewind(); - } - - public byte get() - { - return _buf.Get(); - } - - public byte get(int index) - { - throw new NotImplementedException(); - } - - public short getShort() - { - return _buf.GetShort(); - } - - public short getShort(int index) - { - throw new NotImplementedException(); - } - - public void putShort(short value) - { - _buf.Put(value); - } - - public void putShort(int index, short value) - { - throw new NotImplementedException(); - } - - public int getInt() - { - return _buf.GetInt(); - } - - public int getInt(int index) - { - throw new NotImplementedException(); - } - - public void putInt(int value) - { - _buf.Put(value); - } - - public void putInt(int index, int value) - { - throw new NotImplementedException(); - } - - public ByteBuffer get(byte[] dst, int offset, int length) - { - throw new NotImplementedException(); - } - - public ByteBuffer put(byte[] src, int offset, int length) - { - throw new NotImplementedException(); - } - - public long getLong() - { - return _buf.GetLong(); - } - - public long getLong(int index) - { - throw new NotImplementedException(); - } - - public void putLong(long value) - { - _buf.Put(value); - } - - public void putLong(int index, long value) - { - throw new NotImplementedException(); - } - - public int remaining() - { - return _buf.Remaining; - } - - public float getFloat() - { - return _buf.GetFloat(); - } - - public float getFloat(int index) - { - throw new NotImplementedException(); - } - - public void putFloat(float value) - { - _buf.Put(value); - } - - public void putFloat(int index, float value) - { - throw new NotImplementedException(); - } - - public double getDouble() - { - return _buf.GetDouble(); - } - - public double getDouble(int index) - { - throw new NotImplementedException(); - } - - public void putDouble(double value) - { - _buf.Put(value); - } - - public void putDouble(int index, double value) - { - throw new NotImplementedException(); - } - - public ushort getUnsignedShort() - { - return _buf.GetUnsignedShort(); - } - - public uint getUnsignedInt() - { - return _buf.GetUnsignedInt(); - } - - public void get(byte[] dst) - { - _buf.Get(dst); - } - - public void put(ushort value) - { - _buf.Put(value); - } - - public void put(uint max) - { - _buf.Put(max); - } - - public void put(ulong tag) - { - _buf.Put(tag); - } - - public void put(byte[] src) - { - _buf.Put(src); - } - - public ulong getUnsignedLong() - { - return _buf.GetUnsignedLong(); - } - } -} diff --git a/qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs deleted file mode 100644 index f95fe1c241..0000000000 --- a/qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs +++ /dev/null @@ -1,474 +0,0 @@ -/* - * - * 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. - * - */ -using System; -using System.Text; - -namespace Qpid.Buffer -{ - public class HeapByteBuffer //: ByteBuffer - { - private byte[] _underlyingData; - - /// - /// The position of the next value to be read or written - /// - private int _position; - - /// - /// The index of the first element that should not be read or written - /// - private int _limit; - - public HeapByteBuffer(int size) : this(new byte[size], 0) - { - } - - private HeapByteBuffer(byte[] bytes, int length) - { - _underlyingData = bytes; - _limit = bytes.Length; - _position = length; - } - - public /*override*/ int Capacity - { - get - { - return _underlyingData.Length; - } - } - - public /*override*/ int Position - { - get - { - return _position; - } - set - { - _position = value; - } - } - - /// - /// Sets this buffer's limit. If the position is larger than the new limit then it is set to the new limit. - /// - /// The new limit value; must be non-negative and no larger than this buffer's capacity - public /*override*/ int Limit - { - get - { - return _limit; - } - set - { - if (value < 0) - { - throw new ArgumentException("Limit must not be negative"); - } - if (value > Capacity) - { - throw new ArgumentException("Limit must not be greater than Capacity"); - } - _limit = value; - if (_position > value) - { - _position = value; - } - } - } - - /// - /// Returns the number of elements between the current position and the limit - /// - /// The number of elements remaining in this buffer - public /*override*/ int Remaining - { - get - { - return (_limit - _position); - } - } - - public /*override*/ void Clear() - { - _position = 0; - _limit = Capacity; - } - - public /*override*/ void Flip() - { - _limit = _position; - _position = 0; - } - - public /*override*/ void Rewind() - { - _position = 0; - } - - public byte[] array() - { - return _underlyingData; - } - - public /*override*/ byte[] ToByteArray() - { - // Return copy of bytes remaining. - byte[] result = new byte[Remaining]; - Array.Copy(_underlyingData, _position, result, 0, Remaining); - return result; - } - - private void CheckSpace(int size) - { - if (_position + size > _limit) - { - throw new BufferOverflowException("Attempt to write " + size + " byte(s) to buffer where position is " + _position + - " and limit is " + _limit); - } - } - - private void CheckSpaceForReading(int size) - { - if (_position + size > _limit) - { - throw new BufferUnderflowException("Attempt to read " + size + " byte(s) to buffer where position is " + _position + - " and limit is " + _limit); - } - } - - /// - /// Writes the given byte into this buffer at the current position, and then increments the position. - /// - /// The byte to be written - /// If this buffer's current position is not smaller than its limit - public /*override*/ void Put(byte data) - { - CheckSpace(1); - _underlyingData[_position++] = data; - } - - /// - /// Writes all the data in the given byte array into this buffer at the current - /// position and then increments the position. - /// - /// The data to copy. - /// If this buffer's current position plus the array length is not smaller than its limit - public /*override*/ void Put(byte[] data) - { - Put(data, 0, data.Length); - } - - public /*override*/ void Put(byte[] data, int offset, int size) - { - if (data == null) - { - throw new ArgumentNullException("data"); - } - CheckSpace(size); - Array.Copy(data, offset, _underlyingData, _position, size); - _position += size; - } - - /// - /// Writes the given ushort into this buffer at the current position, and then increments the position. - /// - /// The ushort to be written - public /*override*/ void Put(ushort data) - { - CheckSpace(2); - _underlyingData[_position++] = (byte) (data >> 8); - _underlyingData[_position++] = (byte) data; - } - - public /*override*/ void Put(uint data) - { - CheckSpace(4); - _underlyingData[_position++] = (byte) (data >> 24); - _underlyingData[_position++] = (byte) (data >> 16); - _underlyingData[_position++] = (byte) (data >> 8); - _underlyingData[_position++] = (byte) data; - } - - public /*override*/ void Put(ulong data) - { - CheckSpace(8); - _underlyingData[_position++] = (byte) (data >> 56); - _underlyingData[_position++] = (byte) (data >> 48); - _underlyingData[_position++] = (byte) (data >> 40); - _underlyingData[_position++] = (byte) (data >> 32); - _underlyingData[_position++] = (byte) (data >> 24); - _underlyingData[_position++] = (byte) (data >> 16); - _underlyingData[_position++] = (byte) (data >> 8); - _underlyingData[_position++] = (byte) data; - } - - public void Put(short data) - { - Put((ushort)data); - } - - public void Put(int data) - { - Put((uint)data); - } - - public void Put(long data) - { - Put((ulong)data); - } - - public void Put(float data) - { - unsafe - { - uint val = *((uint*)&data); - Put(val); - } - } - - public void Put(double data) - { - unsafe - { - ulong val = *((ulong*)&data); - Put(val); - } - } - - - /// - /// Read the byte at the current position and increment the position - /// - /// a byte - /// if there are no bytes left to read - public /*override*/ byte Get() - { - CheckSpaceForReading(1); - return _underlyingData[_position++]; - } - - /// - /// Reads bytes from the buffer into the supplied array - /// - /// The destination array. The array must not - /// be bigger than the remaining space in the buffer, nor can it be null. - public /*override*/ void Get(byte[] destination) - { - if (destination == null) - { - throw new ArgumentNullException("destination"); - } - int len = destination.Length; - CheckSpaceForReading(len); - Array.Copy(_underlyingData, _position, destination, 0, len); - _position += len; - } - - /// - /// Reads and returns an unsigned short (two bytes, big endian) from this buffer - /// - /// an unsigned short - /// If there are fewer than two bytes remaining in this buffer - public /*override*/ ushort GetUnsignedShort() - { - CheckSpaceForReading(2); - byte upper = _underlyingData[_position++]; - byte lower = _underlyingData[_position++]; - return (ushort) ((upper << 8) + lower); - } - - /// - /// Reads and returns an unsigned int (four bytes, big endian) from this buffer - /// - /// an unsigned integer - /// If there are fewer than four bytes remaining in this buffer - public /*override*/ uint GetUnsignedInt() - { - CheckSpaceForReading(4); - byte b1 = _underlyingData[_position++]; - byte b2 = _underlyingData[_position++]; - byte b3 = _underlyingData[_position++]; - byte b4 = _underlyingData[_position++]; - return (uint) ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4); - } - - public /*override*/ ulong GetUnsignedLong() - { - CheckSpaceForReading(8); - byte b1 = _underlyingData[_position++]; - byte b2 = _underlyingData[_position++]; - byte b3 = _underlyingData[_position++]; - byte b4 = _underlyingData[_position++]; - byte b5 = _underlyingData[_position++]; - byte b6 = _underlyingData[_position++]; - byte b7 = _underlyingData[_position++]; - byte b8 = _underlyingData[_position++]; - // all the casts necessary because otherwise each subexpression - // only gets promoted to uint and cause incorrect results - return (((ulong)b1 << 56) + ((ulong)b2 << 48) + ((ulong)b3 << 40) + - ((ulong)b4 << 32) + ((ulong)b5 << 24) + - ((ulong)b6 << 16) + ((ulong)b7 << 8) + b8); - } - - public short GetShort() - { - return (short) GetUnsignedShort(); - } - - public int GetInt() - { - return (int) GetUnsignedInt(); - } - - public long GetLong() - { - return (long) GetUnsignedLong(); - } - - public float GetFloat() - { - unsafe - { - uint val = GetUnsignedInt(); - return *((float*)&val); - } - } - - public double GetDouble() - { - unsafe - { - ulong val = GetUnsignedLong(); - return *((double*)&val); - } - } - - public /*override*/ string GetString(uint length, Encoding encoder) - { - CheckSpaceForReading((int)length); - string result = encoder.GetString(_underlyingData, _position, (int)length); - _position += (int)length; - return result; - } - - public /*override*/ void Acquire() - { - } - - public /*override*/ void Release() - { - } - - public /*override*/ bool IsAutoExpand - { - get { return false; } - set { } - } - - public /*override*/ void Expand(int expectedRemaining) - { - throw new NotImplementedException(); - } - - public /*override*/ void Expand(int pos, int expectedRemaining) - { - throw new NotImplementedException(); - } - - public /*override*/ bool Pooled - { - get { return false; } - set { } - } - - public void Mark() - { - throw new NotImplementedException(); - } - - public void Reset() - { - throw new NotImplementedException(); - } - - public /*override*/ byte Get(int index) - { - throw new NotImplementedException(); - } - -// public /*override*/ void Put(ByteBuffer src) -// { -// if (src == this) -// { -// throw new ArgumentException("Cannot copy self into self!"); -// } -// -// HeapByteBuffer sb; -// if (src is HeapByteBuffer) -// { -// sb = (HeapByteBuffer) src; -// } -// else -// { -// sb = (HeapByteBuffer)((RefCountingByteBuffer) src).Buf; -// } -// int n = sb.Remaining; -// if (n > Remaining) -// { -// throw new BufferOverflowException("Not enought capacity in this buffer for " + n + " elements - only " + Remaining + " remaining"); -// } -// Array.Copy(sb._underlyingData, sb._position, _underlyingData, _position, n); -// sb._position += n; -// _position += n; -// } - - public /*override*/ void Compact() - { - if (Remaining > 0) - { - if (_position > 0) - { - Array.Copy(_underlyingData, _position, _underlyingData, 0, Remaining); - } - _position = Remaining; - } - else - { - _position = 0; - } - _limit = Capacity; - } - - public static HeapByteBuffer wrap(byte[] bytes, int length) - { - return new HeapByteBuffer(bytes, length); - } - - public static HeapByteBuffer wrap(byte[] bytes) - { - return new HeapByteBuffer(bytes, bytes.Length); - } - } -} - - diff --git a/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs index c7c2f563aa..0cc0811a5c 100644 --- a/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs +++ b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs @@ -19,32 +19,31 @@ * */ +using System; + namespace Qpid.Buffer { /// /// Allocates 's and manages them. Please /// implement this interface if you need more advanced memory management scheme /// - public interface IByteBufferAllocator + public interface IByteBufferAllocator : IDisposable { /// /// Returns the buffer which is capable of the specified size. /// /// The capacity of the buffer - /// true to get a direct buffer, false to get a heap buffer - ByteBuffer Allocate(int capacity, bool direct); + /// A new buffer + ByteBuffer Allocate(int capacity); /// - /// Wraps the specified buffer + /// Wrap the specified byte array in a new buffer /// - /// fixed byte buffer - /// The wrapped buffer - ByteBuffer Wrap(FixedByteBuffer nioBuffer); + /// Source array + /// A new buffer + ByteBuffer Wrap(byte[] src); + + } // interface IByteBufferAllocator +} - /// - /// Dispose of this allocator. - /// - void Dispose(); - } -} \ No newline at end of file diff --git a/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj index e6bade037b..a03bf348b2 100644 --- a/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj +++ b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj @@ -38,18 +38,15 @@ - - - - - + +