Write a class called ByteArray that implement allocating, reading and writing to an array of bytes. The runtime environment has a limitation. The maximum continuous memory size that it can allocated is 64k bytes. It can allocate many 64K ( or less) chunks.
The ByteArray class should hide this limitation and support allocating arrays larger than 64K as in the following example :
ByteArray ba = new ByteArray (250000); // Create
ba[150000] = 15; // Write byte
byte x = ba[190000]; // Read byte
This question is really asking for if you know how to implement the index. I responded with the following one minute recipe.
class ByteArray
{
byte[] _Byte;
const int _MaxSizeinKB = 64;
const int _MaxSizeInBytes = _MaxSizeinKB * 1024;
public ByteArray(int nLength)
{
if (nLength > _MaxSizeInBytes)
throw new InsufficientMemoryException("Cannot allocate more than " + _MaxSizeinKB.ToString() + "KB");
else
_Byte = new byte[nLength];
}
public byte this[int nIndex]
{
get { return _Byte[nIndex]; }
set { _Byte[nIndex] = value; }
}
}
Usage is as above in the question. Enjoy!
Thanks for pointing out.
I have updated the code the reflect the same.
--EDIT--
This is an update based upon the comment that I received. I missed the last sentence; that is,
The ByteArray class should hide this limitation and support allocating arrays larger than 64kThis update adds rest of the functionality; following is the updated ByteArray class:
class ByteArrayEx
{
private List lstArray = new List();
public int _nSize;
public int _nChunks;
public const int _MaxSizeLimit = 65536;//3;//65536;//64K
public ByteArrayEx(int nSize)
{
_nSize = nSize;
if (nSize > _MaxSizeLimit)
{
//1. Calculate the number of 64K chunks
int nChunks = nSize / _MaxSizeLimit;
//130K; 64K + 64K + 2K
//64 = 130/
//2 = 64k x 2 = 128k
//Remaining = 128 - 130 = 2
//Remaining = nLengh - AllocatedSize
int nAllocatedSize = 0;
//2. Loop through the chunks
for (int i = 0; i < nChunks; i++)
{
//3. Allocate the size
nAllocatedSize = _MaxSizeLimit + nAllocatedSize;
lstArray.Add(new byte[_MaxSizeLimit]);
}
//4. Allocate remaining bytes
int nRemainingBytes = nSize - nAllocatedSize;
if (nRemainingBytes > 0)
lstArray.Add(new byte[nRemainingBytes]);
_nChunks = lstArray.Count;
}
else
lstArray.Add(new byte[nSize]);
}
public byte this[int nIndex]
{
get
{
//1. Get the index of array list item
//2. Convert the incoming index to Index of byte array
int nByteIndex = nIndex % _MaxSizeLimit;
return ((byte[])(lstArray[GetBlockIndex(nIndex)]))[nByteIndex];
}
set
{
//1. Get the index/block of array list
//2. Convert the incoming index to Index of byte array
int nBlockIndex = GetBlockIndex(nIndex);
int nByteIndex = nIndex % _MaxSizeLimit;
((byte[])(lstArray[nBlockIndex]))[nByteIndex] = value;
}
}
///
/// Block, represents the index of List item
///
/// Incoming Index /// Actual Block Index
private int GetBlockIndex(int nIndex)
{
int nAllocatedSize = 0;
//2. Loop through the chunks
int nBlockIndex = 0;
for (int i = 0; i < _nChunks; i++)
{
//3. Allocate the size
nAllocatedSize = _MaxSizeLimit + nAllocatedSize;
if (nIndex <= nAllocatedSize)
{
nBlockIndex = i;
break;
}
}
return nBlockIndex;
}
}
Usage is as follows: ByteArray ba = new ByteArray (250000); // Create
ba[150000] = 15; // Write byte
byte x = ba[190000]; // Read byte
Couple of things to note; the 64K limit that is in the ByteArrayEx class can be anything; for instance:
In case of 64K of it would create single array to contain all the byte array elements.
In case of 128K (64K x 2 = 128K), it will create 2 items in the array list of size 64K each.
In case of 130K (64K x 2 + 2K more = 128K + 2K = 130K) it will create 3 items in the array list; this time, two items of size 64K and third item of size 2K. So array list would contain 3 byte arrays.
Hope you get the idea.
You can change the 64K limit to 32K or 8K or 3K, etc; and it will work as above.
Checkout the output, for the following given input:
class Program
{
static void Main(string[] args)
{
//Test 1
ByteArrayEx baTest1 = new ByteArrayEx(133120);// (64 + 64 + 2) * 1024; //130K or 133120 bytes
baTest1[0] = (byte)'c';//Write
Console.WriteLine(string.Format("Written byte:[{0}]", Convert.ToChar(baTest1[0])));
baTest1[133110] = (byte)'d';//Write more
Console.WriteLine(string.Format("Written byte:[{0}]", Convert.ToChar(baTest1[133110])));
byte r = baTest1[133110];// be[133110];
Console.WriteLine(string.Format("Reading byte:[{0}]", Convert.ToChar(r)));
Console.WriteLine(string.Format("Max Limit: {0}, Size: {1}, Chunks: {2}", ByteArrayEx._MaxSizeLimit,
baTest1._nSize, baTest1._nChunks));
//Test 2
ByteArrayEx byteArray = new ByteArrayEx(250000); // Create
byteArray[150000] = 15; // Write byte
byte x = byteArray[190000]; // Read byte
Console.WriteLine(string.Format("byte:[{0}]", x));
Console.WriteLine(string.Format("Max Limit: {0}, Size: {1}, Chunks: {2}", ByteArrayEx._MaxSizeLimit,
byteArray._nSize, byteArray._nChunks));
Console.ReadKey();
}
}
Note that, I have the List class to demostrate the functionality. You can add any class that provides array like functionality.