diff options
| author | Robert Greig <rgreig@apache.org> | 2007-02-26 17:46:07 +0000 |
|---|---|---|
| committer | Robert Greig <rgreig@apache.org> | 2007-02-26 17:46:07 +0000 |
| commit | 3bfaba7fd65f251b68e8c4085582a4b62edf8e5d (patch) | |
| tree | 6e90ae3729802623450af664e0a39a52f5f1b3f3 | |
| parent | 2ea003c24ab3170dec118af6f9f8c128241cec65 (diff) | |
| download | qpid-python-3bfaba7fd65f251b68e8c4085582a4b62edf8e5d.tar.gz | |
(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/qpid@511923 13f79535-47bb-0310-9956-ffa450edef68
46 files changed, 2295 insertions, 4677 deletions
diff --git a/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs b/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..d97f8278b5 --- /dev/null +++ b/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/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj b/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj new file mode 100644 index 0000000000..ac9e2f5229 --- /dev/null +++ b/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj @@ -0,0 +1,59 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{74640962-99D0-4D06-B57A-9CD66517CF52}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Qpid.Buffer.Tests</RootNamespace>
+ <AssemblyName>Qpid.Buffer.Tests</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>true</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Client.Tests\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SlicedByteBufferTests.cs" />
+ <Compile Include="SimpleByteBufferTests.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs b/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs new file mode 100644 index 0000000000..290e908a0d --- /dev/null +++ b/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
+{
+ /// <summary>
+ /// Tests for the SimpleByteBuffer class
+ /// </summary>
+ [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/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs b/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs new file mode 100644 index 0000000000..07c7e14a48 --- /dev/null +++ b/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
+{
+ /// <summary>
+ /// Tests for the SlicedByteBuffer class
+ /// </summary>
+ [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/dotnet/Qpid.Buffer/BaseByteBuffer.cs b/dotnet/Qpid.Buffer/BaseByteBuffer.cs deleted file mode 100644 index 3a6beabae8..0000000000 --- a/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 -{ - /// <summary> - /// A base implementation of <see cref="ByteBuffer"/>. This implementation - /// assumes that <see cref="ByteBuffer.Buf"/> always returns a correct NIO - /// <see cref="FixedByteBuffer"/> instance. Most implementations could - /// extend this class and implement their own buffer management mechanism. - /// </summary> - /// <seealso cref="ByteBufferAllocator"/> - public abstract class BaseByteBuffer : ByteBuffer - { - private bool _autoExpand; - - /// <summary> - /// We don't have any access to Buffer.markValue(), - /// so we need to track it down, which will cause small extra overhead. - /// </summary> - 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; - } - - - /// <summary> - /// Implement this method to increase the capacity of this buffer. - /// </summary> - /// <param name="newCapacity">is always greater than the current capacity.</param> - 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/dotnet/Qpid.Buffer/BufferDataException.cs b/dotnet/Qpid.Buffer/BufferDataException.cs deleted file mode 100644 index c76441dde0..0000000000 --- a/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 -{ - /// <summary> - /// An exception thrown when the data the <see cref="ByteBuffer"/> - /// contains is corrupt - /// </summary> - [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/dotnet/Qpid.Buffer/ByteBuffer.cs b/dotnet/Qpid.Buffer/ByteBuffer.cs index 1a4f0072d6..1bfc749746 100644 --- a/dotnet/Qpid.Buffer/ByteBuffer.cs +++ b/dotnet/Qpid.Buffer/ByteBuffer.cs @@ -19,2367 +19,964 @@ * */ using System; -using System.Text; namespace Qpid.Buffer { - public enum ByteOrder { BigEndian, LittleEndian } -// /// <summary> -// /// A buffer that manages an underlying byte oriented stream, and writes and reads to and from it in -// /// BIG ENDIAN order. -// /// </summary> -// 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() -// }; -// -// /// <summary> -// /// 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. -// /// </summary> -// /// <param name="capacity">The capacity.</param> -// /// <returns></returns> -// 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; -// } -// -// /// <summary> -// /// 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. -// /// </summary> -// public abstract void Acquire(); -// -// /// <summary> -// /// Releases the specified buffer to the buffer pool. -// /// </summary> -// public abstract void Release(); -// -// public abstract int Capacity -// { -// get; -// } -// -// public abstract bool IsAutoExpand -// { -// get; -// set; -// } -// -// /// <summary> -// /// 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. -// /// </summary> -// /// <param name="expectedRemaining">Room you want from the current position</param> -// public abstract void Expand(int expectedRemaining); -// -// /// <summary> -// /// Changes the capacity and limit of this buffer sot his buffer gets the specified -// /// expectedRemaining room from the specified position. -// /// </summary> -// /// <param name="pos">The pos you want the room to be available from.</param> -// /// <param name="expectedRemaining">The expected room you want available.</param> -// public abstract void Expand(int pos, int expectedRemaining); -// -// /// <summary> -// /// Returns true if and only if this buffer is returned back to the buffer pool when released. -// /// </summary> -// /// <value><c>true</c> if pooled; otherwise, <c>false</c>.</value> -// 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(); -// -// /// <summary> -// /// 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. -// /// </summary> -// 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); -// } -// } -// -// /// <summary> -// /// Fills the buffer with the specified specified value. This method moves the buffer position forward. -// /// </summary> -// /// <param name="value">The value.</param> -// /// <param name="size">The size.</param> -// 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. - * <p> - * 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: - * <ul> - * <li>It doesn't provide useful getters and putters such as - * <code>fill</code>, <code>get/putString</code>, and - * <code>get/putAsciiInt()</code> enough.</li> - * <li>It is hard to distinguish if the buffer is created from MINA buffer - * pool or not. MINA have to return used buffers back to pool.</li> - * <li>It is difficult to write variable-length data due to its fixed - * capacity</li> - * </ul> - * </p> - * - * <h2>Allocation</h2> - * <p> - * You can get a heap buffer from buffer pool: - * <pre> - * ByteBuffer buf = ByteBuffer.allocate(1024, false); - * </pre> - * you can also get a direct buffer from buffer pool: - * <pre> - * ByteBuffer buf = ByteBuffer.allocate(1024, true); - * </pre> - * or you can let MINA choose: - * <pre> - * ByteBuffer buf = ByteBuffer.allocate(1024); - * </pre> - * </p> - * - * <h2>Acquire/Release</h2> - * <p> - * <b>Please note that you never need to release the allocated buffer</b> - * because MINA will release it automatically when: - * <ul> - * <li>You pass the buffer by calling {@link IoSession#write(Object)}.</li> - * <li>You pass the buffer by calling {@link IoFilter.NextFilter#filterWrite(IoSession,IoFilter.WriteRequest)}.</li> - * <li>You pass the buffer by calling {@link ProtocolEncoderOutput#write(ByteBuffer)}.</li> - * </ul> - * 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. - * <p> - * You have to release buffers manually by calling {@link #release()} when: - * <ul> - * <li>You allocated a buffer, but didn't pass the buffer to any of two methods above.</li> - * <li>You called {@link #acquire()} to prevent the buffer from being released.</li> - * </ul> - * </p> - * - * <h2>Wrapping existing NIO buffers and arrays</h2> - * <p> - * This class provides a few <tt>wrap(...)</tt> 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 <tt>true</tt> flag to enable pooling. - * - * <h2>AutoExpand</h2> - * <p> - * Writing variable-length data using NIO <tt>ByteBuffers</tt> is not really - * easy, and it is because its size is fixed. MINA <tt>ByteBuffer</tt> - * introduces <tt>autoExpand</tt> property. If <tt>autoExpand</tt> 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: - * <pre> - * 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 ); - * </pre> - * NIO <tt>ByteBuffer</tt> is reallocated by MINA <tt>ByteBuffer</tt> 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. - * </p> - * - * <h2>Derived Buffers</h2> - * <p> - * 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}. - * </p> - * - * <h2>Changing Buffer Allocation and Management Policy</h2> - * <p> - * MINA provides a {@link ByteBufferAllocator} interface to let you override - * the default buffer management behavior. There are two allocators provided - * out-of-the-box: - * <ul> - * <li>{@link PooledByteBufferAllocator} (Default)</li> - * <li>{@link SimpleByteBufferAllocator}</li> - * </ul> - * You can change the allocator by calling {@link #setAllocator(ByteBufferAllocator)}. - * </p> - * - * @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 <tt>true</tt> to get a direct buffer, - * <tt>false</tt> 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 <tt>offset</tt> and <tt>length</tt>. - */ - 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 <tt>true</tt> if and only if <tt>autoExpand</tt> is turned on. - */ - public abstract bool isAutoExpand(); - - /** - * Turns on or off <tt>autoExpand</tt>. - */ - public abstract ByteBuffer setAutoExpand( bool autoExpand ); - - /** - * Changes the capacity and limit of this buffer so this buffer get - * the specified <tt>expectedRemaining</tt> room from the current position. - * This method works even if you didn't set <tt>autoExpand</tt> to - * <tt>true</tt>. - */ - public ByteBuffer expand( int expectedRemaining ) - { - return expand( position(), expectedRemaining ); - } - - /** - * Changes the capacity and limit of this buffer so this buffer get - * the specified <tt>expectedRemaining</tt> room from the specified - * <tt>pos</tt>. - * This method works even if you didn't set <tt>autoExpand</tt> to - * <tt>true</tt>. - */ - public abstract ByteBuffer expand( int pos, int expectedRemaining ); - - /** - * Returns <tt>true</tt> if and only if this buffer is returned back - * to the buffer pool when released. - * <p> - * The default value of this property is <tt>true</tt> if and only if you - * allocated this buffer using {@link #allocate(int)} or {@link #allocate(int, bool)}, - * or <tt>false</tt> 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. - * <p> - * The default value of this property is <tt>true</tt> if and only if you - * allocated this buffer using {@link #allocate(int)} or {@link #allocate(int, bool)}, - * or <tt>false</tt> 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 <tt>-1</tt> 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 <tt>NUL</tt>. - * 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 <tt>value</tt>. - * 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 <tt>src</tt> into this buffer. - */ - public abstract ByteBuffer put( FixedByteBuffer src ); - - /** - * Writes the content of the specified <tt>src</tt> 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 <tt>-1</tt> 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 <tt>autoExpand</tt> 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 <code>NUL</code>-terminated string from this buffer using the - * specified <code>decoder</code> and returns it. This method reads - * until the limit of this buffer if no <tt>NUL</tt> 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 <code>NUL</code>-terminated string from this buffer using the - * specified <code>decoder</code> 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 <code>in</code> into this buffer using the - * specified <code>encoder</code>. This method doesn't terminate - * string with <tt>NUL</tt>. 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 <code>in</code> into this buffer as a - * <code>NUL</code>-terminated string using the specified - * <code>encoder</code>. - * <p> - * If the charset name of the encoder is UTF-16, you cannot specify - * odd <code>fieldSize</code>, and this method will Append two - * <code>NUL</code>s as a terminator. - * <p> - * Please note that this method doesn't terminate with <code>NUL</code> - * if the input string is longer than <tt>fieldSize</tt>. - * - * @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 <code>decoder</code> and returns it. - * This method is a shortcut for <tt>getPrefixedString(2, decoder)</tt>. - */ -// 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 <code>decoder</code> 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 <code>in</code> into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified <code>encoder</code>. - * This method is a shortcut for <tt>putPrefixedString(in, 2, 0, encoder)</tt>. - * - * @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 <code>in</code> into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified <code>encoder</code>. - * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, 0, encoder)</tt>. - * - * @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 <code>in</code> into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified <code>encoder</code>. - * This method is a shortcut for <tt>putPrefixedString(in, prefixLength, padding, ( byte ) 0, encoder)</tt>. - * - * @param prefixLength the length of the length field (1, 2, or 4) - * @param padding the number of padded <tt>NUL</tt>s (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 <code>in</code> into this buffer as a - * string which has a 16-bit length field before the actual - * encoded string, using the specified <code>encoder</code>. - * - * @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 <tt>classLoader</tt>. - */ -// 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 <tt>true</tt> 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 - * <tt>prefixedDataAvailable( prefixLength, Integer.MAX_VALUE )</tt>. - * 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 <tt>true</tt> 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 <tt>maxDataLength</tt> - */ - 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 <code>size</code> - * 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 <code>NUL (0x00)</code>. - * 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 <code>NUL (0x00)</code>. - * 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 - * <tt>autoExpand</tt> property is <tt>true</tt>. - */ - protected ByteBuffer autoExpand( int expectedRemaining ) - { - if( isAutoExpand() ) - { - expand( expectedRemaining ); - } - return this; - } - - /** - * This method forwards the call to {@link #expand(int)} only when - * <tt>autoExpand</tt> property is <tt>true</tt>. - */ - 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(); - } + /// <summary> + /// Abstract class implementing a byte buffer + /// </summary> + public abstract class ByteBuffer + { + private int _position; + private int _limit; + private bool _isAutoExpand; + private static IByteBufferAllocator _allocator = + new SimpleByteBufferAllocator(); + + #region Properties + // + // Properties + // + + /// <summary> + /// The maximum number of bytes the buffer can hold + /// </summary> + public abstract int Capacity + { + get; + } + + /// <summary> + /// Return the backing array of this buffer + /// </summary> + public abstract byte[] Array + { + get; + } + + /// <summary> + /// The current position inside this buffer + /// </summary> + public int Position + { + get { return _position; } + set { Seek(value); } + } + + /// <summary> + /// 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. + /// </summary> + public int Limit + { + get { return _limit; } + set { SetLimit(value); } + } + + /// <summary> + /// Number of bytes remaining in the buffer from the current position + /// </summary> + public int Remaining + { + get { return Limit - Position; } + } + + /// <summary> + /// True if there are bytes remaining in the buffer + /// </summary> + public bool HasRemaining + { + get { return Remaining > 0; } + } + + /// <summary> + /// If true, the buffer will be resized as necessary + /// to allow space for writing. By default is false. + /// </summary> + public bool IsAutoExpand + { + get { return _isAutoExpand; } + set { _isAutoExpand = value; } + } + + #endregion // Properties + + #region Buffer Manipulation + // + // Buffer Manipulation + // + + /// <summary> + /// Move the buffer to Position 0 + /// </summary> + /// <returns>This instance</returns> + public ByteBuffer Rewind() + { + Seek(0); + return this; + } + + /// <summary> + /// Prepare the buffer to read back what's been written + /// </summary> + /// <returns>This instance</returns> + public ByteBuffer Flip() + { + Limit = Position; + Position = 0; + return this; + } + + /// <summary> + /// Compact this buffer. + /// </summary> + /// <returns>This instance</returns> + /// <remarks> + /// The bytes between the buffer's current position and its limit, if any, + /// are copied to the beginning of the buffer. + /// </remarks> + public ByteBuffer Compact() + { + DoCompact(); + return this; + } + + /// <summary> + /// Clears this buffer. The position is set to zero, the limit is set to the capacity + /// </summary> + /// <returns>This instance</returns> + public ByteBuffer Clear() + { + Limit = Capacity; + Position = 0; + return this; + } + + /// <summary> + /// Expands this buffer's capacity so that + /// Remaining == expectedRemaining + /// </summary> + /// <param name="expectedRemaining">Number of bytes that should be accessable after resizing</param> + /// <returns>This instance</returns> + public ByteBuffer Expand(int expectedRemaining) + { + return Expand(Position, expectedRemaining); + } + + /// <summary> + /// Expands this buffer's capacity so that + /// Remaining == expectedRemaining + /// </summary> + /// <param name="position">Position from which to start the resize</param> + /// <param name="expectedRemaining">Number of bytes that should be accessable after resizing</param> + /// <returns>This instance</returns> + 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; + } + + /// <summary> + /// Creates a new byte buffer whose content is a shared + /// subsequence of this buffer's content. + /// </summary> + /// <remarks> + /// 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. + /// <para> + /// The new buffer's position will be zero, its capacity and its limit will + /// be the number of bytes remaining in this buffer. + /// </para> + /// </remarks> + /// <returns>A view on top of this instance</returns> + public ByteBuffer Slice() + { + return new SlicedByteBuffer(this); + } + + /// <summary> + /// Skip the specified number of bytes + /// </summary> + /// <param name="numBytes">Number of bytes to move forward by</param> + /// <returns>This instance</returns> + public ByteBuffer Skip(int numBytes) + { + Position += numBytes; + return this; + } + + /// <summary> + /// Acquire this buffer to keep it alive. + /// </summary> + public virtual void Acquire() + { + // override in subclass if supported + } + + /// <summary> + /// Release this buffer instance + /// </summary> + public virtual void Release() + { + // override in subclass if supported + } + + /// <summary> + /// Return a string with a Hex Dump of this buffer's contents + /// </summary> + /// <returns>The hex dump</returns> + public string GetHexDump() + { + return ByteBufferHexDumper.GetHexDump(this); + } + + public override string ToString() + { + return GetHexDump(); + } + #endregion // Buffer Manipulation + + #region Static Operations + // + // Static Operations + // + /// <summary> + /// Replaces the default allocator with your own implementation + /// </summary> + /// <param name="allocator">New allocator</param> + public static void SetAllocator(IByteBufferAllocator allocator) + { + if ( allocator == null ) + throw new ArgumentNullException("allocator"); + _allocator = allocator; + } + + /// <summary> + /// Allocate a new buffer with the specified capacity + /// using the default allocator + /// </summary> + /// <param name="capacity">Desired capacity</param> + /// <returns>The new buffer</returns> + public static ByteBuffer Allocate(int capacity) + { + return _allocator.Allocate(capacity); + } + + /// <summary> + /// Wraps the specified arrat into a new buffer + /// </summary> + /// <param name="buffer"></param> + /// <returns></returns> + public static ByteBuffer Wrap(byte[] buffer) + { + return _allocator.Wrap(buffer); + } + #endregion // Static Operations + + #region Data Accessors + // + // Data Accessors + // + + // Byte Stuff + + /// <summary> + /// Read the next byte in the buffer + /// </summary> + /// <returns>The next byte available</returns> + public byte GetByte() + { + byte value = GetByte(Position); + Position += 1; + return value; + } + /// <summary> + /// Read the byte at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public byte GetByte(int position) + { + CheckSpaceForReading(position, 1); + return ReadByte(position); + } + /// <summary> + /// Write a byte at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(byte value) + { + Put(Position, value); + Position++; + return this; + } + /// <summary> + /// Write a byte at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, byte value) + { + CheckSpaceForWriting(position, 1); + Write(position, value); + return this; + } + + // SByte Stuff + + /// <summary> + /// Read the next signed byte in the buffer + /// </summary> + /// <returns>The next signed byte available</returns> + public sbyte GetSByte() + { + sbyte value = GetSByte(Position); + Position += 1; + return value; + } + /// <summary> + /// Read the signed byte at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public sbyte GetSByte(int position) + { + CheckSpaceForReading(position, 1); + return (sbyte)ReadByte(position); + } + + /// <summary> + /// Write a signed byte at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(sbyte value) + { + Put(Position, value); + Position += 1; + return this; + } + + /// <summary> + /// Write a signed byte at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, sbyte value) + { + CheckSpaceForWriting(position, 1); + Write(position, (byte)value); + return this; + } + + // UInt16 Stuff + + /// <summary> + /// Read the next uint16 in the buffer + /// </summary> + /// <returns>The next uint16 available</returns> + public ushort GetUInt16() + { + ushort value = GetUInt16(Position); + Position += 2; + return value; + } + /// <summary> + /// Read the uint16 at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public ushort GetUInt16(int position) + { + CheckSpaceForReading(position, 2); + byte upper = ReadByte(position); + byte lower = ReadByte(position+1); + return (ushort)(((ushort)upper << 8) + lower); + } + + /// <summary> + /// Write a uint16 at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(ushort value) + { + Put(Position, value); + Position += 2; + return this; + } + + /// <summary> + /// Write a uint16 at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, ushort value) + { + CheckSpaceForWriting(position, 2); + Write(position, (byte)(value >> 8)); + Write(position+1, (byte)(value)); + return this; + } + + // Int16 Stuff + + /// <summary> + /// Read the next int16 in the buffer + /// </summary> + /// <returns>The next int16 available</returns> + public short GetInt16() + { + return (short) GetUInt16(); + } + /// <summary> + /// Read the int16 at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public short GetInt16(int position) + { + return (short)GetUInt16(position); + } + + /// <summary> + /// Write a int16 at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(short value) + { + return Put((ushort) value); + } + + /// <summary> + /// Write a int16 at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, short value) + { + return Put(position, (ushort)value); + } + + + // UInt32 Stuff + + /// <summary> + /// Read the next uint32 in the buffer + /// </summary> + /// <returns>The next uint32 available</returns> + public uint GetUInt32() + { + uint value = GetUInt32(Position); + Position += 4; + return value; + } + /// <summary> + /// Read the uint32 at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + 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); + } + + /// <summary> + /// Write a uint32 at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(uint value) + { + Put(Position, value); + Position += 4; + return this; + } + + /// <summary> + /// Write a uint32 at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + 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 + + /// <summary> + /// Read the next int32 in the buffer + /// </summary> + /// <returns>The next int32 available</returns> + public int GetInt32() + { + return (int)GetUInt32(); + } + /// <summary> + /// Read the int32 at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public int GetInt32(int position) + { + return (int)GetUInt32(position); + } + + /// <summary> + /// Write a int32 at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int value) + { + return Put((uint)value); + } + + /// <summary> + /// Write a int32 at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, int value) + { + return Put(position, (uint)value); + } + + // UInt64 Stuff + + /// <summary> + /// Read the next uint64 in the buffer + /// </summary> + /// <returns>The next uint64 available</returns> + public ulong GetUInt64() + { + ulong value = GetUInt64(Position); + Position += 8; + return value; + } + /// <summary> + /// Read the uint64 at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + 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); + } + + /// <summary> + /// Write a uint64 at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(ulong value) + { + Put(Position, value); + Position += 8; + return this; + } + + /// <summary> + /// Write a uint64 at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + 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 + + /// <summary> + /// Read the next int64 in the buffer + /// </summary> + /// <returns>The next int64 available</returns> + public long GetInt64() + { + return (long)GetUInt64(); + } + /// <summary> + /// Read the int64 at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public long GetInt64(int position) + { + return (long)GetUInt64(position); + } + + /// <summary> + /// Write a int64 at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(long value) + { + return Put((ulong)value); + } + + /// <summary> + /// Write a int64 at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, long value) + { + return Put(position, (ulong)value); + } + + + // Float Stuff + + /// <summary> + /// Read the next float in the buffer + /// </summary> + /// <returns>The next float available</returns> + public float GetFloat() + { + unsafe + { + uint val = GetUInt32(); + return *((float*)&val); + } + } + /// <summary> + /// Read the float at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public float GetFloat(int position) + { + unsafe + { + uint val = GetUInt32(position); + return *((float*)&val); + } + } + + /// <summary> + /// Write a float at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(float value) + { + unsafe + { + uint val = *((uint*)&value); + return Put(val); + } + } + + /// <summary> + /// Write a float at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, float value) + { + unsafe + { + uint val = *((uint*)&value); + return Put(position, val); + } + } + + // Double Stuff + + /// <summary> + /// Read the next double in the buffer + /// </summary> + /// <returns>The next double available</returns> + public double GetDouble() + { + unsafe + { + ulong val = GetUInt64(); + return *((double*)&val); + } + } + /// <summary> + /// Read the double at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public double GetDouble(int position) + { + unsafe + { + ulong val = GetUInt64(position); + return *((double*)&val); + } + } + + /// <summary> + /// Write a double at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(double value) + { + unsafe + { + ulong val = *((ulong*)&value); + return Put(val); + } + } + + /// <summary> + /// Write a double at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(int position, double value) + { + unsafe + { + ulong val = *((ulong*)&value); + return Put(position, val); + } + } + + // Char Stuff + + /// <summary> + /// Read the next char in the buffer + /// </summary> + /// <returns>The next char available</returns> + public char GetChar() + { + return (char)GetUInt16(); + } + /// <summary> + /// Read the char at the specified position + /// </summary> + /// <param name="position">Position to read from</param> + /// <returns>The value at the position</returns> + public char getChar(int position) + { + return (char)GetUInt16(position); + } + + /// <summary> + /// Write a char at the current position + /// </summary> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + public ByteBuffer Put(char value) + { + return Put((ushort) value); + } + + /// <summary> + /// Write a char at the specified position + /// </summary> + /// <param name="position">Position to write to</param> + /// <param name="value">Value to write</param> + /// <returns>This instance</returns> + 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/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs b/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs index 459abc56ef..bf7c738041 100644 --- a/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs +++ b/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/dotnet/Qpid.Buffer/ByteBufferProxy.cs b/dotnet/Qpid.Buffer/ByteBufferProxy.cs deleted file mode 100644 index 6fc46ab156..0000000000 --- a/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/dotnet/Qpid.Buffer/FixedByteBuffer.cs b/dotnet/Qpid.Buffer/FixedByteBuffer.cs deleted file mode 100644 index d2f3ca8a3c..0000000000 --- a/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(); - } - - /// <summary> - /// Returns backing array. - /// </summary> - /// <returns></returns> - 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/dotnet/Qpid.Buffer/HeapByteBuffer.cs b/dotnet/Qpid.Buffer/HeapByteBuffer.cs deleted file mode 100644 index f95fe1c241..0000000000 --- a/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; - - /// <summary> - /// The position of the next value to be read or written - /// </summary> - private int _position; - - /// <summary> - /// The index of the first element that should not be read or written - /// </summary> - 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; - } - } - - /// <summary> - /// Sets this buffer's limit. If the position is larger than the new limit then it is set to the new limit. - /// </summary> - /// <value>The new limit value; must be non-negative and no larger than this buffer's capacity</value> - 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; - } - } - } - - /// <summary> - /// Returns the number of elements between the current position and the limit - /// </summary> - /// <value>The number of elements remaining in this buffer</value> - 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); - } - } - - /// <summary> - /// Writes the given byte into this buffer at the current position, and then increments the position. - /// </summary> - /// <param name="data">The byte to be written</param> - /// <exception cref="BufferOverflowException">If this buffer's current position is not smaller than its limit</exception> - public /*override*/ void Put(byte data) - { - CheckSpace(1); - _underlyingData[_position++] = data; - } - - /// <summary> - /// Writes all the data in the given byte array into this buffer at the current - /// position and then increments the position. - /// </summary> - /// <param name="data">The data to copy.</param> - /// <exception cref="BufferOverflowException">If this buffer's current position plus the array length is not smaller than its limit</exception> - 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; - } - - /// <summary> - /// Writes the given ushort into this buffer at the current position, and then increments the position. - /// </summary> - /// <param name="data">The ushort to be written</param> - 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); - } - } - - - /// <summary> - /// Read the byte at the current position and increment the position - /// </summary> - /// <returns>a byte</returns> - /// <exception cref="BufferUnderflowException">if there are no bytes left to read</exception> - public /*override*/ byte Get() - { - CheckSpaceForReading(1); - return _underlyingData[_position++]; - } - - /// <summary> - /// Reads bytes from the buffer into the supplied array - /// </summary> - /// <param name="destination">The destination array. The array must not - /// be bigger than the remaining space in the buffer, nor can it be null.</param> - 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; - } - - /// <summary> - /// Reads and returns an unsigned short (two bytes, big endian) from this buffer - /// </summary> - /// <returns>an unsigned short</returns> - /// <exception cref="BufferUnderflowException">If there are fewer than two bytes remaining in this buffer</exception> - public /*override*/ ushort GetUnsignedShort() - { - CheckSpaceForReading(2); - byte upper = _underlyingData[_position++]; - byte lower = _underlyingData[_position++]; - return (ushort) ((upper << 8) + lower); - } - - /// <summary> - /// Reads and returns an unsigned int (four bytes, big endian) from this buffer - /// </summary> - /// <returns>an unsigned integer</returns> - /// <exception cref="BufferUnderflowException">If there are fewer than four bytes remaining in this buffer</exception> - 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/dotnet/Qpid.Buffer/IByteBufferAllocator.cs b/dotnet/Qpid.Buffer/IByteBufferAllocator.cs index c7c2f563aa..0cc0811a5c 100644 --- a/dotnet/Qpid.Buffer/IByteBufferAllocator.cs +++ b/dotnet/Qpid.Buffer/IByteBufferAllocator.cs @@ -19,32 +19,31 @@ *
*/
+using System;
+
namespace Qpid.Buffer
{
/// <summary>
/// Allocates <see cref="ByteBuffer"/>'s and manages them. Please
/// implement this interface if you need more advanced memory management scheme
/// </summary>
- public interface IByteBufferAllocator
+ public interface IByteBufferAllocator : IDisposable
{
/// <summary>
/// Returns the buffer which is capable of the specified size.
/// </summary>
/// <param name="capacity">The capacity of the buffer</param>
- /// <param name="direct">true to get a direct buffer, false to get a heap buffer</param>
- ByteBuffer Allocate(int capacity, bool direct);
+ /// <returns>A new buffer</returns>
+ ByteBuffer Allocate(int capacity);
/// <summary>
- /// Wraps the specified buffer
+ /// Wrap the specified byte array in a new buffer
/// </summary>
- /// <param name="nioBuffer">fixed byte buffer</param>
- /// <returns>The wrapped buffer</returns>
- ByteBuffer Wrap(FixedByteBuffer nioBuffer);
+ /// <param name="src">Source array</param>
+ /// <returns>A new buffer</returns>
+ ByteBuffer Wrap(byte[] src);
+
+ } // interface IByteBufferAllocator
+}
- /// <summary>
- /// Dispose of this allocator.
- /// </summary>
- void Dispose();
- }
-}
\ No newline at end of file diff --git a/dotnet/Qpid.Buffer/Qpid.Buffer.csproj b/dotnet/Qpid.Buffer/Qpid.Buffer.csproj index e6bade037b..a03bf348b2 100644 --- a/dotnet/Qpid.Buffer/Qpid.Buffer.csproj +++ b/dotnet/Qpid.Buffer/Qpid.Buffer.csproj @@ -38,18 +38,15 @@ <Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
- <Compile Include="BaseByteBuffer.cs" />
- <Compile Include="BufferDataException.cs" />
<Compile Include="BufferOverflowException.cs" />
<Compile Include="BufferUnderflowException.cs" />
<Compile Include="ByteBuffer.cs" />
<Compile Include="ByteBufferHexDumper.cs" />
- <Compile Include="ByteBufferProxy.cs" />
- <Compile Include="FixedByteBuffer.cs" />
- <Compile Include="HeapByteBuffer.cs" />
<Compile Include="IByteBufferAllocator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SimpleByteBuffer.cs" />
<Compile Include="SimpleByteBufferAllocator.cs" />
+ <Compile Include="SlicedByteBuffer.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/dotnet/Qpid.Buffer/SimpleByteBuffer.cs b/dotnet/Qpid.Buffer/SimpleByteBuffer.cs new file mode 100644 index 0000000000..d91f7747d2 --- /dev/null +++ b/dotnet/Qpid.Buffer/SimpleByteBuffer.cs @@ -0,0 +1,120 @@ +/*
+ *
+ * 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
+{
+ internal sealed class SimpleByteBuffer : ByteBuffer
+ {
+ private byte[] _buffer;
+
+ public override int Capacity
+ {
+ get { return _buffer.Length; }
+ }
+
+ public override byte[] Array
+ {
+ get { return _buffer; }
+ }
+
+ /// <summary>
+ /// Initialize a new instance with the desired size
+ /// </summary>
+ /// <param name="desiredSize">Initial Length of the array</param>
+ internal SimpleByteBuffer(int desiredSize)
+ {
+ _buffer = new byte[desiredSize];
+ Position = 0;
+ Limit = Capacity;
+ }
+
+ /// <summary>
+ /// Initialize a new instance with the data from
+ /// an underlying array
+ /// </summary>
+ /// <param name="buffer">Initial data</param>
+ /// <remarks>The original array is copied during construction and is not modified</remarks>
+ internal SimpleByteBuffer(byte[] buffer)
+ {
+ _buffer = (byte[])buffer.Clone();
+ // position at end
+ Position = Limit = Capacity;
+ }
+
+ protected override void DoWrite(int position, byte value)
+ {
+ // available space is already handled by base class
+ _buffer[position] = value;
+ }
+
+ protected override void DoWrite(int position, byte[] src, int offset, int length)
+ {
+ // available space is already handled by base class
+ for ( int i = 0; i < length; i++ )
+ {
+ _buffer[position+i] = src[offset+i];
+ }
+ }
+
+ protected override byte DoReadByte(int position)
+ {
+ return _buffer[position];
+ }
+
+ protected override void DoReadBytes(int position, byte[] dest, int offset, int length)
+ {
+ System.Array.Copy(_buffer, position, dest, offset, length);
+ }
+
+ protected override void DoCompact()
+ {
+ if ( Remaining > 0 )
+ {
+ if ( Position > 0 )
+ {
+ System.Array.Copy(_buffer, Position, _buffer, 0, Remaining);
+ }
+ Position = Remaining;
+ } else
+ {
+ Position = 0;
+ }
+ Limit = Capacity;
+ }
+
+ protected override void DoResize(int newSize)
+ {
+ if ( newSize < Capacity )
+ throw new NotSupportedException("Cannot resize a buffer to make it smaller");
+
+ int newCapacity = 1;
+ while ( newCapacity < newSize )
+ {
+ newCapacity <<= 1;
+ }
+
+ byte[] newBuffer = new byte[newCapacity];
+ System.Array.Copy(_buffer, newBuffer, _buffer.Length);
+ _buffer = newBuffer;
+ }
+ } // class SimpleByteBuffer
+}
diff --git a/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs b/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs index 2de3a13560..6933480c92 100644 --- a/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs +++ b/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs @@ -18,171 +18,40 @@ * under the License. * */ -using System; -using System.Runtime.CompilerServices; namespace Qpid.Buffer { - /// <summary> - /// A simplistic <see cref="ByteBufferAllocator"/> which simply allocates a new - /// buffer every time - /// </summary> - public class SimpleByteBufferAllocator : IByteBufferAllocator - { - private const int MINIMUM_CAPACITY = 1; + /// <summary> + /// Allocates <see cref="ByteBuffer"/>'s and manages them. + /// This is a simple implementation that just returns buffers + /// as they are. Buffers are not reused or refcounted + /// </summary> + public class SimpleByteBufferAllocator : IByteBufferAllocator + { + #region IByteBufferAllocator Members - public SimpleByteBufferAllocator() - { - } - - public ByteBuffer Allocate( int capacity, bool direct ) - { - FixedByteBuffer nioBuffer; - if( direct ) - { - nioBuffer = FixedByteBuffer.allocateDirect( capacity ); - } - else - { - nioBuffer = FixedByteBuffer.allocate( capacity ); - } - return new SimpleByteBuffer( nioBuffer ); - } - - public ByteBuffer Wrap( FixedByteBuffer nioBuffer ) - { - return new SimpleByteBuffer( nioBuffer ); - } + public ByteBuffer Allocate(int capacity) + { + return new SimpleByteBuffer(capacity); + } - public void Dispose() - { - } + public ByteBuffer Wrap(byte[] src) + { + return new SimpleByteBuffer(src); + } - private class SimpleByteBuffer : BaseByteBuffer - { - private FixedByteBuffer _buf; - private int refCount = 1; + #endregion - internal SimpleByteBuffer( FixedByteBuffer buf ) - { - this._buf = buf; - buf.order( ByteOrder.BigEndian ); - refCount = 1; - } + #region IDisposable Members - [MethodImpl(MethodImplOptions.Synchronized)] - public override void acquire() - { - if( refCount <= 0 ) - { - throw new InvalidOperationException("Already released buffer."); - } + public void Dispose() + { + // no need to do anaything + } - refCount ++; - } + #endregion - public override void release() - { - lock( this ) - { - if( refCount <= 0 ) - { - refCount = 0; - throw new InvalidOperationException( - "Already released buffer. You released the buffer too many times." ); - } - - refCount --; - if( refCount > 0) - { - return; - } - } - } - - public override FixedByteBuffer buf() - { - return _buf; - } - - public override bool isPooled() - { - return false; - } - - public override void setPooled(bool pooled) - { - } - - protected override void capacity0(int requestedCapacity) - { - int newCapacity = MINIMUM_CAPACITY; - while( newCapacity < requestedCapacity ) - { - newCapacity <<= 1; - } - - FixedByteBuffer oldBuf = this._buf; - FixedByteBuffer newBuf; - if( isDirect() ) - { - newBuf = FixedByteBuffer.allocateDirect( newCapacity ); - } - else - { - newBuf = FixedByteBuffer.allocate( newCapacity ); - } - - newBuf.clear(); - oldBuf.clear(); - newBuf.put( oldBuf ); - this._buf = newBuf; - } - - public override ByteBuffer duplicate() { - return new SimpleByteBuffer( this._buf.duplicate() ); - } - - public override ByteBuffer slice() - { - return new SimpleByteBuffer( this._buf.slice() ); - } - - public override ByteBuffer asReadOnlyBuffer() - { - return new SimpleByteBuffer( this._buf.asReadOnlyBuffer() ); - } - - public override byte[] array() - { - return _buf.array(); - } - - public override int arrayOffset() - { - return _buf.arrayOffset(); - } - - public override void put(ushort value) - { - _buf.put(value); - } - - public override void put(uint max) - { - _buf.put(max); - } - - public override void put(ulong tag) - { - _buf.put(tag); - } + } // class SimpleByteBufferAllocator +} - public override ulong GetUnsignedLong() - { - return _buf.getUnsignedLong(); - } - } - } -} diff --git a/dotnet/Qpid.Buffer/SlicedByteBuffer.cs b/dotnet/Qpid.Buffer/SlicedByteBuffer.cs new file mode 100644 index 0000000000..414da94a8d --- /dev/null +++ b/dotnet/Qpid.Buffer/SlicedByteBuffer.cs @@ -0,0 +1,86 @@ +/*
+ *
+ * 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
+{
+ internal sealed class SlicedByteBuffer : ByteBuffer
+ {
+ private ByteBuffer _buffer;
+ private int _capacity;
+ private int _startPos;
+
+ public override int Capacity
+ {
+ get { return _capacity; }
+ }
+
+ public override byte[] Array
+ {
+ get { return _buffer.Array; }
+ }
+
+ /// <summary>
+ /// Initialize a new instance
+ /// </summary>
+ /// <param name="buffer">Underlying byte buffer</param>
+ internal SlicedByteBuffer(ByteBuffer buffer)
+ {
+ _buffer = buffer;
+ _startPos = buffer.Position;
+ Position = 0;
+ _capacity = buffer.Remaining;
+ Limit = Capacity;
+ // cannot autoexpand
+ IsAutoExpand = false;
+ }
+
+ protected override void DoWrite(int position, byte value)
+ {
+ _buffer.Put(_startPos + position, value);
+ }
+
+ protected override void DoWrite(int position, byte[] src, int offset, int length)
+ {
+ _buffer.Put(_startPos + position, src, offset, length);
+ }
+
+ protected override byte DoReadByte(int position)
+ {
+ return _buffer.GetByte(_startPos + position);
+ }
+
+ protected override void DoReadBytes(int position, byte[] dest, int offset, int length)
+ {
+ _buffer.GetBytes(_startPos + position, dest, offset, length);
+ }
+
+ protected override void DoCompact()
+ {
+ throw new NotSupportedException();
+ }
+
+ protected override void DoResize(int newSize)
+ {
+ throw new NotSupportedException();
+ }
+ } // class SlicedByteBuffer
+}
diff --git a/dotnet/Qpid.Client/Client/AmqChannel.cs b/dotnet/Qpid.Client/Client/AmqChannel.cs index 528fa96924..9855416db5 100644 --- a/dotnet/Qpid.Client/Client/AmqChannel.cs +++ b/dotnet/Qpid.Client/Client/AmqChannel.cs @@ -815,8 +815,8 @@ namespace Qpid.Client byte[] payload = null; if (buf != null) { - payload = new byte[buf.remaining()]; - buf.get(payload); + payload = new byte[buf.Remaining]; + buf.GetBytes(payload); } BasicContentHeaderProperties contentHeaderProperties = message.ContentHeaderProperties; @@ -824,7 +824,7 @@ namespace Qpid.Client { if (!disableTimestamps) { - contentHeaderProperties.Expiration = (uint)currentTime + timeToLive; + contentHeaderProperties.Expiration = currentTime + timeToLive; } } else diff --git a/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs b/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs index 13a6fa8113..75c4edd67d 100644 --- a/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs +++ b/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs @@ -43,20 +43,20 @@ namespace Qpid.Client.Message if (bodies != null && bodies.Count == 1) { _logger.Debug("Non-fragmented message body (bodySize=" + contentHeader.BodySize +")"); - data = ByteBuffer.wrap(((ContentBody)bodies[0]).Payload); + data = ByteBuffer.Wrap(((ContentBody)bodies[0]).Payload); } else { _logger.Debug("Fragmented message body (" + bodies.Count + " frames, bodySize=" + contentHeader.BodySize + ")"); - data = ByteBuffer.allocate((int)contentHeader.BodySize); // XXX: Is cast a problem? + data = ByteBuffer.Allocate((int)contentHeader.BodySize); // XXX: Is cast a problem? foreach (ContentBody body in bodies) { - data.put(body.Payload); + data.Put(body.Payload); //body.Payload.Release(); } - data.flip(); + data.Flip(); } - _logger.Debug("Creating message from buffer with position=" + data.position() + " and remaining=" + data.remaining()); + _logger.Debug("Creating message from buffer with position=" + data.Position + " and remaining=" + data.Remaining); return CreateMessage(messageNbr, data, contentHeader); } diff --git a/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs b/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs index 85ac497ad2..1d2b2db3ca 100644 --- a/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs +++ b/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs @@ -36,33 +36,38 @@ namespace Qpid.Client.Message protected ByteBuffer _data; protected bool _readableMessage = false; + private QpidHeaders _headers; #region new_java_ctrs protected AbstractQmsMessage(ByteBuffer data) : base(new BasicContentHeaderProperties()) { - _data = data; - if (_data != null) - { - _data.acquire(); - } - _readableMessage = (data != null); + Init(data); } protected AbstractQmsMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, ByteBuffer data) : this(contentHeader, deliveryTag) { - _data = data; - if (_data != null) - { - _data.acquire(); - } - _readableMessage = data != null; + Init(data); } protected AbstractQmsMessage(BasicContentHeaderProperties contentHeader, long deliveryTag) : base(contentHeader, deliveryTag) { + Init(null); + } + + private void Init(ByteBuffer data) + { + _data = data; + if ( _data != null ) + { + _data.Acquire(); + } + _readableMessage = (data != null); + if ( ContentHeaderProperties.Headers == null ) + ContentHeaderProperties.Headers = new FieldTable(); + _headers = new QpidHeaders(ContentHeaderProperties.Headers); } #endregion @@ -269,7 +274,7 @@ namespace Qpid.Client.Message } set { - ContentHeaderProperties.Expiration = (uint) value; + ContentHeaderProperties.Expiration = value; } } @@ -314,7 +319,7 @@ namespace Qpid.Client.Message public IHeaders Headers { - get { return new QpidHeaders(this); } + get { return _headers; } } public abstract void ClearBodyImpl(); @@ -345,13 +350,13 @@ namespace Qpid.Client.Message { if (!_readableMessage) { - _data.flip(); + _data.Flip(); } else { // Make sure we rewind the data just in case any method has moved the // position beyond the start. - _data.rewind(); + _data.Rewind(); } } return _data; diff --git a/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs b/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs index 044dec58b1..32e47d852a 100644 --- a/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs +++ b/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs @@ -62,8 +62,8 @@ namespace Qpid.Client.Message ContentHeaderProperties.ContentType = MIME_TYPE; if (data == null) { - _data = ByteBuffer.allocate(DEFAULT_BUFFER_INITIAL_SIZE); - _data.setAutoExpand(true); + _data = ByteBuffer.Allocate(DEFAULT_BUFFER_INITIAL_SIZE); + _data.IsAutoExpand = true; } } @@ -76,7 +76,7 @@ namespace Qpid.Client.Message public override void ClearBodyImpl() { - _data.clear(); + _data.Clear(); } public override string ToBodyString() @@ -99,19 +99,19 @@ namespace Qpid.Client.Message { return null; } - int pos = _data.position(); - _data.rewind(); + int pos = _data.Position; + _data.Rewind(); // one byte left is for the end of frame marker - if (_data.remaining() == 0) + if (_data.Remaining == 0) { // this is really redundant since pos must be zero - _data.position(pos); + _data.Position = pos; return null; } else { - byte[] data = new byte[_data.remaining()]; - _data.get(data); + byte[] data = new byte[_data.Remaining]; + _data.GetBytes(data); return Encoding.UTF8.GetString(data); } } @@ -129,7 +129,7 @@ namespace Qpid.Client.Message get { CheckReadable(); - return _data.limit(); + return _data.Limit; } } @@ -145,63 +145,63 @@ namespace Qpid.Client.Message { CheckReadable(); CheckAvailable(1); - return _data.get() != 0; + return _data.GetByte() != 0; } public byte ReadByte() { CheckReadable(); CheckAvailable(1); - return _data.get(); + return _data.GetByte(); } public short ReadSignedByte() { CheckReadable(); CheckAvailable(1); - return _data.get(); + return _data.GetSByte(); } public short ReadShort() { CheckReadable(); CheckAvailable(2); - return _data.getShort(); + return _data.GetInt16(); } public char ReadChar() { CheckReadable(); CheckAvailable(2); - return _data.getChar(); + return _data.GetChar(); } public int ReadInt() { CheckReadable(); CheckAvailable(4); - return _data.getInt(); + return _data.GetInt32(); } public long ReadLong() { CheckReadable(); CheckAvailable(8); - return _data.getLong(); + return _data.GetInt64(); } public float ReadFloat() { CheckReadable(); CheckAvailable(4); - return _data.getFloat(); + return _data.GetFloat(); } public double ReadDouble() { CheckReadable(); CheckAvailable(8); - return _data.getDouble(); + return _data.GetDouble(); } public string ReadUTF() @@ -212,8 +212,8 @@ namespace Qpid.Client.Message CheckAvailable(1); try { - byte[] data = new byte[_data.remaining()]; - _data.get(data); + byte[] data = new byte[_data.Remaining]; + _data.GetBytes(data); return Encoding.UTF8.GetString(data); } catch (IOException e) @@ -229,14 +229,14 @@ namespace Qpid.Client.Message throw new ArgumentNullException("bytes"); } CheckReadable(); - int count = (_data.remaining() >= bytes.Length ? bytes.Length : _data.remaining()); + int count = (_data.Remaining >= bytes.Length ? bytes.Length : _data.Remaining); if (count == 0) { return -1; } else { - _data.get(bytes, 0, count); + _data.GetBytes(bytes, 0, count); return count; } } @@ -252,14 +252,14 @@ namespace Qpid.Client.Message throw new ArgumentOutOfRangeException("maxLength must be >= 0"); } CheckReadable(); - int count = (_data.remaining() >= maxLength ? maxLength : _data.remaining()); + int count = (_data.Remaining >= maxLength ? maxLength : _data.Remaining); if (count == 0) { return -1; } else { - _data.get(bytes, 0, count); + _data.GetBytes(bytes, 0, count); return count; } } @@ -267,80 +267,80 @@ namespace Qpid.Client.Message public void WriteBoolean(bool b) { CheckWritable(); - _data.put(b ? (byte)1 : (byte)0); + _data.Put(b ? (byte)1 : (byte)0); } public void WriteByte(byte b) { CheckWritable(); - _data.put(b); + _data.Put(b); } public void WriteShort(short i) { CheckWritable(); - _data.putShort(i); + _data.Put(i); } public void WriteChar(char c) { CheckWritable(); - _data.putChar(c); + _data.Put(c); } public void WriteSignedByte(short value) { CheckWritable(); - _data.put((byte)value); + _data.Put(value); } public void WriteDouble(double value) { CheckWritable(); - _data.putDouble(value); + _data.Put(value); } public void WriteFloat(float value) { CheckWritable(); - _data.putFloat(value); + _data.Put(value); } public void WriteInt(int value) { CheckWritable(); - _data.putInt(value); + _data.Put(value); } public void WriteLong(long value) { CheckWritable(); - _data.putLong(value); + _data.Put(value); } public void WriteUTF(string value) { CheckWritable(); byte[] encodedData = Encoding.UTF8.GetBytes(value); - _data.put(encodedData); + _data.Put(encodedData); } public void WriteBytes(byte[] bytes) { CheckWritable(); - _data.put(bytes); + _data.Put(bytes); } public void WriteBytes(byte[] bytes, int offset, int length) { CheckWritable(); - _data.put(bytes, offset, length); + _data.Put(bytes, offset, length); } protected override void Reset() { base.Reset(); - _data.flip(); + _data.Flip(); } void IBytesMessage.Reset() @@ -356,7 +356,7 @@ namespace Qpid.Client.Message */ private void CheckAvailable(int len) { - if (_data.remaining() < len) + if (_data.Remaining < len) { throw new MessageEOFException("Unable to read " + len + " bytes"); } diff --git a/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs b/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs index 3b44dbc45d..6538fcbefc 100644 --- a/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs +++ b/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs @@ -6,351 +6,202 @@ using Qpid.Messaging; namespace Qpid.Client.Message { - internal class QpidHeaders : IHeaders - { - public const char BOOLEAN_PROPERTY_PREFIX = 'B'; - public const char BYTE_PROPERTY_PREFIX = 'b'; - public const char SHORT_PROPERTY_PREFIX = 's'; - public const char INT_PROPERTY_PREFIX = 'i'; - public const char LONG_PROPERTY_PREFIX = 'l'; - public const char FLOAT_PROPERTY_PREFIX = 'f'; - public const char DOUBLE_PROPERTY_PREFIX = 'd'; - public const char STRING_PROPERTY_PREFIX = 'S'; - - AbstractQmsMessage _message; - - public QpidHeaders(AbstractQmsMessage message) - { - _message = message; - } - - public bool Contains(string name) - { - CheckPropertyName(name); - if (_message.ContentHeaderProperties.Headers == null) - { - return false; - } - else - { - // TODO: fix this - return _message.ContentHeaderProperties.Headers.Contains(STRING_PROPERTY_PREFIX + name); - } - } - - public void Clear() - { - if (_message.ContentHeaderProperties.Headers != null) - { - _message.ContentHeaderProperties.Headers.Clear(); - } - } - - public string this[string name] - { - get - { - return GetString(name); - } - set - { - SetString(name, value); - } - } - - public bool GetBoolean(string name) - { - CheckPropertyName(name); - if (_message.ContentHeaderProperties.Headers == null) - { - return false; - } - else - { - object b = _message.ContentHeaderProperties.Headers[BOOLEAN_PROPERTY_PREFIX + name]; - - if (b == null) - { - return false; - } - else - { - return (bool)b; - } - } - } - - public void SetBoolean(string name, bool b) - { - CheckPropertyName(name); - _message.ContentHeaderProperties.Headers[BOOLEAN_PROPERTY_PREFIX + name] = b; - } - - public byte GetByte(string propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return 0; - } - else - { - object b = _message.ContentHeaderProperties.Headers[BYTE_PROPERTY_PREFIX + propertyName]; - if (b == null) - { - return 0; - } - else - { - return (byte)b; - } - } - } - - public void SetByte(string propertyName, byte b) - { - CheckPropertyName(propertyName); - _message.ContentHeaderProperties.Headers[BYTE_PROPERTY_PREFIX + propertyName] = b; - } - - public short GetShort(string propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return 0; - } - else - { - object s = _message.ContentHeaderProperties.Headers[SHORT_PROPERTY_PREFIX + propertyName]; - if (s == null) - { - return 0; - } - else - { - return (short)s; - } - } - } - - public void SetShort(string propertyName, short i) - { - CheckPropertyName(propertyName); - _message.ContentHeaderProperties.Headers[SHORT_PROPERTY_PREFIX + propertyName] = i; - } - - public int GetInt(string propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return 0; - } - else - { - object i = _message.ContentHeaderProperties.Headers[INT_PROPERTY_PREFIX + propertyName]; - if (i == null) - { - return 0; - } - else - { - return (int)i; - } - } - } - - public void SetInt(string propertyName, int i) - { - CheckPropertyName(propertyName); - _message.ContentHeaderProperties.Headers[INT_PROPERTY_PREFIX + propertyName] = i; - } - - public long GetLong(string propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return 0; - } - else - { - object l = _message.ContentHeaderProperties.Headers[LONG_PROPERTY_PREFIX + propertyName]; - if (l == null) - { - // temp - the spec says do this but this throws a NumberFormatException - //return Long.valueOf(null).longValue(); - return 0; - } - else - { - return (long)l; - } - } - } - - public void SetLong(string propertyName, long l) - { - CheckPropertyName(propertyName); - _message.ContentHeaderProperties.Headers[LONG_PROPERTY_PREFIX + propertyName] = l; - } - - public float GetFloat(String propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return 0; - } - else - { - object f = _message.ContentHeaderProperties.Headers[FLOAT_PROPERTY_PREFIX + propertyName]; - if (f == null) - { - return 0; - } - else - { - return (float)f; - } - } - } - - public void SetFloat(string propertyName, float f) - { - CheckPropertyName(propertyName); - _message.ContentHeaderProperties.Headers[FLOAT_PROPERTY_PREFIX + propertyName] = f; - } - - public double GetDouble(string propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return 0; - } - else - { - object d = _message.ContentHeaderProperties.Headers[DOUBLE_PROPERTY_PREFIX + propertyName]; - if (d == null) - { - return 0; - } - else - { - return (double)d; - } - } - } - - public void SetDouble(string propertyName, double v) - { - CheckPropertyName(propertyName); - _message.ContentHeaderProperties.Headers[DOUBLE_PROPERTY_PREFIX + propertyName] = v; - } - - public string GetString(string propertyName) - { - CheckPropertyName(propertyName); - if (_message.ContentHeaderProperties.Headers == null) - { - return null; - } - else - { - return (string)_message.ContentHeaderProperties.Headers[STRING_PROPERTY_PREFIX + propertyName]; - } - } - - public void SetString(string propertyName, string value) - { - CheckPropertyName(propertyName); - CreatePropertyMapIfRequired(); - propertyName = STRING_PROPERTY_PREFIX + propertyName; - _message.ContentHeaderProperties.Headers[propertyName] = value; - } - - private void CheckPropertyName(string propertyName) - { - if (propertyName == null) - { - throw new ArgumentException("Property name must not be null"); - } - else if ("".Equals(propertyName)) - { - throw new ArgumentException("Property name must not be the empty string"); - } - - if (_message.ContentHeaderProperties.Headers == null) - { - _message.ContentHeaderProperties.Headers = new FieldTable(); - } - } - - private void CreatePropertyMapIfRequired() - { - if (_message.ContentHeaderProperties.Headers == null) - { - _message.ContentHeaderProperties.Headers = new FieldTable(); - } - } - - public override string ToString() - { - StringBuilder buf = new StringBuilder("{"); - int i = 0; - foreach (DictionaryEntry entry in _message.ContentHeaderProperties.Headers) - { - ++i; - if (i > 1) - { - buf.Append(", "); - } - string propertyName = (string)entry.Key; - if (propertyName == null) - { - buf.Append("\nInternal error: Property with NULL key defined"); - } - else - { - buf.Append(propertyName.Substring(1)); - - buf.Append(" : "); - - char typeIdentifier = propertyName[0]; - buf.Append(typeIdentifierToName(typeIdentifier)); - buf.Append(" = ").Append(entry.Value); - } - } - buf.Append("}"); - return buf.ToString(); - } - - private static string typeIdentifierToName(char typeIdentifier) - { - switch (typeIdentifier) - { - case BOOLEAN_PROPERTY_PREFIX: - return "boolean"; - case BYTE_PROPERTY_PREFIX: - return "byte"; - case SHORT_PROPERTY_PREFIX: - return "short"; - case INT_PROPERTY_PREFIX: - return "int"; - case LONG_PROPERTY_PREFIX: - return "long"; - case FLOAT_PROPERTY_PREFIX: - return "float"; - case DOUBLE_PROPERTY_PREFIX: - return "double"; - case STRING_PROPERTY_PREFIX: - return "string"; - default: - return "unknown ( '" + typeIdentifier + "')"; - } - } - - } -}
\ No newline at end of file + internal class QpidHeaders : IHeaders + { + private FieldTable _headers; + + public QpidHeaders(FieldTable headers) + { + if ( headers == null ) + throw new ArgumentNullException("headers"); + _headers = headers; + } + + public bool Contains(string name) + { + CheckPropertyName(name); + return _headers.Contains(name); + } + + public void Clear() + { + _headers.Clear(); + } + + public string this[string name] + { + get + { + return GetString(name); + } + set + { + SetString(name, value); + } + } + + public bool GetBoolean(string name) + { + CheckPropertyName(name); + if ( Contains(name) ) + return _headers.GetBoolean(name); + return false; + } + + public void SetBoolean(string name, bool b) + { + CheckPropertyName(name); + _headers.SetBoolean(name, b); + } + + public byte GetByte(string propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetByte(propertyName); + return 0; + } + + public void SetByte(string propertyName, byte b) + { + CheckPropertyName(propertyName); + _headers.SetByte(propertyName, b); + } + + // we have sbyte overloads to interoperate with java + // because the Java client/server uses signed bytes + // by default, while C#'s is unsigned + public sbyte GetSByte(string propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetSByte(propertyName); + return 0; + } + + public void SetSByte(string propertyName, sbyte b) + { + CheckPropertyName(propertyName); + _headers.SetSByte(propertyName, b); + } + + public short GetShort(string propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetInt16(propertyName); + return 0; + } + + public void SetShort(string propertyName, short i) + { + CheckPropertyName(propertyName); + _headers.SetInt16(propertyName, i); + } + + public int GetInt(string propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetInt32(propertyName); + return 0; + } + + public void SetInt(string propertyName, int i) + { + CheckPropertyName(propertyName); + _headers.SetInt32(propertyName, i); + } + + public long GetLong(string propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetInt64(propertyName); + return 0; + } + + public void SetLong(string propertyName, long l) + { + CheckPropertyName(propertyName); + _headers.SetInt64(propertyName, l); + } + + public float GetFloat(String propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetFloat(propertyName); + return 0f; + } + + public void SetFloat(string propertyName, float f) + { + CheckPropertyName(propertyName); + _headers.SetFloat(propertyName, f); + } + + public double GetDouble(string propertyName) + { + CheckPropertyName(propertyName); + if ( Contains(propertyName) ) + return _headers.GetDouble(propertyName); + return 0; + } + + public void SetDouble(string propertyName, double v) + { + CheckPropertyName(propertyName); + _headers.SetDouble(propertyName, v); + } + + public string GetString(string propertyName) + { + CheckPropertyName(propertyName); + return _headers.GetString(propertyName); + } + + public void SetString(string propertyName, string value) + { + CheckPropertyName(propertyName); + _headers.SetString(propertyName, value); + } + + private static void CheckPropertyName(string propertyName) + { + if ( propertyName == null ) + { + throw new ArgumentException("Property name must not be null"); + } else if ( "".Equals(propertyName) ) + { + throw new ArgumentException("Property name must not be the empty string"); + } + } + + public override string ToString() + { + StringBuilder buf = new StringBuilder("{"); + int i = 0; + foreach ( DictionaryEntry entry in _headers ) + { + ++i; + if ( i > 1 ) + { + buf.Append(", "); + } + string propertyName = (string)entry.Key; + if ( propertyName == null ) + { + buf.Append("\nInternal error: Property with NULL key defined"); + } else + { + buf.Append(propertyName); + buf.Append(" = ").Append(entry.Value); + } + } + buf.Append("}"); + return buf.ToString(); + } + + } +} diff --git a/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs b/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs index 317d2283f3..cff42f1df5 100644 --- a/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs +++ b/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs @@ -53,7 +53,7 @@ namespace Qpid.Client.Message { if (_data != null) { - _data.release(); + _data.Release(); } _data = null; _decodedValue = null; @@ -86,11 +86,11 @@ namespace Qpid.Client.Message } else { - _data.rewind(); + _data.Rewind(); // Read remaining bytes. - byte[] bytes = new byte[_data.remaining()]; - _data.get(bytes); + byte[] bytes = new byte[_data.Remaining]; + _data.GetBytes(bytes); // Convert to string based on encoding. if (ContentHeaderProperties.Encoding != null) @@ -118,7 +118,7 @@ namespace Qpid.Client.Message // throw ArgumentException if the encoding is not supported bytes = Encoding.GetEncoding(ContentHeaderProperties.Encoding).GetBytes(value); } - _data = ByteBuffer.wrap(bytes); + _data = ByteBuffer.Wrap(bytes); _decodedValue = value; } } diff --git a/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketProcessor.cs b/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketProcessor.cs index bdec584b7b..7a9ead0c06 100644 --- a/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketProcessor.cs +++ b/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketProcessor.cs @@ -71,7 +71,7 @@ namespace Qpid.Client.Transport.Socket.Blocking {
try
{
- _networkStream.Write(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit()); // FIXME
+ _networkStream.Write(byteBuffer.Array, byteBuffer.Position, byteBuffer.Limit); // FIXME
}
catch (Exception e)
{
@@ -87,10 +87,10 @@ namespace Qpid.Client.Transport.Socket.Blocking int numOctets = _networkStream.Read(bytes, 0, bytes.Length);
- ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
- byteBuffer.limit(numOctets);
+ ByteBuffer byteBuffer = ByteBuffer.Wrap(bytes);
+ byteBuffer.Limit = numOctets;
- byteBuffer.flip();
+ byteBuffer.Flip();
return byteBuffer;
}
@@ -114,3 +114,4 @@ namespace Qpid.Client.Transport.Socket.Blocking }
}
+
diff --git a/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs b/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs index 21614cf108..72c56e0b17 100644 --- a/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs +++ b/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs @@ -33,8 +33,8 @@ namespace Qpid.Codec /// </summary> protected CumulativeProtocolDecoder() { - _remaining = ByteBuffer.allocate(4096); - _remaining.setAutoExpand(true); + _remaining = ByteBuffer.Allocate(4096); + _remaining.IsAutoExpand = true; } /// <summary> @@ -48,7 +48,7 @@ namespace Qpid.Codec /// </exception> public void Decode(ByteBuffer input, IProtocolDecoderOutput output) { - if (_remaining.position() != 0) // If there were remaining undecoded bytes + if (_remaining.Position != 0) // If there were remaining undecoded bytes { DecodeRemainingAndInput(input, output); } @@ -67,9 +67,9 @@ namespace Qpid.Codec } finally { - if (input.hasRemaining()) + if (input.HasRemaining) { - _remaining.put(input); + _remaining.Put(input); } } } @@ -77,8 +77,8 @@ namespace Qpid.Codec private void DecodeRemainingAndInput(ByteBuffer input, IProtocolDecoderOutput output) { // Concatenate input buffer with left-over bytes. - _remaining.put(input); - _remaining.flip(); + _remaining.Put(input); + _remaining.Flip(); try { @@ -86,7 +86,7 @@ namespace Qpid.Codec } finally { - _remaining.compact(); + _remaining.Compact(); } } @@ -94,17 +94,17 @@ namespace Qpid.Codec { for (;;) { - int oldPos = buf.position(); + int oldPos = buf.Position; bool decoded = DoDecode(buf, output); if (decoded) { - if (buf.position() == oldPos) + if (buf.Position == oldPos) { throw new Exception( "doDecode() can't return true when buffer is not consumed."); } - if (!buf.hasRemaining()) + if (!buf.HasRemaining) { break; } diff --git a/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs b/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs index 6577909cff..27095bd32d 100644 --- a/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs +++ b/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs @@ -217,8 +217,8 @@ namespace Qpid.Codec.Demux for (int i = decoders.Length - 1; i >= 0; i --) { IMessageDecoder decoder = decoders[i]; - int limit = input.limit(); - int pos = input.position(); + int limit = input.Limit; + int pos = input.Position; try { @@ -226,8 +226,8 @@ namespace Qpid.Codec.Demux } finally { - input.position(pos); - input.limit(limit); + input.Position = pos; + input.Limit = limit; } if (result == MessageDecoderResult.OK) @@ -248,9 +248,9 @@ namespace Qpid.Codec.Demux if (undecodables == _decoders.Length) { // Throw an exception if all decoders cannot decode data. - input.position(input.limit()); // Skip data + input.Position = input.Limit; // Skip data throw new ProtocolDecoderException( - "No appropriate message decoder: " + input.HexDump); + "No appropriate message decoder: " + input.GetHexDump()); } if (_currentDecoder == null) @@ -383,3 +383,4 @@ namespace Qpid.Codec.Demux } } + diff --git a/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj b/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj index 8c5142e690..684d21b324 100644 --- a/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj +++ b/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj @@ -40,6 +40,7 @@ <ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Qpid\Collections\TestLinkedHashtable.cs" />
+ <Compile Include="Qpid\Framing\TestEncodingUtils.cs" />
<Compile Include="Qpid\Framing\TestAMQType.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs b/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs index 805d728db6..f5ff30182d 100644 --- a/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs +++ b/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs @@ -34,12 +34,12 @@ namespace Qpid.Framing.Tests public void LONG_STRING_ReadWrite()
{
AMQType type = AMQType.LONG_STRING;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const string VALUE = "simple string 1";
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
@@ -75,12 +75,12 @@ namespace Qpid.Framing.Tests public void UINT32_ReadWrite()
{
AMQType type = AMQType.UINT32;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const uint VALUE = 0xFFEEDDCC;
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
@@ -113,11 +113,11 @@ namespace Qpid.Framing.Tests public void VOID_ReadWrite()
{
AMQType type = AMQType.VOID;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
type.WriteToBuffer(null, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(null, value.Value);
}
@@ -152,11 +152,11 @@ namespace Qpid.Framing.Tests public void BOOLEAN_ReadWrite()
{
AMQType type = AMQType.BOOLEAN;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
type.WriteToBuffer(true, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(true, value.Value);
}
@@ -167,24 +167,24 @@ namespace Qpid.Framing.Tests public void INT16_ReadWrite()
{
AMQType type = AMQType.INT16;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const short VALUE = -32765;
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
//public void UINT16_ReadWrite()
//{
// AMQType type = AMQType.UINT16;
- // ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ // ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
// const ushort VALUE = 64321;
// type.WriteToBuffer(VALUE, buffer);
- // buffer.flip();
- // buffer.position(0);
+ // buffer.Flip();
+ // buffer.Rewind();
// AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
// Assert.AreEqual(VALUE, value.Value);
//}
@@ -195,12 +195,12 @@ namespace Qpid.Framing.Tests public void INT32_ReadWrite()
{
AMQType type = AMQType.INT32;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const int VALUE = -39273563;
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
@@ -211,12 +211,12 @@ namespace Qpid.Framing.Tests public void INT64_ReadWrite()
{
AMQType type = AMQType.INT64;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const long VALUE = -(2^43+1233123);
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
@@ -224,12 +224,12 @@ namespace Qpid.Framing.Tests public void UINT64_ReadWrite()
{
AMQType type = AMQType.UINT64;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const ulong VALUE = (2 ^ 61 + 1233123);
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
@@ -240,12 +240,12 @@ namespace Qpid.Framing.Tests public void FLOAT_ReadWrite()
{
AMQType type = AMQType.FLOAT;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const float VALUE = 1.2345000E-035f;
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
@@ -256,12 +256,12 @@ namespace Qpid.Framing.Tests public void DOUBLE_ReadWrite()
{
AMQType type = AMQType.DOUBLE;
- ByteBuffer buffer = (new SimpleByteBufferAllocator()).Allocate(0x1000, false);
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
const double VALUE = 1.2345000E-045;
type.WriteToBuffer(VALUE, buffer);
- buffer.flip();
- buffer.position(0);
+ buffer.Flip();
+ buffer.Rewind();
AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
Assert.AreEqual(VALUE, value.Value);
}
diff --git a/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs b/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs new file mode 100644 index 0000000000..7c6615ed1e --- /dev/null +++ b/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs @@ -0,0 +1,60 @@ +/*
+ *
+ * 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;
+using Qpid.Framing;
+
+namespace Qpid.Framing.Tests
+{
+ [TestFixture]
+ public class TestEncodingUtils
+ {
+ [Test]
+ public void CanReadLongAsShortString()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ EncodingUtils.WriteShortStringBytes(buffer, "98878122");
+ buffer.Flip();
+ long value = EncodingUtils.ReadLongAsShortString(buffer);
+ Assert.AreEqual(98878122, value);
+ }
+ [Test]
+ public void CanReadLongAsShortStringNegative()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ EncodingUtils.WriteShortStringBytes(buffer, "-98878122");
+ buffer.Flip();
+ long value = EncodingUtils.ReadLongAsShortString(buffer);
+ Assert.AreEqual(-98878122, value);
+ }
+ [Test]
+ public void CanReadLongAsShortStringEmpty()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ EncodingUtils.WriteShortStringBytes(buffer, "");
+ buffer.Flip();
+ long value = EncodingUtils.ReadLongAsShortString(buffer);
+ Assert.AreEqual(0, value);
+ }
+
+ }
+}
diff --git a/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs b/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs index 2e373402b6..1c1080bdcb 100644 --- a/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs +++ b/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs @@ -51,11 +51,11 @@ namespace Qpid.Framing } // final +1 represents the command end which we know we must require even // if there is an empty body - if (input.remaining() < 1) + if (input.Remaining < 1) { return MessageDecoderResult.NEED_DATA; } - byte type = input.get(); + byte type = input.GetByte(); // we have to check this isn't a protocol initiation frame here - we can't tell later on and we end up // waiting for more data. This could be improved if MINA supported some kind of state awareness when decoding @@ -65,13 +65,13 @@ namespace Qpid.Framing return MessageDecoderResult.NOT_OK; } // zero, channel, body size and end byte - if (input.remaining() < (1 + 2 + 4 + 1)) + if (input.Remaining < (1 + 2 + 4 + 1)) { return MessageDecoderResult.NEED_DATA; } - - int channel = input.GetUnsignedShort(); - long bodySize = input.GetUnsignedInt(); + + int channel = input.GetUInt16(); + long bodySize = input.GetUInt32(); // bodySize can be zero if (type <= 0 || channel < 0 || bodySize < 0) @@ -80,7 +80,7 @@ namespace Qpid.Framing return MessageDecoderResult.NOT_OK; } - if (input.remaining() < (bodySize + 1)) + if (input.Remaining < (bodySize + 1)) { return MessageDecoderResult.NEED_DATA; } @@ -116,9 +116,9 @@ namespace Qpid.Framing protected Object CreateAndPopulateFrame(ByteBuffer input) { - byte type = input.get(); - ushort channel = input.GetUnsignedShort(); - uint bodySize = input.GetUnsignedInt(); + byte type = input.GetByte(); + ushort channel = input.GetUInt16(); + uint bodySize = input.GetUInt32(); IBodyFactory bodyFactory = (IBodyFactory)_supportedBodies[type]; if (bodyFactory == null) @@ -129,7 +129,7 @@ namespace Qpid.Framing frame.PopulateFromBuffer(input, channel, bodySize, bodyFactory); - byte marker = input.get(); + byte marker = input.GetByte(); if (marker != 0xCE) { throw new FormatException("marker is not 0xCE"); } diff --git a/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs b/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs index 6c30040167..b180e1ac95 100644 --- a/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs +++ b/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs @@ -51,14 +51,14 @@ namespace Qpid.Framing { IDataBlock frame = (IDataBlock) message; int frameSize = (int)frame.Size; // TODO: sort out signed/unsigned - ByteBuffer buffer = ByteBuffer.allocate(frameSize); + ByteBuffer buffer = ByteBuffer.Allocate(frameSize); frame.WritePayload(buffer); if (_logger.IsDebugEnabled) { _logger.Debug("Encoded frame byte-buffer is '" + ByteBufferHexDumper.GetHexDump(buffer) + "'"); } - buffer.flip(); + buffer.Flip(); output.Write(buffer); } } diff --git a/dotnet/Qpid.Common/Framing/AMQFrame.cs b/dotnet/Qpid.Common/Framing/AMQFrame.cs index 9652cdfabc..2708c331b3 100644 --- a/dotnet/Qpid.Common/Framing/AMQFrame.cs +++ b/dotnet/Qpid.Common/Framing/AMQFrame.cs @@ -74,12 +74,12 @@ namespace Qpid.Framing public void WritePayload(ByteBuffer buffer) { - buffer.put(_bodyFrame.BodyType); + buffer.Put(_bodyFrame.BodyType); // TODO: how does channel get populated - buffer.put(_channel); - buffer.put(_bodyFrame.Size); + buffer.Put(_channel); + buffer.Put(_bodyFrame.Size); _bodyFrame.WritePayload(buffer); - buffer.put((byte) 0xCE); + buffer.Put((byte) 0xCE); } #endregion diff --git a/dotnet/Qpid.Common/Framing/AMQMethodBody.cs b/dotnet/Qpid.Common/Framing/AMQMethodBody.cs index 96e8e60be1..804e6a4039 100644 --- a/dotnet/Qpid.Common/Framing/AMQMethodBody.cs +++ b/dotnet/Qpid.Common/Framing/AMQMethodBody.cs @@ -62,8 +62,8 @@ namespace Qpid.Framing public void WritePayload(ByteBuffer buffer) { - buffer.put(Clazz); - buffer.put(Method); + buffer.Put(Clazz); + buffer.Put(Method); WriteMethodPayload(buffer); } diff --git a/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs b/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs index 5df9720678..a5c90f0fdd 100644 --- a/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs +++ b/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs @@ -39,7 +39,7 @@ namespace Qpid.Framing /// <exception>AMQFrameDecodingException</exception> public IBody CreateBody(ByteBuffer inbuf) { - return MethodBodyDecoderRegistry.Get(inbuf.GetUnsignedShort(), inbuf.GetUnsignedShort()); + return MethodBodyDecoderRegistry.Get(inbuf.GetUInt16(), inbuf.GetUInt16()); } } } diff --git a/dotnet/Qpid.Common/Framing/AMQType.cs b/dotnet/Qpid.Common/Framing/AMQType.cs index 3bcc6c6222..8743ea0ea5 100644 --- a/dotnet/Qpid.Common/Framing/AMQType.cs +++ b/dotnet/Qpid.Common/Framing/AMQType.cs @@ -63,7 +63,7 @@ namespace Qpid.Framing /// <param name="buffer">Buffer to write to</param>
public void WriteToBuffer(object value, ByteBuffer buffer)
{
- buffer.put(Identifier);
+ buffer.Put(Identifier);
WriteValueImpl(value, buffer);
}
@@ -163,7 +163,7 @@ namespace Qpid.Framing sealed class AMQUInt32Type : AMQType
{
- public AMQUInt32Type() : base('I')
+ public AMQUInt32Type() : base('i')
{
}
@@ -560,7 +560,7 @@ namespace Qpid.Framing sealed class AMQInt32Type : AMQType
{
- public AMQInt32Type() : base('i')
+ public AMQInt32Type() : base('I')
{
}
diff --git a/dotnet/Qpid.Common/Framing/AMQTypedValue.cs b/dotnet/Qpid.Common/Framing/AMQTypedValue.cs index 08b5c1e6e9..7fdabbaf6c 100644 --- a/dotnet/Qpid.Common/Framing/AMQTypedValue.cs +++ b/dotnet/Qpid.Common/Framing/AMQTypedValue.cs @@ -64,7 +64,7 @@ namespace Qpid.Framing public static AMQTypedValue ReadFromBuffer(ByteBuffer buffer)
{
- AMQType type = AMQTypeMap.GetType(buffer.get());
+ AMQType type = AMQTypeMap.GetType(buffer.GetByte());
return new AMQTypedValue(type, buffer);
}
diff --git a/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs b/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs index 709db419c4..75d67fdfb8 100644 --- a/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs +++ b/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs @@ -41,7 +41,7 @@ namespace Qpid.Framing public string CorrelationId; - public uint Expiration; + public long Expiration; public string ReplyTo; @@ -102,13 +102,13 @@ namespace Qpid.Framing EncodingUtils.WriteShortStringBytes(buffer, ContentType); EncodingUtils.WriteShortStringBytes(buffer, Encoding); EncodingUtils.WriteFieldTableBytes(buffer, Headers); - buffer.put(DeliveryMode); - buffer.put(Priority); + buffer.Put(DeliveryMode); + buffer.Put(Priority); EncodingUtils.WriteShortStringBytes(buffer, CorrelationId); EncodingUtils.WriteShortStringBytes(buffer, ReplyTo); EncodingUtils.WriteShortStringBytes(buffer, String.Format("{0:D}", Expiration)); EncodingUtils.WriteShortStringBytes(buffer, MessageId); - buffer.put(Timestamp); + buffer.Put(Timestamp); EncodingUtils.WriteShortStringBytes(buffer, Type); EncodingUtils.WriteShortStringBytes(buffer, UserId); EncodingUtils.WriteShortStringBytes(buffer, AppId); @@ -125,19 +125,19 @@ namespace Qpid.Framing if ((propertyFlags & (1 << 13)) > 0) Headers = EncodingUtils.ReadFieldTable(buffer); if ((propertyFlags & (1 << 12)) > 0) - DeliveryMode = buffer.get(); + DeliveryMode = buffer.GetByte(); if ((propertyFlags & (1 << 11)) > 0) - Priority = buffer.get(); + Priority = buffer.GetByte(); if ((propertyFlags & (1 << 10)) > 0) CorrelationId = EncodingUtils.ReadShortString(buffer); if ((propertyFlags & (1 << 9)) > 0) ReplyTo = EncodingUtils.ReadShortString(buffer); if ((propertyFlags & (1 << 8)) > 0) - Expiration = UInt32.Parse(EncodingUtils.ReadShortString(buffer)); + Expiration = EncodingUtils.ReadLongAsShortString(buffer); if ((propertyFlags & (1 << 7)) > 0) MessageId = EncodingUtils.ReadShortString(buffer); - if ((propertyFlags & (1 << 6)) > 0) - Timestamp = buffer.GetUnsignedLong(); + if ((propertyFlags & (1 << 6)) > 0) + Timestamp = buffer.GetUInt64(); if ((propertyFlags & (1 << 5)) > 0) Type = EncodingUtils.ReadShortString(buffer); if ((propertyFlags & (1 << 4)) > 0) diff --git a/dotnet/Qpid.Common/Framing/ContentBody.cs b/dotnet/Qpid.Common/Framing/ContentBody.cs index 4e7ae2019a..b63df22339 100644 --- a/dotnet/Qpid.Common/Framing/ContentBody.cs +++ b/dotnet/Qpid.Common/Framing/ContentBody.cs @@ -54,7 +54,7 @@ namespace Qpid.Framing { if (Payload != null) { - buffer.put(Payload); + buffer.Put(Payload); } } @@ -63,7 +63,7 @@ namespace Qpid.Framing if (size > 0) { Payload = new byte[size]; - buffer.get(Payload); + buffer.GetBytes(Payload); } } diff --git a/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs b/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs index f72f6208bc..29ec46c0fb 100644 --- a/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs +++ b/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs @@ -73,19 +73,19 @@ namespace Qpid.Framing public void WritePayload(ByteBuffer buffer) { - buffer.put(ClassId); - buffer.put(Weight); - buffer.put(BodySize); - buffer.put(Properties.PropertyFlags); + buffer.Put(ClassId); + buffer.Put(Weight); + buffer.Put(BodySize); + buffer.Put(Properties.PropertyFlags); Properties.WritePropertyListPayload(buffer); } public void PopulateFromBuffer(ByteBuffer buffer, uint size) { - ClassId = buffer.GetUnsignedShort(); - Weight = buffer.GetUnsignedShort(); - BodySize = buffer.GetUnsignedLong(); - ushort propertyFlags = buffer.GetUnsignedShort(); + ClassId = buffer.GetUInt16(); + Weight = buffer.GetUInt16(); + BodySize = buffer.GetUInt64(); + ushort propertyFlags = buffer.GetUInt16(); ContentHeaderPropertiesFactory factory = ContentHeaderPropertiesFactory.GetInstance(); Properties = factory.CreateContentHeaderProperties(ClassId, propertyFlags, buffer); } diff --git a/dotnet/Qpid.Common/Framing/EncodingUtils.cs b/dotnet/Qpid.Common/Framing/EncodingUtils.cs index 564c9d87ef..6dc973a672 100644 --- a/dotnet/Qpid.Common/Framing/EncodingUtils.cs +++ b/dotnet/Qpid.Common/Framing/EncodingUtils.cs @@ -19,6 +19,7 @@ * */ using System; +using System.Globalization; using System.Text; using Qpid.Buffer; @@ -52,13 +53,13 @@ namespace Qpid.Framing encodedString = DEFAULT_ENCODER.GetBytes(s); } // TODO: check length fits in an unsigned byte - buffer.put((byte)encodedString.Length); - buffer.put(encodedString); + buffer.Put((byte)encodedString.Length); + buffer.Put(encodedString); } else { // really writing out unsigned byte - buffer.put((byte)0); + buffer.Put((byte)0); } } @@ -103,14 +104,14 @@ namespace Qpid.Framing } public static string ReadLongString(ByteBuffer buffer, Encoding encoding) { - uint length = buffer.getUnsignedInt(); + uint length = buffer.GetUInt32(); if ( length == 0 ) { return null; } else { byte[] data = new byte[length]; - buffer.get(data); + buffer.GetBytes(data); lock ( encoding ) { return encoding.GetString(data); @@ -132,14 +133,13 @@ namespace Qpid.Framing { lock ( encoding ) { - byte[] encodedString = null; - encodedString = encoding.GetBytes(s); - buffer.put((uint)encodedString.Length); - buffer.put(encodedString); + byte[] encodedString = encoding.GetBytes(s); + buffer.Put((uint)encodedString.Length); + buffer.Put(encodedString); } } else { - buffer.put((uint)0); + buffer.Put((uint)0); } } @@ -156,14 +156,14 @@ namespace Qpid.Framing } public static byte[] ReadLongstr(ByteBuffer buffer) { - uint length = buffer.getUnsignedInt(); + uint length = buffer.GetUInt32(); if ( length == 0 ) { return null; } else { byte[] result = new byte[length]; - buffer.get(result); + buffer.GetBytes(result); return result; } } @@ -171,18 +171,18 @@ namespace Qpid.Framing { if ( data != null ) { - buffer.put((uint)data.Length); - buffer.put(data); + buffer.Put((uint)data.Length); + buffer.Put(data); } else { - buffer.put((uint)0); + buffer.Put((uint)0); } } // BOOLEANS public static bool[] ReadBooleans(ByteBuffer buffer) { - byte packedValue = buffer.get(); + byte packedValue = buffer.GetByte(); bool[] result = new bool[8]; for ( int i = 0; i < 8; i++ ) @@ -202,7 +202,7 @@ namespace Qpid.Framing } } - buffer.put(packedValue); + buffer.Put(packedValue); } // FIELD TABLES @@ -226,7 +226,7 @@ namespace Qpid.Framing /// <exception cref="AMQFrameDecodingException">if the buffer does not contain a decodable field table</exception> public static FieldTable ReadFieldTable(ByteBuffer buffer) { - uint length = buffer.GetUnsignedInt(); + uint length = buffer.GetUInt32(); if ( length == 0 ) { return null; @@ -242,7 +242,7 @@ namespace Qpid.Framing table.WriteToBuffer(buffer); } else { - buffer.put((uint)0); + buffer.Put((uint)0); } } @@ -255,14 +255,14 @@ namespace Qpid.Framing /// <exception cref="AMQFrameDecodingException">if the buffer does not contain a decodable short string</exception> public static string ReadShortString(ByteBuffer buffer) { - byte length = buffer.get(); + byte length = buffer.GetByte(); if ( length == 0 ) { return null; } else { byte[] data = new byte[length]; - buffer.get(data); + buffer.GetBytes(data); lock ( DEFAULT_ENCODER ) { @@ -280,12 +280,12 @@ namespace Qpid.Framing } public static bool ReadBoolean(ByteBuffer buffer) { - byte packedValue = buffer.get(); + byte packedValue = buffer.GetByte(); return (packedValue == 1); } public static void WriteBoolean(ByteBuffer buffer, bool value) { - buffer.put((byte)(value ? 1 : 0)); + buffer.Put((byte)(value ? 1 : 0)); } @@ -296,11 +296,11 @@ namespace Qpid.Framing } public static char ReadChar(ByteBuffer buffer) { - return (char)buffer.get(); + return (char)buffer.GetByte(); } public static void WriteChar(ByteBuffer buffer, char value) { - buffer.put((byte)value); + buffer.Put((byte)value); } // BYTE @@ -310,11 +310,11 @@ namespace Qpid.Framing } public static byte ReadByte(ByteBuffer buffer) { - return buffer.get(); + return buffer.GetByte(); } public static void WriteByte(ByteBuffer buffer, byte value) { - buffer.put(value); + buffer.Put(value); } // SBYTE @@ -324,11 +324,11 @@ namespace Qpid.Framing } public static sbyte ReadSByte(ByteBuffer buffer) { - return (sbyte)buffer.get(); + return buffer.GetSByte(); } public static void WriteSByte(ByteBuffer buffer, sbyte value) { - buffer.put((byte)value); + buffer.Put(value); } // INT16 @@ -339,11 +339,11 @@ namespace Qpid.Framing public static short ReadShort(ByteBuffer buffer) { - return buffer.getShort(); + return buffer.GetInt16(); } public static void WriteShort(ByteBuffer buffer, short value) { - buffer.putShort(value); + buffer.Put(value); } // UINT16 @@ -354,11 +354,11 @@ namespace Qpid.Framing public static ushort ReadUnsignedShort(ByteBuffer buffer) { - return buffer.GetUnsignedShort(); + return buffer.GetUInt16(); } public static void WriteUnsignedShort(ByteBuffer buffer, ushort value) { - buffer.put(value); + buffer.Put(value); } @@ -369,11 +369,11 @@ namespace Qpid.Framing } public static int ReadInteger(ByteBuffer buffer) { - return buffer.getInt(); + return buffer.GetInt32(); } public static void WriteInteger(ByteBuffer buffer, int value) { - buffer.putInt(value); + buffer.Put(value); } // UINT32 @@ -383,11 +383,11 @@ namespace Qpid.Framing } public static void WriteUnsignedInteger(ByteBuffer buffer, uint value) { - buffer.put(value); + buffer.Put(value); } public static uint ReadUnsignedInteger(ByteBuffer buffer) { - return buffer.getUnsignedInt(); + return buffer.GetUInt32(); } // INT64 @@ -397,11 +397,11 @@ namespace Qpid.Framing } public static ulong ReadUnsignedLong(ByteBuffer buffer) { - return buffer.GetUnsignedLong(); + return buffer.GetUInt64(); } public static void WriteUnsignedLong(ByteBuffer buffer, ulong value) { - buffer.put(value); + buffer.Put(value); } // UINT64 @@ -411,11 +411,11 @@ namespace Qpid.Framing } public static long ReadLong(ByteBuffer buffer) { - return buffer.getLong(); + return buffer.GetInt64(); } public static void WriteLong(ByteBuffer buffer, long value) { - buffer.putLong(value); + buffer.Put(value); } // FLOAT @@ -425,11 +425,11 @@ namespace Qpid.Framing } public static void WriteFloat(ByteBuffer buffer, float value) { - buffer.putFloat(value); + buffer.Put(value); } public static float ReadFloat(ByteBuffer buffer) { - return buffer.getFloat(); + return buffer.GetFloat(); } // DOUBLE @@ -439,11 +439,20 @@ namespace Qpid.Framing } public static void WriteDouble(ByteBuffer buffer, double value) { - buffer.putDouble(value); + buffer.Put(value); } public static double ReadDouble(ByteBuffer buffer) { - return buffer.getDouble(); + return buffer.GetDouble(); + } + + // OTHER + public static long ReadLongAsShortString(ByteBuffer buffer) + { + string value = ReadShortString(buffer); + if ( value == null || value.Length == 0 ) + return 0L; + return Convert.ToInt64(value, CultureInfo.InvariantCulture); } } diff --git a/dotnet/Qpid.Common/Framing/FieldTable.cs b/dotnet/Qpid.Common/Framing/FieldTable.cs index b977bef0ba..fe83fff721 100644 --- a/dotnet/Qpid.Common/Framing/FieldTable.cs +++ b/dotnet/Qpid.Common/Framing/FieldTable.cs @@ -50,10 +50,10 @@ namespace Qpid.Framing /// <exception cref="AMQFrameDecodingException">if there is an error decoding the table</exception> public FieldTable(ByteBuffer buffer, uint length) : this() { - _encodedForm = buffer.slice(); - _encodedForm.limit((int)length); + _encodedForm = buffer.Slice(); + _encodedForm.Limit = (int)length; _encodedSize = length; - buffer.skip((int)length); + buffer.Skip((int)length); } /// <summary> @@ -312,6 +312,7 @@ namespace Qpid.Framing /// <returns>The enumerator object</returns> public IEnumerator GetEnumerator() { + InitMapIfNecessary(); return _properties.GetEnumerator(); } @@ -322,6 +323,7 @@ namespace Qpid.Framing /// <returns>True if the property exists</returns> public bool Contains(string s) { + InitMapIfNecessary(); return _properties.Contains(s); } @@ -332,6 +334,7 @@ namespace Qpid.Framing /// <returns>The internal dictionary</returns> public IDictionary AsDictionary() { + InitMapIfNecessary(); return _properties; } @@ -381,11 +384,11 @@ namespace Qpid.Framing /// <returns>An array of bytes</returns> public byte[] GetDataAsBytes() { - ByteBuffer buffer = ByteBuffer.allocate((int)_encodedSize); + ByteBuffer buffer = ByteBuffer.Allocate((int)_encodedSize); WritePayload(buffer); byte[] result = new byte[_encodedSize]; - buffer.flip(); - buffer.get(result); + buffer.Flip(); + buffer.GetBytes(result); //buffer.Release(); return result; } @@ -527,7 +530,7 @@ namespace Qpid.Framing bool trace = _log.IsDebugEnabled; if ( length > 0 ) { - int expectedRemaining = buffer.remaining() - (int)length; + int expectedRemaining = buffer.Remaining - (int)length; _properties = new LinkedHashtable(); do @@ -540,7 +543,7 @@ namespace Qpid.Framing } _properties.Add(key, value); - } while ( buffer.remaining() > expectedRemaining ); + } while ( buffer.Remaining > expectedRemaining ); _encodedSize = length; } if ( trace ) @@ -595,7 +598,7 @@ namespace Qpid.Framing { if ( _encodedForm != null ) { - buffer.put(_encodedForm); + buffer.Put(_encodedForm); } else if ( _properties != null ) { foreach ( DictionaryEntry de in _properties ) @@ -609,8 +612,8 @@ namespace Qpid.Framing _log.Debug("Writing Property:" + key + " Type:" + value.Type + " Value:" + value.Value); - _log.Debug("Buffer Position:" + buffer.position() + - " Remaining:" + buffer.remaining()); + _log.Debug("Buffer Position:" + buffer.Position + + " Remaining:" + buffer.Remaining); } //Write the actual parameter name EncodingUtils.WriteShortStringBytes(buffer, key); @@ -623,8 +626,8 @@ namespace Qpid.Framing _log.Debug("Writing Property:" + key + " Type:" + value.Type + " Value:" + value.Value); - _log.Debug("Buffer Position:" + buffer.position() + - " Remaining:" + buffer.remaining()); + _log.Debug("Buffer Position:" + buffer.Position + + " Remaining:" + buffer.Remaining); } } } diff --git a/dotnet/Qpid.Common/Framing/HeartbeatBody.cs b/dotnet/Qpid.Common/Framing/HeartbeatBody.cs index 07f9f345bb..3fdaa7e850 100644 --- a/dotnet/Qpid.Common/Framing/HeartbeatBody.cs +++ b/dotnet/Qpid.Common/Framing/HeartbeatBody.cs @@ -52,7 +52,7 @@ namespace Qpid.Framing if (size > 0) { //allow other implementations to have a payload, but ignore it: - buffer.skip((int) size); + buffer.Skip((int) size); } } diff --git a/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs b/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs index 886fbcee09..280242513c 100644 --- a/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs +++ b/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs @@ -72,12 +72,12 @@ namespace Qpid.Framing { foreach (char c in Header) { - buffer.put((byte) c); + buffer.Put((byte) c); } - buffer.put(ProtocolClass); - buffer.put(ProtocolInstance); - buffer.put(ProtocolMajor); - buffer.put(ProtocolMinor); + buffer.Put(ProtocolClass); + buffer.Put(ProtocolInstance); + buffer.Put(ProtocolMajor); + buffer.Put(ProtocolMinor); } /// <summary> @@ -99,7 +99,7 @@ namespace Qpid.Framing { return MessageDecoderResult.NOT_OK; } - if (inbuf.remaining() < 8) + if (inbuf.Remaining < 8) { return MessageDecoderResult.NEED_DATA; } @@ -108,7 +108,7 @@ namespace Qpid.Framing char[] expected = new char[]{'A', 'M', 'Q', 'P'}; for (int i = 0; i < 4; i++) { - if (((char) inbuf.get()) != expected[i]) + if (((char) inbuf.GetByte()) != expected[i]) { return MessageDecoderResult.NOT_OK; } @@ -120,21 +120,19 @@ namespace Qpid.Framing /// <summary> /// Decodes the specified session. /// </summary> - /// <param name="session">The session.</param> /// <param name="inbuf">The inbuf.</param> - /// <param name="outbuf">The outbuf.</param> + /// <param name="output">The protocol output.</param> /// <returns></returns> - /// <exception cref="ProtocolViolationException">thrown if the frame violates the protocol</exception> public MessageDecoderResult Decode(ByteBuffer inbuf, IProtocolDecoderOutput output) { byte[] header = new byte[4]; - inbuf.get(header); + inbuf.GetBytes(header); ProtocolInitiation pi = new ProtocolInitiation(); pi.Header = new char[]{'A','M','Q','P'}; - pi.ProtocolClass = inbuf.get(); - pi.ProtocolInstance = inbuf.get(); - pi.ProtocolMajor = inbuf.get(); - pi.ProtocolMinor = inbuf.get(); + pi.ProtocolClass = inbuf.GetByte(); + pi.ProtocolInstance = inbuf.GetByte(); + pi.ProtocolMajor = inbuf.GetByte(); + pi.ProtocolMinor = inbuf.GetByte(); output.Write(pi); return MessageDecoderResult.OK; } diff --git a/dotnet/Qpid.Common/Qpid.Common.csproj b/dotnet/Qpid.Common/Qpid.Common.csproj index 626a889e0a..dccadd4667 100644 --- a/dotnet/Qpid.Common/Qpid.Common.csproj +++ b/dotnet/Qpid.Common/Qpid.Common.csproj @@ -89,6 +89,7 @@ <Compile Include="generated\BasicQosBody.cs" />
<Compile Include="generated\BasicQosOkBody.cs" />
<Compile Include="generated\BasicRecoverBody.cs" />
+ <Compile Include="generated\BasicRecoverOkBody.cs" />
<Compile Include="generated\BasicRejectBody.cs" />
<Compile Include="generated\BasicReturnBody.cs" />
<Compile Include="generated\ChannelAlertBody.cs" />
diff --git a/dotnet/Qpid.Common/stylesheets/utils.xsl b/dotnet/Qpid.Common/stylesheets/utils.xsl index 38405ad694..422b757b5c 100644 --- a/dotnet/Qpid.Common/stylesheets/utils.xsl +++ b/dotnet/Qpid.Common/stylesheets/utils.xsl @@ -67,19 +67,19 @@ <xsl:param name="f"/> <xsl:choose> <xsl:when test="$f/@type='char'"> - <xsl:value-of select="concat('buffer.put(', $f/@name, ')')"/> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> </xsl:when> <xsl:when test="$f/@type='octet'"> - <xsl:value-of select="concat('buffer.put(', $f/@name, ')')"/> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> </xsl:when> <xsl:when test="$f/@type='short'"> - <xsl:value-of select="concat('buffer.put(', $f/@name, ')')"/> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> </xsl:when> <xsl:when test="$f/@type='long'"> - <xsl:value-of select="concat('buffer.put(', $f/@name, ')')"/> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> </xsl:when> <xsl:when test="$f/@type='longlong'"> - <xsl:value-of select="concat('buffer.put(', $f/@name, ')')"/> + <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/> </xsl:when> <xsl:when test="$f/@type='shortstr'"> <xsl:value-of select="concat('EncodingUtils.WriteShortStringBytes(buffer, ', $f/@name, ')')"/> @@ -108,16 +108,16 @@ <xsl:value-of select="concat($f/@name, ' = buffer.GetChar()')"/> </xsl:when> <xsl:when test="$f/@type='octet'"> - <xsl:value-of select="concat($f/@name, ' = buffer.get()')"/> + <xsl:value-of select="concat($f/@name, ' = buffer.GetByte()')"/> </xsl:when> <xsl:when test="$f/@type='short'"> - <xsl:value-of select="concat($f/@name, ' = buffer.GetUnsignedShort()')"/> + <xsl:value-of select="concat($f/@name, ' = buffer.GetUInt16()')"/> </xsl:when> <xsl:when test="$f/@type='long'"> - <xsl:value-of select="concat($f/@name, ' = buffer.GetUnsignedInt()')"/> + <xsl:value-of select="concat($f/@name, ' = buffer.GetUInt32()')"/> </xsl:when> <xsl:when test="$f/@type='longlong'"> - <xsl:value-of select="concat($f/@name, ' = buffer.GetUnsignedLong()')"/> + <xsl:value-of select="concat($f/@name, ' = buffer.GetUInt64()')"/> </xsl:when> <xsl:when test="$f/@type='shortstr'"> <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadShortString(buffer)')"/> diff --git a/dotnet/Qpid.Messaging/IHeaders.cs b/dotnet/Qpid.Messaging/IHeaders.cs index fb1514f24d..1a0d187c67 100644 --- a/dotnet/Qpid.Messaging/IHeaders.cs +++ b/dotnet/Qpid.Messaging/IHeaders.cs @@ -32,6 +32,9 @@ namespace Qpid.Messaging byte GetByte(string name); void SetByte(string name, byte value); + //sbyte GetSByte(string name); + //void SetSByte(string name, sbyte value); + short GetShort(string name); void SetShort(string name, short value); diff --git a/dotnet/Qpid.NET.sln b/dotnet/Qpid.NET.sln index 33abed66bd..5d302a5a68 100644 --- a/dotnet/Qpid.NET.sln +++ b/dotnet/Qpid.NET.sln @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Sasl", "Qpid.Sasl\Qpid EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Sasl.Tests", "Qpid.Sasl.Tests\Qpid.Sasl.Tests.csproj", "{587B3520-EBB9-41ED-B019-E96116B651CE}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Buffer.Tests", "Qpid.Buffer.Tests\Qpid.Buffer.Tests.csproj", "{74640962-99D0-4D06-B57A-9CD66517CF52}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -60,6 +62,10 @@ Global {587B3520-EBB9-41ED-B019-E96116B651CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{587B3520-EBB9-41ED-B019-E96116B651CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{587B3520-EBB9-41ED-B019-E96116B651CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
|
