Skip to content

Commit

Permalink
Allow advancing ByteQueue and Peeking blocks of data
Browse files Browse the repository at this point in the history
  • Loading branch information
NZSmartie committed Dec 19, 2017
1 parent 7e0bc60 commit f13b3ec
Showing 1 changed file with 103 additions and 72 deletions.
175 changes: 103 additions & 72 deletions src/CoAPNet/Utils/ByteQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,40 +33,42 @@ namespace CoAPNet.Utils
/// <summary>
/// Defines a class that represents a resizable circular byte queue.
/// </summary>
public sealed class ByteQueue
internal sealed class ByteQueue
{
// Private fields
private int fHead;
private int fTail;
private int fSize;
private int fSizeUntilCut;
private byte[] fInternalBuffer;
private int _head;
private int _tail;
private int _size;
private int _sizeUntilCut;
private byte[] _internalBuffer;

private const int _bufferBlockSize = 2048; // must be a power of 2

/// <summary>
/// Gets the length of the byte queue
/// </summary>
public int Length
{
get { return fSize; }
get { return _size; }
}

/// <summary>
/// Constructs a new instance of a byte queue.
/// </summary>
public ByteQueue()
{
fInternalBuffer = new byte[2048];
_internalBuffer = new byte[_bufferBlockSize];
}

/// <summary>
/// Clears the byte queue
/// </summary>
internal void Clear()
{
fHead = 0;
fTail = 0;
fSize = 0;
fSizeUntilCut = fInternalBuffer.Length;
_head = 0;
_tail = 0;
_size = 0;
_sizeUntilCut = _internalBuffer.Length;
}

/// <summary>
Expand All @@ -76,22 +78,22 @@ internal void Clear(int size)
{
lock (this)
{
if (size > fSize)
size = fSize;
if (size > _size)
size = _size;

if (size == 0)
return;

fHead = (fHead + size) % fInternalBuffer.Length;
fSize -= size;
_head = (_head + size) % _internalBuffer.Length;
_size -= size;

if (fSize == 0)
if (_size == 0)
{
fHead = 0;
fTail = 0;
_head = 0;
_tail = 0;
}

fSizeUntilCut = fInternalBuffer.Length - fHead;
_sizeUntilCut = _internalBuffer.Length - _head;
return;
}
}
Expand All @@ -103,22 +105,22 @@ private void SetCapacity(int capacity)
{
byte[] newBuffer = new byte[capacity];

if (fSize > 0)
if (_size > 0)
{
if (fHead < fTail)
if (_head < _tail)
{
Buffer.BlockCopy(fInternalBuffer, fHead, newBuffer, 0, fSize);
Buffer.BlockCopy(_internalBuffer, _head, newBuffer, 0, _size);
}
else
{
Buffer.BlockCopy(fInternalBuffer, fHead, newBuffer, 0, fInternalBuffer.Length - fHead);
Buffer.BlockCopy(fInternalBuffer, 0, newBuffer, fInternalBuffer.Length - fHead, fTail);
Buffer.BlockCopy(_internalBuffer, _head, newBuffer, 0, _internalBuffer.Length - _head);
Buffer.BlockCopy(_internalBuffer, 0, newBuffer, _internalBuffer.Length - _head, _tail);
}
}

fHead = 0;
fTail = fSize;
fInternalBuffer = newBuffer;
_head = 0;
_tail = _size;
_internalBuffer = newBuffer;
}


Expand All @@ -135,31 +137,31 @@ internal void Enqueue(byte[] buffer, int offset, int size)

lock (this)
{
if ((fSize + size) > fInternalBuffer.Length)
SetCapacity((fSize + size + 2047) & ~2047);
if ((_size + size) > _internalBuffer.Length)
SetCapacity((_size + size + (_bufferBlockSize - 1)) & ~(_bufferBlockSize - 1));

if (fHead < fTail)
if (_head < _tail)
{
int rightLength = (fInternalBuffer.Length - fTail);
int rightLength = (_internalBuffer.Length - _tail);

if (rightLength >= size)
{
Buffer.BlockCopy(buffer, offset, fInternalBuffer, fTail, size);
Buffer.BlockCopy(buffer, offset, _internalBuffer, _tail, size);
}
else
{
Buffer.BlockCopy(buffer, offset, fInternalBuffer, fTail, rightLength);
Buffer.BlockCopy(buffer, offset + rightLength, fInternalBuffer, 0, size - rightLength);
Buffer.BlockCopy(buffer, offset, _internalBuffer, _tail, rightLength);
Buffer.BlockCopy(buffer, offset + rightLength, _internalBuffer, 0, size - rightLength);
}
}
else
{
Buffer.BlockCopy(buffer, offset, fInternalBuffer, fTail, size);
Buffer.BlockCopy(buffer, offset, _internalBuffer, _tail, size);
}

fTail = (fTail + size) % fInternalBuffer.Length;
fSize += size;
fSizeUntilCut = fInternalBuffer.Length - fHead;
_tail = (_tail + size) % _internalBuffer.Length;
_size += size;
_sizeUntilCut = _internalBuffer.Length - _head;
}
}

Expand All @@ -174,45 +176,74 @@ internal int Dequeue(byte[] buffer, int offset, int size)
{
lock (this)
{
if (size > fSize)
size = fSize;
size = PeekInternal(buffer, offset, size);
AdvanceQueueInternal(size);
return size;
}
}

if (size == 0)
return 0;
internal void AdvanceQueue(int bytes)
{
lock (this)
AdvanceQueueInternal(bytes);
}

if (fHead < fTail)
{
Buffer.BlockCopy(fInternalBuffer, fHead, buffer, offset, size);
}
else
{
int rightLength = (fInternalBuffer.Length - fHead);
private void AdvanceQueueInternal(int bytes)
{
_head = (_head + bytes) % _internalBuffer.Length;
_size -= bytes;

if (rightLength >= size)
{
Buffer.BlockCopy(fInternalBuffer, fHead, buffer, offset, size);
}
else
{
Buffer.BlockCopy(fInternalBuffer, fHead, buffer, offset, rightLength);
Buffer.BlockCopy(fInternalBuffer, 0, buffer, offset + rightLength, size - rightLength);
}
}
if (_size == 0)
{
_head = 0;
_tail = 0;
}

fHead = (fHead + size) % fInternalBuffer.Length;
fSize -= size;
_sizeUntilCut = _internalBuffer.Length - _head;
}

if (fSize == 0)
/// <summary>
/// Dequeues a buffer from the queue
/// </summary>
/// <param name="buffer">Buffer to enqueue</param>
/// <param name="offset">The zero-based byte offset in the buffer</param>
/// <param name="size">The number of bytes to dequeue</param>
/// <returns>Number of bytes dequeued</returns>
internal int Peek(byte[] buffer, int offset, int size)
{
lock (this)
return PeekInternal(buffer, offset, size);
}

private int PeekInternal(byte[] buffer, int offset, int size)
{
if (size > _size)
size = _size;

if (size == 0)
return 0;

if (_head < _tail)
{
Buffer.BlockCopy(_internalBuffer, _head, buffer, offset, size);
}
else
{
int rightLength = (_internalBuffer.Length - _head);

if (rightLength >= size)
{
fHead = 0;
fTail = 0;
Buffer.BlockCopy(_internalBuffer, _head, buffer, offset, size);
}
else
{
Buffer.BlockCopy(_internalBuffer, _head, buffer, offset, rightLength);
Buffer.BlockCopy(_internalBuffer, 0, buffer, offset + rightLength, size - rightLength);
}

fSizeUntilCut = fInternalBuffer.Length - fHead;
return size;
}
}

return size;
}

/// <summary>
/// Peeks a byte with a relative index to the fHead
Expand All @@ -222,9 +253,9 @@ internal int Dequeue(byte[] buffer, int offset, int size)
/// <returns>The byte peeked</returns>
private byte PeekOne(int index)
{
return index >= fSizeUntilCut
? fInternalBuffer[index - fSizeUntilCut]
: fInternalBuffer[fHead + index];
return index >= _sizeUntilCut
? _internalBuffer[index - _sizeUntilCut]
: _internalBuffer[_head + index];
}


Expand Down

0 comments on commit f13b3ec

Please sign in to comment.