156 lines
3.8 KiB
C#
156 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace BizHawk.Emulation.DiscSystem
|
|
{
|
|
/// <summary>
|
|
/// Helper class to convert big and little endian numbers from a byte
|
|
/// array to a value.
|
|
///
|
|
/// This code was modified from the endian bit converter presented by
|
|
/// Robert Unoki in his blog post:
|
|
/// http://blogs.msdn.com/robunoki/archive/2006/04/05/568737.aspx
|
|
///
|
|
/// I have added support for more data types and the ability to
|
|
/// specify an offset into the array to be converted where the value
|
|
/// begins.
|
|
/// </summary>
|
|
public class EndianBitConverter {
|
|
#region Static Constructors
|
|
|
|
/// <summary>
|
|
/// Build a converter from little endian to the system endian-ness.
|
|
/// </summary>
|
|
/// <returns>The converter</returns>
|
|
public static EndianBitConverter CreateForLittleEndian() {
|
|
return new EndianBitConverter(!BitConverter.IsLittleEndian);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Build a converter from big endian to the system endian-ness.
|
|
/// </summary>
|
|
/// <returns>The converter</returns>
|
|
public static EndianBitConverter CreateForBigEndian() {
|
|
return new EndianBitConverter(BitConverter.IsLittleEndian);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Properties
|
|
|
|
/// <summary>
|
|
/// Keep track of whether we need to swap the bytes or not
|
|
/// </summary>
|
|
private bool swap;
|
|
|
|
#endregion
|
|
|
|
#region Private Constructor
|
|
|
|
/// <summary>
|
|
/// Create the converter with the given endian-ness.
|
|
/// </summary>
|
|
/// <param name="swapBytes">Whether or not to swap bytes.</param>
|
|
private EndianBitConverter(bool swapBytes) {
|
|
swap = swapBytes;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 16-bit
|
|
|
|
public Int16 ToInt16(byte[] data) {
|
|
return ToInt16(data, 0);
|
|
}
|
|
public Int16 ToInt16(byte[] data, int offset) {
|
|
byte[] corrected;
|
|
if (swap) {
|
|
corrected = (byte[])data.Clone();
|
|
Array.Reverse(corrected, offset, 2);
|
|
}
|
|
else {
|
|
corrected = data;
|
|
}
|
|
return BitConverter.ToInt16(corrected, offset);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 32-bit
|
|
|
|
public Int32 ToInt32(byte[] data) {
|
|
return ToInt32(data, 0);
|
|
}
|
|
public Int32 ToInt32(byte[] data, int offset) {
|
|
byte[] corrected;
|
|
if (swap) {
|
|
corrected = (byte[])data.Clone();
|
|
Array.Reverse(corrected, offset, 4);
|
|
}
|
|
else {
|
|
corrected = data;
|
|
}
|
|
return BitConverter.ToInt32(corrected, offset);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 64-bit
|
|
|
|
public Int64 ToInt64(byte[] data) {
|
|
return ToInt64(data, 0);
|
|
}
|
|
public Int64 ToInt64(byte[] data, int offset) {
|
|
byte[] corrected;
|
|
if (swap) {
|
|
corrected = (byte[])data.Clone();
|
|
Array.Reverse(corrected, offset, 8);
|
|
}
|
|
else {
|
|
corrected = data;
|
|
}
|
|
return BitConverter.ToInt64(corrected, offset);
|
|
}
|
|
|
|
#endregion
|
|
|
|
// (asni 20171013) - Some methods I wrote that have been shoehorned in from another project to speed up development time
|
|
// If these are offensive in any way, tell me I suck and that I need to do more work with existing methods
|
|
#region Misc
|
|
|
|
/// <summary>
|
|
/// Returns a byte array of any length
|
|
/// Not really anything endian going on, but I struggled to find a better place for it
|
|
/// </summary>
|
|
public byte[] ReadBytes(byte[] buffer, int offset, int length)
|
|
{
|
|
return buffer.Skip(offset).Take(length).ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an int32 value from any size byte array
|
|
/// (careful, data may/will be truncated)
|
|
/// </summary>
|
|
public int ReadIntValue(byte[] buffer, int offset, int length)
|
|
{
|
|
var bytes = buffer.Skip(offset).Take(length).ToArray();
|
|
|
|
if (swap)
|
|
Array.Reverse(bytes);
|
|
|
|
if (length == 1)
|
|
return bytes.FirstOrDefault();
|
|
|
|
if (length == 2)
|
|
return BitConverter.ToInt16(bytes, 0);
|
|
|
|
int result = BitConverter.ToInt32(bytes, 0);
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|