diff options
| author | Steven Shaw <steshaw@apache.org> | 2006-11-25 22:04:39 +0000 |
|---|---|---|
| committer | Steven Shaw <steshaw@apache.org> | 2006-11-25 22:04:39 +0000 |
| commit | 7c1f9158be7a5d1124a48f42f8d7dcfb6d5df2a6 (patch) | |
| tree | 3122525268281cd9df870e0a9cb309ee7410a424 /dotnet/Qpid.Buffer/HeapByteBuffer.cs | |
| parent | 8f32ca18d5281eaa5baafa769c99fa70c830b14f (diff) | |
| download | qpid-python-7c1f9158be7a5d1124a48f42f8d7dcfb6d5df2a6.tar.gz | |
QPID-128 Initial import of the C# sources.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@479211 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'dotnet/Qpid.Buffer/HeapByteBuffer.cs')
| -rw-r--r-- | dotnet/Qpid.Buffer/HeapByteBuffer.cs | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/dotnet/Qpid.Buffer/HeapByteBuffer.cs b/dotnet/Qpid.Buffer/HeapByteBuffer.cs new file mode 100644 index 0000000000..03dbd58bff --- /dev/null +++ b/dotnet/Qpid.Buffer/HeapByteBuffer.cs @@ -0,0 +1,390 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +using System; +using System.Text; + +namespace Qpid.Buffer +{ + public class HeapByteBuffer : ByteBuffer + { + private byte[] _underlyingData; + + /// <summary> + /// The position of the next value to be read or written + /// </summary> + private int _position; + + /// <summary> + /// The index of the first element that should not be read or written + /// </summary> + private int _limit; + + public HeapByteBuffer(int size) : this(new byte[size], 0) + { + } + + private HeapByteBuffer(byte[] bytes, int length) + { + _underlyingData = bytes; + _limit = bytes.Length; + _position = length; + } + + public override int Capacity + { + get + { + return _underlyingData.Length; + } + } + + public override int Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + /// <summary> + /// Sets this buffer's limit. If the position is larger than the new limit then it is set to the new limit. + /// </summary> + /// <value>The new limit value; must be non-negative and no larger than this buffer's capacity</value> + public override int Limit + { + get + { + return _limit; + } + set + { + if (value < 0) + { + throw new ArgumentException("Limit must not be negative"); + } + if (value > Capacity) + { + throw new ArgumentException("Limit must not be greater than Capacity"); + } + _limit = value; + if (_position > value) + { + _position = value; + } + } + } + + /// <summary> + /// Returns the number of elements between the current position and the limit + /// </summary> + /// <value>The number of elements remaining in this buffer</value> + public override int Remaining + { + get + { + return (_limit - _position); + } + } + + public override void Clear() + { + _position = 0; + _limit = Capacity; + } + + public override void Flip() + { + _limit = _position; + _position = 0; + } + + public override void Rewind() + { + _position = 0; + } + + public override byte[] ToByteArray() + { + return _underlyingData; + } + + private void CheckSpace(int size) + { + if (_position + size > _limit) + { + throw new BufferOverflowException("Attempt to write " + size + " byte(s) to buffer where position is " + _position + + " and limit is " + _limit); + } + } + + private void CheckSpaceForReading(int size) + { + if (_position + size > _limit) + { + throw new BufferUnderflowException("Attempt to read " + size + " byte(s) to buffer where position is " + _position + + " and limit is " + _limit); + } + } + + /// <summary> + /// Writes the given byte into this buffer at the current position, and then increments the position. + /// </summary> + /// <param name="data">The byte to be written</param> + /// <exception cref="BufferOverflowException">If this buffer's current position is not smaller than its limit</exception> + public override void Put(byte data) + { + CheckSpace(1); + _underlyingData[_position++] = data; + } + + /// <summary> + /// Writes all the data in the given byte array into this buffer at the current + /// position and then increments the position. + /// </summary> + /// <param name="data">The data to copy.</param> + /// <exception cref="BufferOverflowException">If this buffer's current position plus the array length is not smaller than its limit</exception> + public override void Put(byte[] data) + { + Put(data, 0, data.Length); + } + + public override void Put(byte[] data, int offset, int size) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + CheckSpace(size); + Array.Copy(data, offset, _underlyingData, _position, size); + _position += size; + } + + /// <summary> + /// Writes the given ushort into this buffer at the current position, and then increments the position. + /// </summary> + /// <param name="data">The ushort to be written</param> + public override void Put(ushort data) + { + CheckSpace(2); + _underlyingData[_position++] = (byte) (data >> 8); + _underlyingData[_position++] = (byte) data; + } + + public override void Put(uint data) + { + CheckSpace(4); + _underlyingData[_position++] = (byte) (data >> 24); + _underlyingData[_position++] = (byte) (data >> 16); + _underlyingData[_position++] = (byte) (data >> 8); + _underlyingData[_position++] = (byte) data; + } + + public override void Put(ulong data) + { + CheckSpace(8); + _underlyingData[_position++] = (byte) (data >> 56); + _underlyingData[_position++] = (byte) (data >> 48); + _underlyingData[_position++] = (byte) (data >> 40); + _underlyingData[_position++] = (byte) (data >> 32); + _underlyingData[_position++] = (byte) (data >> 24); + _underlyingData[_position++] = (byte) (data >> 16); + _underlyingData[_position++] = (byte) (data >> 8); + _underlyingData[_position++] = (byte) data; + } + + /// <summary> + /// Read the byte at the current position and increment the position + /// </summary> + /// <returns>a byte</returns> + /// <exception cref="BufferUnderflowException">if there are no bytes left to read</exception> + public override byte Get() + { + CheckSpaceForReading(1); + return _underlyingData[_position++]; + } + + /// <summary> + /// Reads bytes from the buffer into the supplied array + /// </summary> + /// <param name="destination">The destination array. The array must not + /// be bigger than the remaining space in the buffer, nor can it be null.</param> + public override void Get(byte[] destination) + { + if (destination == null) + { + throw new ArgumentNullException("destination"); + } + int len = destination.Length; + CheckSpaceForReading(len); + Array.Copy(_underlyingData, _position, destination, 0, len); + _position += len; + } + + /// <summary> + /// Reads and returns an unsigned short (two bytes, big endian) from this buffer + /// </summary> + /// <returns>an unsigned short</returns> + /// <exception cref="BufferUnderflowException">If there are fewer than two bytes remaining in this buffer</exception> + public override ushort GetUnsignedShort() + { + CheckSpaceForReading(2); + byte upper = _underlyingData[_position++]; + byte lower = _underlyingData[_position++]; + return (ushort) ((upper << 8) + lower); + } + + /// <summary> + /// Reads and returns an unsigned int (four bytes, big endian) from this buffer + /// </summary> + /// <returns>an unsigned integer</returns> + /// <exception cref="BufferUnderflowException">If there are fewer than four bytes remaining in this buffer</exception> + public override uint GetUnsignedInt() + { + CheckSpaceForReading(4); + byte b1 = _underlyingData[_position++]; + byte b2 = _underlyingData[_position++]; + byte b3 = _underlyingData[_position++]; + byte b4 = _underlyingData[_position++]; + return (uint) ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4); + } + + public override ulong GetUnsignedLong() + { + CheckSpaceForReading(8); + byte b1 = _underlyingData[_position++]; + byte b2 = _underlyingData[_position++]; + byte b3 = _underlyingData[_position++]; + byte b4 = _underlyingData[_position++]; + byte b5 = _underlyingData[_position++]; + byte b6 = _underlyingData[_position++]; + byte b7 = _underlyingData[_position++]; + byte b8 = _underlyingData[_position++]; + return (ulong)((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32) + (b5 << 24) + + (b6 << 16) + (b7 << 8) + b8); + } + + public override string GetString(uint length, Encoding encoder) + { + CheckSpaceForReading((int)length); + string result = encoder.GetString(_underlyingData, _position, (int)length); + _position += (int)length; + return result; + } + + public override void Acquire() + { + } + + public override void Release() + { + } + + public override bool IsAutoExpand + { + get { return false; } + set { } + } + + public override void Expand(int expectedRemaining) + { + throw new NotImplementedException(); + } + + public override void Expand(int pos, int expectedRemaining) + { + throw new NotImplementedException(); + } + + public override bool Pooled + { + get { return false; } + set { } + } + + public void Mark() + { + throw new NotImplementedException(); + } + + public void Reset() + { + throw new NotImplementedException(); + } + + public override byte Get(int index) + { + throw new NotImplementedException(); + } + + public override void Put(ByteBuffer src) + { + if (src == this) + { + throw new ArgumentException("Cannot copy self into self!"); + } + + HeapByteBuffer sb; + if (src is HeapByteBuffer) + { + sb = (HeapByteBuffer) src; + } + else + { + sb = (HeapByteBuffer)((RefCountingByteBuffer) src).Buf; + } + int n = sb.Remaining; + if (n > Remaining) + { + throw new BufferOverflowException("Not enought capacity in this buffer for " + n + " elements - only " + Remaining + " remaining"); + } + Array.Copy(sb._underlyingData, sb._position, _underlyingData, _position, n); + sb._position += n; + _position += n; + } + + public override void Compact() + { + if (Remaining > 0) + { + if (_position > 0) + { + Array.Copy(_underlyingData, _position, _underlyingData, 0, Remaining); + } + _position = Remaining; + } + else + { + _position = 0; + } + _limit = Capacity; + } + + public static HeapByteBuffer wrap(byte[] bytes, int length) + { + return new HeapByteBuffer(bytes, length); + } + } +} + |
