|
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace Buffers
{
[Serializable]
class WordBuffer : IEquatable<WordBuffer>
{
#region Constants
const int cntMinNumBytesPerWord = 1;
const int cntMaxNumBytesPerWord = 8;
#endregion
#region Private members
bool locked;
int numWords;
int numBytesPerWord;
long defaultValue;
byte[] defaultValueInBytes;
byte[] buffer;
#endregion
#region Constructor
public WordBuffer(int numWords, int numBytesPerWord, long defaultValue)
{
if(numBytesPerWord<cntMinNumBytesPerWord || numBytesPerWord>cntMaxNumBytesPerWord)
throw new ArgumentOutOfRangeException("numBytesPerWord",
string.Format(CultureInfo.InvariantCulture, StringResources.ArgumentOutOfRangeMessage, "numBytesPerWord",
numBytesPerWord, cntMinNumBytesPerWord, cntMaxNumBytesPerWord));
this.numWords = numWords;
this.numBytesPerWord = numBytesPerWord;
// Default value as a byte array
long bwValue = defaultValue;
defaultValueInBytes = new byte[numBytesPerWord];
for(int i=0; i<numBytesPerWord; i++)
{
defaultValueInBytes[i] = (byte)bwValue;
bwValue>>=8;
}
// Default value casted to the number of bytes
for(int i=numBytesPerWord-1; i>=0; i--)
this.defaultValue = (this.defaultValue<<8) + defaultValueInBytes[i];
}
#endregion
#region Properties
/// <summary>
/// Returns true if no data has been written in the buffer (so the buffer is not allocated)
/// </summary>
public bool IsEmpty
{
get { return buffer==null; }
}
/// <summary>
/// Returns true if the buffer is locked (readonly)
/// </summary>
public bool IsLocked
{
get { return locked; }
}
#endregion
#region Public Methods
/// <summary>
/// Gets the byte[] as an integer value depending on the numBytesPerWord
/// </summary>
public long GetIntegerData(int byteOffset)
{
if(buffer==null)
{
return defaultValue;
}
else
{
switch(numBytesPerWord)
{
case 1:
return (long)buffer[byteOffset];
case 2:
return (long)BitConverter.ToUInt16(buffer, byteOffset);
case 4:
return (long)BitConverter.ToUInt32(buffer, byteOffset);
default:
long data = 0;
for(int i=numBytesPerWord-1; i>=0; i--)
data = (data<<8) + buffer[byteOffset+i];
return data;
}
}
}
/// <summary>
/// Sets the byte[] as an integer value depending on the numBytesPerWord
/// </summary>
public void SetIntegerData(int byteOffset, long value)
{
if(IsLocked)
throw new BufferIsReadOnlyException();
if(buffer==null)
AllocateBuffer();
Buffer.BlockCopy(BitConverter.GetBytes(value), 0, buffer, byteOffset, numBytesPerWord);
}
/// <summary>
/// Locks the buffer so it'll be read only
/// </summary>
public void Lock()
{
locked = true;
}
/// <summary>
/// Frees the memory used by the buffer (all data is lost)
/// </summary>
public void Free()
{
buffer = null;
}
#endregion
#region Private methods
private void AllocateBuffer()
{
buffer = new byte[numWords*numBytesPerWord];
// Initialize them with the default word value
int offset = 0;
for(int i=0; i<numWords; i++)
{
Buffer.BlockCopy(defaultValueInBytes, 0, buffer, offset, numBytesPerWord);
offset+=numBytesPerWord;
}
}
#endregion
#region IEquatable<ByteBuffer> Members
public bool Equals(WordBuffer other)
{
if(this.numWords!=other.numWords || this.numBytesPerWord!=other.numBytesPerWord)
return false;
if(buffer==null)
return (other.buffer==null);
for(int i = 0; i < buffer.Length; i++)
{
if(buffer[i] != other.buffer[i])
return false;
}
return true;
}
// override object.Equals
public override bool Equals(object obj)
{
if(obj == null || GetType() != obj.GetType())
{
return false;
}
return this.Equals((WordBuffer)obj);
}
// override object.GetHashCode
public override int GetHashCode()
{
return base.GetHashCode();
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I finished my Degree in Industrial Electronics in the year 2000. I worked for 6 years as a Hardware and Software development engineer in Barcelona. On January 2007 I moved to Dublin to work as Software Engineer and I specialised in .NET technologies. Currently I'm consulting for other companies and running my own start up project Trainer Inside (www.trainerinside.com)