Just thought I'd put this class here as it might help someone that comes across this in a search
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace MapCore
{
internal static class ByteManager
{
public static byte[] GetBytes(object input)
{
//Declare variables
int size;
byte[] result;
IntPtr resultPtr;
//Set the size of array
size = Marshal.SizeOf(input);
//Setup result array
result = new byte[size];
//Setup the result pointer
resultPtr = Marshal.AllocHGlobal(size);
//Copy the structure to the pointer
Marshal.StructureToPtr(input, resultPtr, true);
//Copy the pointer memory into the result array
Marshal.Copy(resultPtr, result, 0, size);
//Free up the used memory
Marshal.FreeHGlobal(resultPtr);
//return the result
return result;
}
public static T FromBytes<T>(byte[] input)
{
//Decalre variables
int size;
IntPtr inputPtr;
T result;
//Create new instance of result
result = Activator.CreateInstance<T>();
//Get a size
size = Marshal.SizeOf(result);
//alocate memory
inputPtr = Marshal.AllocHGlobal(size);
//copy over the byte array into the pointer
Marshal.Copy(input, 0, inputPtr, size);
//Setup the result object
result = (T)Marshal.PtrToStructure(inputPtr, result.GetType());
//remove the pointer from memory
Marshal.FreeHGlobal(inputPtr);
//return the result
return result;
}
}
}
Basically just converts any object into a byte array and back again
there are no null checks though so best you handle that before calling it xD
Edit
---------------------
Here's an example of me using this to create a DMap from bytes and turn a DMap into bytes
Code:
public static byte[] GetBytes(DMapData input)
{
//Declare variables
List<byte>
result;
byte[]
bufferOne,
bufferTwo;
//setup result list
result = new List<byte>();
//Get the input data
bufferOne = ByteManager.GetBytes(input);
//Setup second buffer
bufferTwo = new byte[bufferOne.Length - 4];
//Copy over the array
Array.Copy(bufferOne, bufferTwo, bufferTwo.Length);
//add buffer to list
result.AddRange(bufferTwo);
//Cycle through each tile
for (int tileIndex = 0; tileIndex < input._tiles.Length; tileIndex++)
{
//Add bytes of tile data to list
result.AddRange(ByteManager.GetBytes(input._tiles[tileIndex]));
}
//return result
return result.ToArray();
}
public byte[] GetBytes()
{
//return bytes of this structure
return GetBytes(this);
}
public void FromBytes(byte[] input)
{
//Declare variables
byte[]
buffer;
DMapData
tempData;
int
position = 0,
temp,
size;
//setup second input array
buffer = new byte[Marshal.SizeOf(typeof(DMapData))];
//Copy over array
Array.Copy(input, buffer, buffer.Length-4);
//Add to the position
position += buffer.Length - 4;
//Get dmap data
tempData = ByteManager.FromBytes<DMapData>(buffer);
//Setup tiles array
tempData._tiles = new ITile[tempData._width * tempData._height];
//Cycle through each tile
for (int tileIndex = 0; tileIndex < tempData._tiles.Length; tileIndex++)
{
//If there isn't enough bytes for expanded type
if (input.Length - position - 6 >= 0)
{
//Get the int16 after the 6 bytes (determines if there is an object there)
temp = BitConverter.ToInt16(input, position + 6);
}
else { temp = 0; }
//Set size
size = temp > byte.MaxValue ?
Marshal.SizeOf(typeof(TileExpandedData)) :
Marshal.SizeOf(typeof(TileData));
//Set the buffer
Array.Copy(input, position, buffer, 0, size);
//Determine type of tile data
if (temp > byte.MaxValue)
{
//load current tile as an expanded type
tempData._tiles[tileIndex] = ByteManager.FromBytes<TileExpandedData>(buffer);
}
else
{
//Load current tile as a regular type
tempData._tiles[tileIndex] = ByteManager.FromBytes<TileData>(buffer);
}
//increase position
position += size;
}
this = tempData;
}