diff options
| author | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
|---|---|---|
| committer | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
| commit | 66765100f4257159622cefe57bed50125a5ad017 (patch) | |
| tree | a88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /qpid/dotnet/Qpid.Buffer | |
| parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
| parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
| download | qpid-python-rajith_jms_client.tar.gz | |
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/dotnet/Qpid.Buffer')
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs | 41 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs | 42 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/ByteBuffer.cs | 982 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs | 79 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs | 50 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs | 53 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj | 77 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs | 120 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs | 58 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs | 86 | ||||
| -rw-r--r-- | qpid/dotnet/Qpid.Buffer/default.build | 46 |
11 files changed, 1634 insertions, 0 deletions
diff --git a/qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs b/qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs new file mode 100644 index 0000000000..5a2fff74a7 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs @@ -0,0 +1,41 @@ +/* + * + * 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 Apache.Qpid.Buffer +{ + [Serializable] + public class BufferOverflowException : Exception + { + public BufferOverflowException(string message) : base(message) + { + } + + protected BufferOverflowException(SerializationInfo info, StreamingContext ctxt) + : base(info, ctxt) + { + } + } +} + + + diff --git a/qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs b/qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs new file mode 100644 index 0000000000..13939b77a8 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs @@ -0,0 +1,42 @@ +/* + * + * 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 Apache.Qpid.Buffer +{ + [Serializable] + public class BufferUnderflowException : Exception + { + public BufferUnderflowException(string message) + : base(message) + { + } + + protected BufferUnderflowException(SerializationInfo info, StreamingContext ctxt) + : base(info, ctxt) + { + } + } +} + + + diff --git a/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs new file mode 100644 index 0000000000..67f0edd440 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs @@ -0,0 +1,982 @@ +/* + * + * 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 Apache.Qpid.Buffer +{ + /// <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 new file mode 100644 index 0000000000..4c2856c333 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs @@ -0,0 +1,79 @@ +/* + * + * 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.Text; + +namespace Apache.Qpid.Buffer +{ + public class ByteBufferHexDumper + { + private static byte[] highDigits; + + private static byte[] lowDigits; + + static ByteBufferHexDumper() + { + byte[] digits = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', + (byte)'E', (byte)'F' }; + int i; + byte[] high = new byte[256]; + byte[] low = new byte[256]; + + for (i = 0; i < 256; i++) + { + high[i] = digits[i >> 4]; + low[i] = digits[i & 0x0F]; + } + + highDigits = high; + lowDigits = low; + } + + public static string GetHexDump(ByteBuffer input) + { + int size = input.Remaining; + if (size == 0) + { + return "empty"; + } + + StringBuilder output = new StringBuilder(size * 3 - 1); + + byte[] data = input.Array; + int byteValue = data[0] & 0xFF; + output.Append((char) highDigits[byteValue]); + output.Append((char) lowDigits[byteValue]); + + for (int i = 1 ; i < size; i++) + { + output.Append(' '); + byteValue = data[i] & 0xFF; + output.Append((char) highDigits[byteValue]); + output.Append((char) lowDigits[byteValue]); + } + + return output.ToString(); + } + } +} + + + diff --git a/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs new file mode 100644 index 0000000000..74944f7e69 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs @@ -0,0 +1,50 @@ +/* + * + * 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 Apache.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 : IDisposable + { + /// <summary> + /// Returns the buffer which is capable of the specified size. + /// </summary> + /// <param name="capacity">The capacity of the buffer</param> + /// <returns>A new buffer</returns> + ByteBuffer Allocate(int capacity); + + /// <summary> + /// Wrap the specified byte array in a new buffer + /// </summary> + /// <param name="src">Source array</param> + /// <returns>A new buffer</returns> + ByteBuffer Wrap(byte[] src); + + } // interface IByteBufferAllocator +} + + + diff --git a/qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b692af7ce5 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +/* + * + * 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.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Apache.Qpid.ByteBuffer")] +[assembly: AssemblyDescription("Built from svn revision number: ")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Apache Software Foundation")] +[assembly: AssemblyProduct("Apache.Qpid.ByteBuffer")] +[assembly: AssemblyCopyright("Apache Software Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2b3333e5-03b5-4f00-9215-66009f8a5c47")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("0.5.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj new file mode 100644 index 0000000000..d13f399196 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj @@ -0,0 +1,77 @@ +<!--
+
+ 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.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Buffer</RootNamespace>
+ <AssemblyName>Apache.Qpid.Buffer</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.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.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs new file mode 100644 index 0000000000..956c59aa45 --- /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 Apache.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 new file mode 100644 index 0000000000..e772e59ae3 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs @@ -0,0 +1,58 @@ +/* + * + * 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. + * + */ + +namespace Apache.Qpid.Buffer +{ + /// <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 ByteBuffer Allocate(int capacity) + { + return new SimpleByteBuffer(capacity); + } + + public ByteBuffer Wrap(byte[] src) + { + return new SimpleByteBuffer(src); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + // no need to do anaything + } + + #endregion + + } // class SimpleByteBufferAllocator +} + + + diff --git a/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs new file mode 100644 index 0000000000..890e2a3c7a --- /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 Apache.Qpid.Buffer +{ + internal sealed class SlicedByteBuffer : ByteBuffer + { + private ByteBuffer _buffer; + private int _capacity; + private int _startPos; + + public override int Capacity + { + get { return _capacity; } + } + + public override byte[] Array + { + get { return _buffer.Array; } + } + + /// <summary> + /// Initialize a new instance + /// </summary> + /// <param name="buffer">Underlying byte buffer</param> + internal SlicedByteBuffer(ByteBuffer buffer) + { + _buffer = buffer; + _startPos = buffer.Position; + Position = 0; + _capacity = buffer.Remaining; + Limit = Capacity; + // cannot autoexpand + IsAutoExpand = false; + } + + protected override void DoWrite(int position, byte value) + { + _buffer.Put(_startPos + position, value); + } + + protected override void DoWrite(int position, byte[] src, int offset, int length) + { + _buffer.Put(_startPos + position, src, offset, length); + } + + protected override byte DoReadByte(int position) + { + return _buffer.GetByte(_startPos + position); + } + + protected override void DoReadBytes(int position, byte[] dest, int offset, int length) + { + _buffer.GetBytes(_startPos + position, dest, offset, length); + } + + protected override void DoCompact() + { + throw new NotSupportedException(); + } + + protected override void DoResize(int newSize) + { + throw new NotSupportedException(); + } + } // class SlicedByteBuffer +} diff --git a/qpid/dotnet/Qpid.Buffer/default.build b/qpid/dotnet/Qpid.Buffer/default.build new file mode 100644 index 0000000000..efb5a8fc89 --- /dev/null +++ b/qpid/dotnet/Qpid.Buffer/default.build @@ -0,0 +1,46 @@ +<?xml version="1.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. + +--> + +<project name="Apache.Qpid.Buffer" default="build"> + <!-- + Properties that come from master build file + - build.dir: root directory for build + - build.debug: true if building debug release + - build.defines: variables to define during build + --> + + <target name="build"> + <csc target="library" + define="${build.defines}" + debug="${build.debug}" + unsafe="true" + output="${build.dir}/${project::get-name()}.dll"> + + <sources> + <include name="**/*.cs" /> + </sources> + <references> + </references> + </csc> + </target> +</project> + |
