summaryrefslogtreecommitdiff
path: root/qpid/dotnet/Qpid.Buffer
diff options
context:
space:
mode:
authorRobert Greig <rgreig@apache.org>2007-02-26 17:46:07 +0000
committerRobert Greig <rgreig@apache.org>2007-02-26 17:46:07 +0000
commita019367dc582d61fa3739f385592c0baf9b972b8 (patch)
tree5ce170123120f788d07d472e2febf6b32f17dc29 /qpid/dotnet/Qpid.Buffer
parent2e9743ac06fc05609155769bf04f4fa442d848c2 (diff)
downloadqpid-python-a019367dc582d61fa3739f385592c0baf9b972b8.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@511923 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/dotnet/Qpid.Buffer')
-rw-r--r--qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs460
-rw-r--r--qpid/dotnet/Qpid.Buffer/BufferDataException.cs54
-rw-r--r--qpid/dotnet/Qpid.Buffer/ByteBuffer.cs3317
-rw-r--r--qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs5
-rw-r--r--qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs190
-rw-r--r--qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs367
-rw-r--r--qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs474
-rw-r--r--qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs25
-rw-r--r--qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj7
-rw-r--r--qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs120
-rw-r--r--qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs181
-rw-r--r--qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs86
12 files changed, 1205 insertions, 4081 deletions
diff --git a/qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs
deleted file mode 100644
index 3a6beabae8..0000000000
--- a/qpid/dotnet/Qpid.Buffer/BaseByteBuffer.cs
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-//package org.apache.mina.common.support;
-//
-//import java.nio.ByteOrder;
-//import java.nio.CharBuffer;
-//import java.nio.DoubleBuffer;
-//import java.nio.FloatBuffer;
-//import java.nio.IntBuffer;
-//import java.nio.LongBuffer;
-//import java.nio.ShortBuffer;
-//
-//import org.apache.mina.common.ByteBuffer;
-//import org.apache.mina.common.ByteBufferAllocator;
-
-namespace Qpid.Buffer
-{
- /// <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/qpid/dotnet/Qpid.Buffer/BufferDataException.cs b/qpid/dotnet/Qpid.Buffer/BufferDataException.cs
deleted file mode 100644
index c76441dde0..0000000000
--- a/qpid/dotnet/Qpid.Buffer/BufferDataException.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-using System;
-using System.Runtime.Serialization;
-
-namespace Qpid.Buffer
-{
- /// <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/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs
index 1a4f0072d6..1bfc749746 100644
--- a/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs
+++ b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs
@@ -19,2367 +19,964 @@
*
*/
using System;
-using System.Text;
namespace Qpid.Buffer
{
- public enum ByteOrder { BigEndian, LittleEndian }
-// /// <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/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs
index 459abc56ef..bf7c738041 100644
--- a/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs
+++ b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs
@@ -49,7 +49,7 @@ namespace Qpid.Buffer
public static string GetHexDump(ByteBuffer input)
{
- int size = input.limit() - input.position();
+ int size = input.Remaining;
if (size == 0)
{
return "empty";
@@ -57,7 +57,7 @@ namespace Qpid.Buffer
StringBuilder output = new StringBuilder(size * 3 - 1);
- byte[] data = input.array();
+ byte[] data = input.Array;
int byteValue = data[0] & 0xFF;
output.Append((char) highDigits[byteValue]);
output.Append((char) lowDigits[byteValue]);
@@ -75,3 +75,4 @@ namespace Qpid.Buffer
}
}
+
diff --git a/qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs b/qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs
deleted file mode 100644
index 6fc46ab156..0000000000
--- a/qpid/dotnet/Qpid.Buffer/ByteBufferProxy.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-using System;
-using System.Text;
-
-namespace Qpid.Buffer
-{
- public class ByteBufferProxy //: ByteBuffer
- {
- protected ByteBuffer _buf;
-
- protected ByteBufferProxy(ByteBuffer buf)
- {
- if (buf == null)
- {
- throw new ArgumentNullException("buf");
- }
- _buf = buf;
- }
-
-
-// public /*override*/ void Acquire()
-// {
-// _buf.Acquire();
-// }
-//
-// public /*override*/ void Release()
-// {
-// _buf.Release();
-// }
-//
-// public /*override*/ int Capacity
-// {
-// get { return _buf.Capacity; }
-// }
-//
-// public /*override*/ bool IsAutoExpand
-// {
-// get { return _buf.IsAutoExpand; }
-// set { _buf.IsAutoExpand = value; }
-// }
-//
-// public /*override*/ void Expand(int expectedRemaining)
-// {
-// _buf.Expand(expectedRemaining);
-// }
-//
-// public /*override*/ void Expand(int pos, int expectedRemaining)
-// {
-// _buf.Expand(pos, expectedRemaining);
-// }
-//
-// public /*override*/ bool Pooled
-// {
-// get { return _buf.Pooled; }
-// set { _buf.Pooled = value; }
-// }
-//
-// public /*override*/ int Position
-// {
-// get { return _buf.Position; }
-// set { _buf.Position = value; }
-// }
-//
-// public /*override*/ int Limit
-// {
-// get { return _buf.Limit; }
-// set { _buf.Limit = value; }
-// }
-//
-// public /*override*/ void Clear()
-// {
-// _buf.Clear();
-// }
-//
-// public /*override*/ void Flip()
-// {
-// _buf.Flip();
-// }
-//
-// public /*override*/ void Rewind()
-// {
-// _buf.Rewind();
-// }
-//
-// public /*override*/ int Remaining
-// {
-// get { return _buf.Remaining; }
-// }
-//
-// public /*override*/ byte Get()
-// {
-// return _buf.Get();
-// }
-//
-// public /*override*/ byte Get(int index)
-// {
-// return _buf.Get(index);
-// }
-//
-// public /*override*/ void Get(byte[] destination)
-// {
-// _buf.Get(destination);
-// }
-//
-// public /*override*/ ushort GetUnsignedShort()
-// {
-// return _buf.GetUnsignedShort();
-// }
-//
-// public /*override*/ uint GetUnsignedInt()
-// {
-// return _buf.GetUnsignedInt();
-// }
-//
-// public /*override*/ ulong GetUnsignedLong()
-// {
-// return _buf.GetUnsignedLong();
-// }
-//
-// public /*override*/ string GetString(uint length, Encoding encoder)
-// {
-// return _buf.GetString(length, encoder);
-// }
-//
-// public /*override*/ void Put(byte data)
-// {
-// _buf.Put(data);
-// }
-//
-// public /*override*/ void Put(byte[] data, int offset, int size)
-// {
-// _buf.Put(data, offset, size);
-// }
-//
-// public /*override*/ void Put(byte[] data)
-// {
-// _buf.Put(data);
-// }
-//
-// public /*override*/ void Put(ushort data)
-// {
-// _buf.Put(data);
-// }
-//
-// public /*override*/ void Put(uint data)
-// {
-// _buf.Put(data);
-// }
-//
-// public /*override*/ void Put(ulong data)
-// {
-// _buf.Put(data);
-// }
-//
-// public /*override*/ void Put(ByteBuffer buf)
-// {
-// _buf.Put(buf);
-// }
-//
-// public /*override*/ void Compact()
-// {
-// _buf.Compact();
-// }
-//
-// public /*override*/ byte[] ToByteArray()
-// {
-// return _buf.ToByteArray();
-// }
- }
-}
-
diff --git a/qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs
deleted file mode 100644
index d2f3ca8a3c..0000000000
--- a/qpid/dotnet/Qpid.Buffer/FixedByteBuffer.cs
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-using System;
-
-namespace Qpid.Buffer
-{
- public class FixedByteBuffer
- {
- private HeapByteBuffer _buf;
-
- public FixedByteBuffer(int capacity)
- {
- _buf = new HeapByteBuffer(capacity);
- }
-
- public FixedByteBuffer(byte[] bytes)
- {
- _buf = HeapByteBuffer.wrap(bytes);
- }
-
- public static FixedByteBuffer wrap(byte[] array)
- {
- return new FixedByteBuffer(array);
- }
-
- public static FixedByteBuffer wrap(byte[] array, int offset, int length)
- {
- throw new NotImplementedException();
- }
-
- public ByteOrder order()
- {
- return ByteOrder.LittleEndian;
- }
-
- public void order(ByteOrder bo)
- {
- // Ignore endianess.
- }
-
- public void compact()
- {
- _buf.Compact();
- }
-
- public char getChar()
- {
- throw new NotImplementedException();
- }
-
- public char getChar(int index)
- {
- throw new NotImplementedException();
- }
-
- public void putChar(char value)
- {
- throw new NotImplementedException();
- }
-
- public void putChar(int index, char value)
- {
- throw new NotImplementedException();
- }
-
- public bool isDirect()
- {
- return false;
- }
-
- public bool isReadOnly()
- {
- throw new NotImplementedException();
- }
-
- public int capacity()
- {
- return _buf.Capacity;
- }
-
- public int limit()
- {
- return _buf.Limit;
- }
-
- public int limit(int limit)
- {
- int previousLimit = _buf.Limit;
- _buf.Limit = limit;
- return previousLimit;
- }
-
- public int position()
- {
- return _buf.Position;
- }
-
- public int position(int newPosition)
- {
- int prev = _buf.Position;
- _buf.Position = newPosition;
- return prev;
- }
-
- public void mark()
- {
- throw new NotImplementedException();
- }
-
- public static FixedByteBuffer allocateDirect(int capacity)
- {
- throw new NotImplementedException();
- }
-
- public static FixedByteBuffer allocate(int capacity)
- {
- return new FixedByteBuffer(capacity);
- }
-
- public void clear()
- {
- _buf.Clear();
- }
-
- public void put(byte b)
- {
- _buf.Put(b);
- }
-
- public void put(int index, byte b)
- {
- throw new NotImplementedException();
- }
-
- public void put(FixedByteBuffer buf)
- {
- _buf.Put(buf.array(), buf.position(), buf.limit() - buf.position());
- }
-
- public FixedByteBuffer duplicate()
- {
- throw new NotImplementedException();
- }
-
- public FixedByteBuffer slice()
- {
- throw new NotImplementedException();
- }
-
- public FixedByteBuffer asReadOnlyBuffer()
- {
- throw new NotImplementedException();
- }
-
- /// <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/qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs
deleted file mode 100644
index f95fe1c241..0000000000
--- a/qpid/dotnet/Qpid.Buffer/HeapByteBuffer.cs
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-using System;
-using System.Text;
-
-namespace Qpid.Buffer
-{
- public class HeapByteBuffer //: ByteBuffer
- {
- private byte[] _underlyingData;
-
- /// <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/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs
index c7c2f563aa..0cc0811a5c 100644
--- a/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs
+++ b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs
@@ -19,32 +19,31 @@
*
*/
+using System;
+
namespace Qpid.Buffer
{
/// <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/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj
index e6bade037b..a03bf348b2 100644
--- a/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj
+++ b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj
@@ -38,18 +38,15 @@
<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/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs
new file mode 100644
index 0000000000..d91f7747d2
--- /dev/null
+++ b/qpid/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/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs b/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs
index 2de3a13560..6933480c92 100644
--- a/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs
+++ b/qpid/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/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs
new file mode 100644
index 0000000000..414da94a8d
--- /dev/null
+++ b/qpid/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
+}