You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2007/02/26 18:46:12 UTC
svn commit: r511923 [2/4] - in /incubator/qpid/trunk/qpid/dotnet: ./
Qpid.Buffer.Tests/ Qpid.Buffer.Tests/Properties/ Qpid.Buffer/
Qpid.Client.Tests/ Qpid.Client/ Qpid.Client/Client/
Qpid.Client/Client/Message/ Qpid.Client/Client/Transport/Socket/Block...
Modified: incubator/qpid/trunk/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs?view=diff&rev=511923&r1=511922&r2=511923
==============================================================================
--- incubator/qpid/trunk/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs (original)
+++ incubator/qpid/trunk/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs Mon Feb 26 09:46:07 2007
@@ -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>
[... 534 lines stripped ...]