using System; namespace Cosmos.Core { /// /// ManagedMemoryBlock class. Used to read and write a managed memory block. /// public unsafe class ManagedMemoryBlock { private byte[] memory; /// /// Offset. /// public UInt32 Offset; /// /// Size. /// public UInt32 Size; /// /// Create a new buffer with the given size, not aligned /// /// Size of buffer public ManagedMemoryBlock(UInt32 size) : this(size, 1, false) { } /// /// Create a new buffer with the given size, aligned on the byte boundary specified /// /// Size of buffer /// Byte Boundary alignment public ManagedMemoryBlock(UInt32 size, byte alignment) : this(size, alignment, true) { } /// /// Create a new buffer with the given size, and aligned on the byte boundary if align is true /// /// Size of buffer /// Byte Boundary alignment /// true if buffer should be aligned, false otherwise public ManagedMemoryBlock(UInt32 size, byte alignment, bool align) { memory = new byte[size + alignment - 1]; fixed (byte* bodystart = memory) { Offset = (UInt32)bodystart; Size = size; } if (align == true) { while (this.Offset % alignment != 0) { this.Offset++; } } } /// /// Get or set the byte at the given offset /// /// Address Offset /// Byte value at given offset /// Thrown on invalid offset. public byte this[uint offset] { get { if (offset > Size) throw new ArgumentOutOfRangeException("offset"); return *(byte*)(this.Offset + offset); } set { if (offset < 0 || offset > Size) throw new ArgumentOutOfRangeException("offset"); (*(byte*)(this.Offset + offset)) = value; } } /// /// Read 16-bit from the memory block. /// /// Data offset. /// UInt16 value. /// Thrown if offset if bigger than memory block size. public UInt16 Read16(uint offset) { if (offset > Size) throw new ArgumentOutOfRangeException("offset"); return *(UInt16*)(this.Offset + offset); } /// /// Write 16-bit to the memory block. /// /// Data offset. /// Value to write. /// Thrown if offset if bigger than memory block size or smaller than 0. public void Write16(uint offset, UInt16 value) { if (offset < 0 || offset > Size) throw new ArgumentOutOfRangeException("offset"); (*(UInt16*)(this.Offset + offset)) = value; } /// /// Read 32-bit from the memory block. /// /// Data offset. /// UInt32 value. /// Thrown if offset if bigger than memory block size. public UInt32 Read32(uint offset) { if (offset > Size) throw new ArgumentOutOfRangeException("offset"); return *(UInt32*)(this.Offset + offset); } /// /// Write 32-bit to the memory block. /// /// Data offset. /// Value to write. /// Thrown if offset if bigger than memory block size or smaller than 0. public void Write32(uint offset, UInt32 value) { if (offset < 0 || offset > Size) throw new ArgumentOutOfRangeException("offset"); (*(UInt32*)(this.Offset + offset)) = value; } } }