135 lines
2.6 KiB
C#
135 lines
2.6 KiB
C#
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
using System;
|
|
|
|
public class ByteBuffer
|
|
{
|
|
private byte[] fData;
|
|
private int fSize; // Amount of fData actually available to the user
|
|
|
|
public ByteBuffer(int initialSize)
|
|
{
|
|
fData = new byte[initialSize];
|
|
fSize = initialSize;
|
|
}
|
|
|
|
public ByteBuffer()
|
|
{
|
|
}
|
|
|
|
public void EnsureSize(int overallSize)
|
|
{
|
|
// Asking for less space than you have does nothing
|
|
if (overallSize < fSize)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Asking for zero when we're empty does nothing
|
|
if (overallSize == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((fData == null) || (fData.Length < overallSize))
|
|
{
|
|
// Not enough room in our current array. Double until we're big enough.
|
|
int newSize = (fData == null) ? overallSize : fData.Length;
|
|
while (newSize < overallSize) { newSize *= 2; }
|
|
byte[] newBuffer = new byte[newSize];
|
|
|
|
if (fData != null)
|
|
{
|
|
int bytesToCopy = overallSize < fSize ? overallSize : fSize;
|
|
Buffer.BlockCopy(fData, 0, newBuffer, 0, bytesToCopy);
|
|
}
|
|
|
|
fData = newBuffer;
|
|
}
|
|
|
|
fSize = overallSize;
|
|
}
|
|
|
|
public void Add(byte[] newData, int offset, int length)
|
|
{
|
|
int previousSize = fSize;
|
|
EnsureSize(previousSize + length);
|
|
Buffer.BlockCopy(newData, offset, fData, previousSize, length);
|
|
}
|
|
|
|
public void Add(byte newByte)
|
|
{
|
|
int previousSize = fSize;
|
|
EnsureSize(previousSize + 1);
|
|
fData[previousSize] = newByte;
|
|
}
|
|
|
|
// WARNING; Do not rely on this being accessible across calls to
|
|
// Add() or EnsureSize()!! Do not index out of bounds!! UNSAFE!
|
|
public byte[] UnderlyingBuffer
|
|
{
|
|
get { return fData; }
|
|
}
|
|
|
|
public byte[] TrimAndCopy(int trimLength)
|
|
{
|
|
return TrimAndCopy(0, trimLength);
|
|
}
|
|
|
|
public byte[] TrimAndCopy(int offset, int trimLength)
|
|
{
|
|
byte[] retval = new byte[trimLength];
|
|
Buffer.BlockCopy(fData, offset, retval, 0, trimLength);
|
|
return retval;
|
|
}
|
|
|
|
public int Size
|
|
{
|
|
get
|
|
{
|
|
if (fData != null)
|
|
{
|
|
return fSize;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public byte this[int index]
|
|
{
|
|
get
|
|
{
|
|
ValidateIndex(index);
|
|
return fData[index];
|
|
}
|
|
|
|
set
|
|
{
|
|
ValidateIndex(index);
|
|
fData[index] = value;
|
|
}
|
|
}
|
|
|
|
private void ValidateIndex(int index)
|
|
{
|
|
if (fData == null)
|
|
{
|
|
throw new IndexOutOfRangeException("Buffer currently empty");
|
|
}
|
|
|
|
if ((index < 0) || (index >= fSize))
|
|
{
|
|
throw new IndexOutOfRangeException();
|
|
}
|
|
}
|
|
}
|