mirror of
https://github.com/aaru-dps/Aaru.Helpers.git
synced 2025-12-16 19:24:35 +00:00
Code reformat.
This commit is contained in:
28
ArrayFill.cs
28
ArrayFill.cs
@@ -31,27 +31,23 @@ namespace DiscImageChef
|
|||||||
{
|
{
|
||||||
public static partial class ArrayHelpers
|
public static partial class ArrayHelpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Fills an array with the specified value</summary>
|
||||||
/// Fills an array with the specified value
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="destinationArray">Array</param>
|
/// <param name="destinationArray">Array</param>
|
||||||
/// <param name="value">Value</param>
|
/// <param name="value">Value</param>
|
||||||
/// <typeparam name="T">Array type</typeparam>
|
/// <typeparam name="T">Array type</typeparam>
|
||||||
public static void ArrayFill<T>(T[] destinationArray, T value)
|
public static void ArrayFill<T>(T[] destinationArray, T value) => ArrayFill(destinationArray, new[]
|
||||||
{
|
{
|
||||||
// if called with a single value, wrap the value in an array and call the main function
|
value
|
||||||
ArrayFill(destinationArray, new[] {value});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Fills an array with the contents of the specified array</summary>
|
||||||
/// Fills an array with the contents of the specified array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="destinationArray">Array</param>
|
/// <param name="destinationArray">Array</param>
|
||||||
/// <param name="value">Value</param>
|
/// <param name="value">Value</param>
|
||||||
/// <typeparam name="T">Array type</typeparam>
|
/// <typeparam name="T">Array type</typeparam>
|
||||||
public static void ArrayFill<T>(T[] destinationArray, T[] value)
|
public static void ArrayFill<T>(T[] destinationArray, T[] value)
|
||||||
{
|
{
|
||||||
if(destinationArray == null) throw new ArgumentNullException(nameof(destinationArray));
|
if(destinationArray == null)
|
||||||
|
throw new ArgumentNullException(nameof(destinationArray));
|
||||||
|
|
||||||
if(value.Length > destinationArray.Length)
|
if(value.Length > destinationArray.Length)
|
||||||
throw new ArgumentException("Length of value array must not be more than length of destination");
|
throw new ArgumentException("Length of value array must not be more than length of destination");
|
||||||
@@ -68,16 +64,16 @@ namespace DiscImageChef
|
|||||||
Array.Copy(destinationArray, 0, destinationArray, copyLength, destinationArray.Length - copyLength);
|
Array.Copy(destinationArray, 0, destinationArray, copyLength, destinationArray.Length - copyLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a byte array to its hexadecimal representation</summary>
|
||||||
/// Converts a byte array to its hexadecimal representation
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">Byte array</param>
|
/// <param name="array">Byte array</param>
|
||||||
/// <param name="upper"><c>true</c> to use uppercase</param>
|
/// <param name="upper"><c>true</c> to use uppercase</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string ByteArrayToHex(byte[] array, bool upper = false)
|
public static string ByteArrayToHex(byte[] array, bool upper = false)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
for(long i = 0; i < array.LongLength; i++) sb.AppendFormat("{0:x2}", array[i]);
|
|
||||||
|
for(long i = 0; i < array.LongLength; i++)
|
||||||
|
sb.AppendFormat("{0:x2}", array[i]);
|
||||||
|
|
||||||
return upper ? sb.ToString().ToUpper() : sb.ToString();
|
return upper ? sb.ToString().ToUpper() : sb.ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,24 +36,15 @@ namespace DiscImageChef
|
|||||||
{
|
{
|
||||||
public static partial class ArrayHelpers
|
public static partial class ArrayHelpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Checks if an array is null, filled with the NULL byte (0x00) or ASCII whitespace (0x20)</summary>
|
||||||
/// Checks if an array is null, filled with the NULL byte (0x00) or ASCII whitespace (0x20)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">Array</param>
|
/// <param name="array">Array</param>
|
||||||
/// <returns>True if null or whitespace</returns>
|
/// <returns>True if null or whitespace</returns>
|
||||||
public static bool ArrayIsNullOrWhiteSpace(byte[] array)
|
public static bool ArrayIsNullOrWhiteSpace(byte[] array) =>
|
||||||
{
|
array == null || array.All(b => b == 0x00 || b == 0x20);
|
||||||
return array == null || array.All(b => b == 0x00 || b == 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Checks if an array is null or filled with the NULL byte (0x00)</summary>
|
||||||
/// Checks if an array is null or filled with the NULL byte (0x00)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">Array</param>
|
/// <param name="array">Array</param>
|
||||||
/// <returns>True if null</returns>
|
/// <returns>True if null</returns>
|
||||||
public static bool ArrayIsNullOrEmpty(byte[] array)
|
public static bool ArrayIsNullOrEmpty(byte[] array) => array == null || array.All(b => b == 0x00);
|
||||||
{
|
|
||||||
return array == null || array.All(b => b == 0x00);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,101 +36,73 @@ using System.Linq;
|
|||||||
namespace DiscImageChef
|
namespace DiscImageChef
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts base data types to an array of bytes, and an array of bytes to base
|
/// Converts base data types to an array of bytes, and an array of bytes to base data types. All info taken from
|
||||||
/// data types.
|
/// the meta data of System.BitConverter. This implementation allows for Endianness consideration.
|
||||||
/// All info taken from the meta data of System.BitConverter. This implementation
|
|
||||||
/// allows for Endianness consideration.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class BigEndianBitConverter
|
public static class BigEndianBitConverter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Converts the specified double-precision floating point number to a 64-bit signed integer.</summary>
|
||||||
/// Converts the specified double-precision floating point number to a 64-bit signed integer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>A 64-bit signed integer whose value is equivalent to value.</returns>
|
/// <returns>A 64-bit signed integer whose value is equivalent to value.</returns>
|
||||||
/// <exception cref="NotImplementedException">It is not currently implemented</exception>
|
/// <exception cref="NotImplementedException">It is not currently implemented</exception>
|
||||||
public static long DoubleToInt64Bits(double value) => throw new NotImplementedException();
|
public static long DoubleToInt64Bits(double value) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified Boolean value as an array of bytes.</summary>
|
||||||
/// Returns the specified Boolean value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">A Boolean value.</param>
|
/// <param name="value">A Boolean value.</param>
|
||||||
/// <returns>An array of bytes with length 1.</returns>
|
/// <returns>An array of bytes with length 1.</returns>
|
||||||
public static byte[] GetBytes(bool value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(bool value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified Unicode character value as an array of bytes.</summary>
|
||||||
/// Returns the specified Unicode character value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">A character to convert.</param>
|
/// <param name="value">A character to convert.</param>
|
||||||
/// <returns>An array of bytes with length 2.</returns>
|
/// <returns>An array of bytes with length 2.</returns>
|
||||||
public static byte[] GetBytes(char value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(char value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified double-precision floating point value as an array of bytes.</summary>
|
||||||
/// Returns the specified double-precision floating point value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 8.</returns>
|
/// <returns>An array of bytes with length 8.</returns>
|
||||||
public static byte[] GetBytes(double value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(double value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified single-precision floating point value as an array of bytes.</summary>
|
||||||
/// Returns the specified single-precision floating point value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 4.</returns>
|
/// <returns>An array of bytes with length 4.</returns>
|
||||||
public static byte[] GetBytes(float value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(float value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified 32-bit signed integer value as an array of bytes.</summary>
|
||||||
/// Returns the specified 32-bit signed integer value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 4.</returns>
|
/// <returns>An array of bytes with length 4.</returns>
|
||||||
public static byte[] GetBytes(int value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(int value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified 64-bit signed integer value as an array of bytes.</summary>
|
||||||
/// Returns the specified 64-bit signed integer value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 8.</returns>
|
/// <returns>An array of bytes with length 8.</returns>
|
||||||
public static byte[] GetBytes(long value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(long value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified 16-bit signed integer value as an array of bytes.</summary>
|
||||||
/// Returns the specified 16-bit signed integer value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 2.</returns>
|
/// <returns>An array of bytes with length 2.</returns>
|
||||||
public static byte[] GetBytes(short value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(short value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified 32-bit unsigned integer value as an array of bytes.</summary>
|
||||||
/// Returns the specified 32-bit unsigned integer value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 4.</returns>
|
/// <returns>An array of bytes with length 4.</returns>
|
||||||
public static byte[] GetBytes(uint value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(uint value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified 64-bit unsigned integer value as an array of bytes.</summary>
|
||||||
/// Returns the specified 64-bit unsigned integer value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 8.</returns>
|
/// <returns>An array of bytes with length 8.</returns>
|
||||||
public static byte[] GetBytes(ulong value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(ulong value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns the specified 16-bit unsigned integer value as an array of bytes.</summary>
|
||||||
/// Returns the specified 16-bit unsigned integer value as an array of bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>An array of bytes with length 2.</returns>
|
/// <returns>An array of bytes with length 2.</returns>
|
||||||
public static byte[] GetBytes(ushort value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
public static byte[] GetBytes(ushort value) => BitConverter.GetBytes(value).Reverse().ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts the specified 64-bit signed integer to a double-precision floating point number.</summary>
|
||||||
/// Converts the specified 64-bit signed integer to a double-precision floating point number.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The number to convert.</param>
|
/// <param name="value">The number to convert.</param>
|
||||||
/// <returns>A double-precision floating point number whose value is equivalent to value.</returns>
|
/// <returns>A double-precision floating point number whose value is equivalent to value.</returns>
|
||||||
public static double Int64BitsToDouble(long value) => throw new NotImplementedException();
|
public static double Int64BitsToDouble(long value) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a Boolean value converted from one byte at a specified position in a byte array.</summary>
|
||||||
/// Returns a Boolean value converted from one byte at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>true if the byte at <see cref="startIndex" /> in value is nonzero; otherwise, false.</returns>
|
/// <returns>true if the byte at <see cref="startIndex" /> in value is nonzero; otherwise, false.</returns>
|
||||||
@@ -141,9 +113,7 @@ namespace DiscImageChef
|
|||||||
/// </exception>
|
/// </exception>
|
||||||
public static bool ToBoolean(byte[] value, int startIndex) => throw new NotImplementedException();
|
public static bool ToBoolean(byte[] value, int startIndex) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a Unicode character converted from two bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a Unicode character converted from two bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array.</param>
|
/// <param name="value">An array.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A character formed by two bytes beginning at <see cref="startIndex" />.</returns>
|
/// <returns>A character formed by two bytes beginning at <see cref="startIndex" />.</returns>
|
||||||
@@ -173,9 +143,7 @@ namespace DiscImageChef
|
|||||||
/// </exception>
|
/// </exception>
|
||||||
public static double ToDouble(byte[] value, int startIndex) => throw new NotImplementedException();
|
public static double ToDouble(byte[] value, int startIndex) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A 16-bit signed integer formed by two bytes beginning at <see cref="startIndex" />.</returns>
|
/// <returns>A 16-bit signed integer formed by two bytes beginning at <see cref="startIndex" />.</returns>
|
||||||
@@ -188,9 +156,7 @@ namespace DiscImageChef
|
|||||||
public static short ToInt16(byte[] value, int startIndex) =>
|
public static short ToInt16(byte[] value, int startIndex) =>
|
||||||
BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(short) - startIndex);
|
BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(short) - startIndex);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A 32-bit signed integer formed by four bytes beginning at <see cref="startIndex" />.</returns>
|
/// <returns>A 32-bit signed integer formed by four bytes beginning at <see cref="startIndex" />.</returns>
|
||||||
@@ -206,9 +172,7 @@ namespace DiscImageChef
|
|||||||
public static int ToInt32(byte[] value, int startIndex) =>
|
public static int ToInt32(byte[] value, int startIndex) =>
|
||||||
BitConverter.ToInt32(value.Reverse().ToArray(), value.Length - sizeof(int) - startIndex);
|
BitConverter.ToInt32(value.Reverse().ToArray(), value.Length - sizeof(int) - startIndex);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A 64-bit signed integer formed by eight bytes beginning at <see cref="startIndex" />.</returns>
|
/// <returns>A 64-bit signed integer formed by eight bytes beginning at <see cref="startIndex" />.</returns>
|
||||||
@@ -256,8 +220,8 @@ namespace DiscImageChef
|
|||||||
public static string ToString(byte[] value) => BitConverter.ToString(value.Reverse().ToArray());
|
public static string ToString(byte[] value) => BitConverter.ToString(value.Reverse().ToArray());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal string
|
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal
|
||||||
/// representation.
|
/// string representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
@@ -274,8 +238,8 @@ namespace DiscImageChef
|
|||||||
BitConverter.ToString(value.Reverse().ToArray(), startIndex);
|
BitConverter.ToString(value.Reverse().ToArray(), startIndex);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal string
|
/// Converts the numeric value of each element of a specified subarray of bytes to its equivalent hexadecimal
|
||||||
/// representation.
|
/// string representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
@@ -296,9 +260,7 @@ namespace DiscImageChef
|
|||||||
public static string ToString(byte[] value, int startIndex, int length) =>
|
public static string ToString(byte[] value, int startIndex, int length) =>
|
||||||
BitConverter.ToString(value.Reverse().ToArray(), startIndex, length);
|
BitConverter.ToString(value.Reverse().ToArray(), startIndex, length);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The array of bytes.</param>
|
/// <param name="value">The array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>
|
/// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>
|
||||||
@@ -311,9 +273,7 @@ namespace DiscImageChef
|
|||||||
public static ushort ToUInt16(byte[] value, int startIndex) =>
|
public static ushort ToUInt16(byte[] value, int startIndex) =>
|
||||||
BitConverter.ToUInt16(value.Reverse().ToArray(), value.Length - sizeof(ushort) - startIndex);
|
BitConverter.ToUInt16(value.Reverse().ToArray(), value.Length - sizeof(ushort) - startIndex);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>
|
/// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>
|
||||||
@@ -329,9 +289,7 @@ namespace DiscImageChef
|
|||||||
public static uint ToUInt32(byte[] value, int startIndex) =>
|
public static uint ToUInt32(byte[] value, int startIndex) =>
|
||||||
BitConverter.ToUInt32(value.Reverse().ToArray(), value.Length - sizeof(uint) - startIndex);
|
BitConverter.ToUInt32(value.Reverse().ToArray(), value.Length - sizeof(uint) - startIndex);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.</summary>
|
||||||
/// Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">An array of bytes.</param>
|
/// <param name="value">An array of bytes.</param>
|
||||||
/// <param name="startIndex">The starting position within value.</param>
|
/// <param name="startIndex">The starting position within value.</param>
|
||||||
/// <returns>A 64-bit unsigned integer formed by the eight bytes beginning at startIndex.</returns>
|
/// <returns>A 64-bit unsigned integer formed by the eight bytes beginning at startIndex.</returns>
|
||||||
@@ -347,11 +305,16 @@ namespace DiscImageChef
|
|||||||
public static ulong ToUInt64(byte[] value, int startIndex) =>
|
public static ulong ToUInt64(byte[] value, int startIndex) =>
|
||||||
BitConverter.ToUInt64(value.Reverse().ToArray(), value.Length - sizeof(ulong) - startIndex);
|
BitConverter.ToUInt64(value.Reverse().ToArray(), value.Length - sizeof(ulong) - startIndex);
|
||||||
|
|
||||||
public static Guid ToGuid(byte[] value, int startIndex) =>
|
public static Guid ToGuid(byte[] value, int startIndex) => new Guid(ToUInt32(value, 0 + startIndex),
|
||||||
new Guid(ToUInt32(value, 0 + startIndex), ToUInt16(value, 4 + startIndex),
|
ToUInt16(value, 4 + startIndex),
|
||||||
ToUInt16(value, 6 + startIndex),
|
ToUInt16(value, 6 + startIndex),
|
||||||
value[8 + startIndex + 0], value[8 + startIndex + 1], value[8 + startIndex + 2],
|
value[8 + startIndex + 0],
|
||||||
value[8 + startIndex + 3], value[8 + startIndex + 5], value[8 + startIndex + 5],
|
value[8 + startIndex + 1],
|
||||||
value[8 + startIndex + 6], value[8 + startIndex + 7]);
|
value[8 + startIndex + 2],
|
||||||
|
value[8 + startIndex + 3],
|
||||||
|
value[8 + startIndex + 5],
|
||||||
|
value[8 + startIndex + 5],
|
||||||
|
value[8 + startIndex + 6],
|
||||||
|
value[8 + startIndex + 7]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,8 +42,7 @@ namespace DiscImageChef.Helpers
|
|||||||
public enum BitEndian
|
public enum BitEndian
|
||||||
{
|
{
|
||||||
/// <summary>Little-endian, or least significant bit</summary>
|
/// <summary>Little-endian, or least significant bit</summary>
|
||||||
Little,
|
Little, /// <summary>Big-endian, or most significant bit</summary>
|
||||||
/// <summary>Big-endian, or most significant bit</summary>
|
|
||||||
Big,
|
Big,
|
||||||
/// <summary>PDP-11 endian, little endian except for 32-bit integers where the 16 halves are swapped between them</summary>
|
/// <summary>PDP-11 endian, little endian except for 32-bit integers where the 16 halves are swapped between them</summary>
|
||||||
Pdp
|
Pdp
|
||||||
|
|||||||
7
CHS.cs
7
CHS.cs
@@ -34,9 +34,7 @@ namespace DiscImageChef.Helpers
|
|||||||
{
|
{
|
||||||
public static class CHS
|
public static class CHS
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Converts a CHS position to a LBA one</summary>
|
||||||
/// Converts a CHS position to a LBA one
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cyl">Cylinder</param>
|
/// <param name="cyl">Cylinder</param>
|
||||||
/// <param name="head">Head</param>
|
/// <param name="head">Head</param>
|
||||||
/// <param name="sector">Sector</param>
|
/// <param name="sector">Sector</param>
|
||||||
@@ -44,8 +42,7 @@ namespace DiscImageChef.Helpers
|
|||||||
/// <param name="maxSector">Number of sectors per track</param>
|
/// <param name="maxSector">Number of sectors per track</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static uint ToLBA(uint cyl, uint head, uint sector, uint maxHead, uint maxSector) =>
|
public static uint ToLBA(uint cyl, uint head, uint sector, uint maxHead, uint maxSector) =>
|
||||||
maxHead == 0 || maxSector == 0
|
maxHead == 0 || maxSector == 0 ? (cyl * 16 + head) * 63 + sector - 1
|
||||||
? (cyl * 16 + head) * 63 + sector - 1
|
|
||||||
: (cyl * maxHead + head) * maxSector + sector - 1;
|
: (cyl * maxHead + head) * maxSector + sector - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,9 +34,7 @@ namespace DiscImageChef
|
|||||||
{
|
{
|
||||||
public static partial class ArrayHelpers
|
public static partial class ArrayHelpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Compares two byte arrays</summary>
|
||||||
/// Compares two byte arrays
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="different"><c>true</c> if they are different in any way</param>
|
/// <param name="different"><c>true</c> if they are different in any way</param>
|
||||||
/// <param name="sameSize"><c>true</c> if they have the same size</param>
|
/// <param name="sameSize"><c>true</c> if they have the same size</param>
|
||||||
/// <param name="compareArray1">Left array</param>
|
/// <param name="compareArray1">Left array</param>
|
||||||
@@ -48,6 +46,7 @@ namespace DiscImageChef
|
|||||||
sameSize = true;
|
sameSize = true;
|
||||||
|
|
||||||
long leastBytes;
|
long leastBytes;
|
||||||
|
|
||||||
if(compareArray1.LongLength < compareArray2.LongLength)
|
if(compareArray1.LongLength < compareArray2.LongLength)
|
||||||
{
|
{
|
||||||
sameSize = false;
|
sameSize = false;
|
||||||
@@ -58,12 +57,14 @@ namespace DiscImageChef
|
|||||||
sameSize = false;
|
sameSize = false;
|
||||||
leastBytes = compareArray2.LongLength;
|
leastBytes = compareArray2.LongLength;
|
||||||
}
|
}
|
||||||
else leastBytes = compareArray1.LongLength;
|
else
|
||||||
|
leastBytes = compareArray1.LongLength;
|
||||||
|
|
||||||
for(long i = 0; i < leastBytes; i++)
|
for(long i = 0; i < leastBytes; i++)
|
||||||
if(compareArray1[i] != compareArray2[i])
|
if(compareArray1[i] != compareArray2[i])
|
||||||
{
|
{
|
||||||
different = true;
|
different = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,15 +34,14 @@ namespace DiscImageChef.Helpers
|
|||||||
{
|
{
|
||||||
public static class CountBits
|
public static class CountBits
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Counts the number of bits set to <c>true</c> in a number</summary>
|
||||||
/// Counts the number of bits set to <c>true</c> in a number
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="number">Number</param>
|
/// <param name="number">Number</param>
|
||||||
/// <returns>Bits set to <c>true</c></returns>
|
/// <returns>Bits set to <c>true</c></returns>
|
||||||
public static int Count(uint number)
|
public static int Count(uint number)
|
||||||
{
|
{
|
||||||
number = number - ((number >> 1) & 0x55555555);
|
number = number - ((number >> 1) & 0x55555555);
|
||||||
number = (number & 0x33333333) + ((number >> 2) & 0x33333333);
|
number = (number & 0x33333333) + ((number >> 2) & 0x33333333);
|
||||||
|
|
||||||
return(int)((((number + (number >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
|
return(int)((((number + (number >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
180
DateHandlers.cs
180
DateHandlers.cs
@@ -41,79 +41,60 @@ namespace DiscImageChef
|
|||||||
static readonly DateTime LisaEpoch = new DateTime(1901, 1, 1, 0, 0, 0);
|
static readonly DateTime LisaEpoch = new DateTime(1901, 1, 1, 0, 0, 0);
|
||||||
static readonly DateTime MacEpoch = new DateTime(1904, 1, 1, 0, 0, 0);
|
static readonly DateTime MacEpoch = new DateTime(1904, 1, 1, 0, 0, 0);
|
||||||
static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
|
static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||||
/// <summary>
|
/// <summary>Day 0 of Julian Date system</summary>
|
||||||
/// Day 0 of Julian Date system
|
|
||||||
/// </summary>
|
|
||||||
static readonly DateTime JulianEpoch = new DateTime(1858, 11, 17, 0, 0, 0);
|
static readonly DateTime JulianEpoch = new DateTime(1858, 11, 17, 0, 0, 0);
|
||||||
static readonly DateTime AmigaEpoch = new DateTime(1978, 1, 1, 0, 0, 0);
|
static readonly DateTime AmigaEpoch = new DateTime(1978, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a Macintosh timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a Macintosh timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="macTimeStamp">Macintosh timestamp (seconds since 1st Jan. 1904)</param>
|
/// <param name="macTimeStamp">Macintosh timestamp (seconds since 1st Jan. 1904)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime MacToDateTime(ulong macTimeStamp) => MacEpoch.AddTicks((long)(macTimeStamp * 10000000));
|
public static DateTime MacToDateTime(ulong macTimeStamp) => MacEpoch.AddTicks((long)(macTimeStamp * 10000000));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a Lisa timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a Lisa timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="lisaTimeStamp">Lisa timestamp (seconds since 1st Jan. 1901)</param>
|
/// <param name="lisaTimeStamp">Lisa timestamp (seconds since 1st Jan. 1901)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime LisaToDateTime(uint lisaTimeStamp) => LisaEpoch.AddSeconds(lisaTimeStamp);
|
public static DateTime LisaToDateTime(uint lisaTimeStamp) => LisaEpoch.AddSeconds(lisaTimeStamp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a UNIX timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UnixToDateTime(int unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
public static DateTime UnixToDateTime(int unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a UNIX timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UnixToDateTime(long unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
public static DateTime UnixToDateTime(long unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a UNIX timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UnixUnsignedToDateTime(uint unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
public static DateTime UnixUnsignedToDateTime(uint unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a UNIX timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="seconds">Seconds since 1st Jan. 1970)</param>
|
/// <param name="seconds">Seconds since 1st Jan. 1970)</param>
|
||||||
/// <param name="nanoseconds">Nanoseconds</param>
|
/// <param name="nanoseconds">Nanoseconds</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UnixUnsignedToDateTime(uint seconds, uint nanoseconds) =>
|
public static DateTime UnixUnsignedToDateTime(uint seconds, uint nanoseconds) =>
|
||||||
UnixEpoch.AddSeconds(seconds).AddTicks((long)nanoseconds / 100);
|
UnixEpoch.AddSeconds(seconds).AddTicks((long)nanoseconds / 100);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a UNIX timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UnixUnsignedToDateTime(ulong unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
public static DateTime UnixUnsignedToDateTime(ulong unixTimeStamp) => UnixEpoch.AddSeconds(unixTimeStamp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a High Sierra Format timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a High Sierra Format timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="vdDateTime">High Sierra Format timestamp</param>
|
/// <param name="vdDateTime">High Sierra Format timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime HighSierraToDateTime(byte[] vdDateTime)
|
public static DateTime HighSierraToDateTime(byte[] vdDateTime)
|
||||||
{
|
{
|
||||||
byte[] isotime = new byte[17];
|
byte[] isotime = new byte[17];
|
||||||
Array.Copy(vdDateTime, 0, isotime, 0, 16);
|
Array.Copy(vdDateTime, 0, isotime, 0, 16);
|
||||||
|
|
||||||
return Iso9660ToDateTime(isotime);
|
return Iso9660ToDateTime(isotime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Timezone
|
// TODO: Timezone
|
||||||
/// <summary>
|
/// <summary>Converts an ISO9660 timestamp to a .NET DateTime</summary>
|
||||||
/// Converts an ISO9660 timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="vdDateTime">ISO9660 timestamp</param>
|
/// <param name="vdDateTime">ISO9660 timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime Iso9660ToDateTime(byte[] vdDateTime)
|
public static DateTime Iso9660ToDateTime(byte[] vdDateTime)
|
||||||
@@ -125,71 +106,89 @@ namespace DiscImageChef
|
|||||||
fourcharvalue[1] = vdDateTime[1];
|
fourcharvalue[1] = vdDateTime[1];
|
||||||
fourcharvalue[2] = vdDateTime[2];
|
fourcharvalue[2] = vdDateTime[2];
|
||||||
fourcharvalue[3] = vdDateTime[3];
|
fourcharvalue[3] = vdDateTime[3];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "year = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "year = \"{0}\"",
|
||||||
StringHandlers.CToString(fourcharvalue, Encoding.ASCII));
|
StringHandlers.CToString(fourcharvalue, Encoding.ASCII));
|
||||||
if(!int.TryParse(StringHandlers.CToString(fourcharvalue, Encoding.ASCII), out int year)) year = 0;
|
|
||||||
|
if(!int.TryParse(StringHandlers.CToString(fourcharvalue, Encoding.ASCII), out int year))
|
||||||
|
year = 0;
|
||||||
|
|
||||||
twocharvalue[0] = vdDateTime[4];
|
twocharvalue[0] = vdDateTime[4];
|
||||||
twocharvalue[1] = vdDateTime[5];
|
twocharvalue[1] = vdDateTime[5];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "month = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "month = \"{0}\"",
|
||||||
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
||||||
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int month)) month = 0;
|
|
||||||
|
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int month))
|
||||||
|
month = 0;
|
||||||
|
|
||||||
twocharvalue[0] = vdDateTime[6];
|
twocharvalue[0] = vdDateTime[6];
|
||||||
twocharvalue[1] = vdDateTime[7];
|
twocharvalue[1] = vdDateTime[7];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "day = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "day = \"{0}\"",
|
||||||
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
||||||
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int day)) day = 0;
|
|
||||||
|
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int day))
|
||||||
|
day = 0;
|
||||||
|
|
||||||
twocharvalue[0] = vdDateTime[8];
|
twocharvalue[0] = vdDateTime[8];
|
||||||
twocharvalue[1] = vdDateTime[9];
|
twocharvalue[1] = vdDateTime[9];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "hour = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "hour = \"{0}\"",
|
||||||
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
||||||
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int hour)) hour = 0;
|
|
||||||
|
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int hour))
|
||||||
|
hour = 0;
|
||||||
|
|
||||||
twocharvalue[0] = vdDateTime[10];
|
twocharvalue[0] = vdDateTime[10];
|
||||||
twocharvalue[1] = vdDateTime[11];
|
twocharvalue[1] = vdDateTime[11];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "minute = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "minute = \"{0}\"",
|
||||||
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
||||||
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int minute)) minute = 0;
|
|
||||||
|
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int minute))
|
||||||
|
minute = 0;
|
||||||
|
|
||||||
twocharvalue[0] = vdDateTime[12];
|
twocharvalue[0] = vdDateTime[12];
|
||||||
twocharvalue[1] = vdDateTime[13];
|
twocharvalue[1] = vdDateTime[13];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "second = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "second = \"{0}\"",
|
||||||
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
||||||
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int second)) second = 0;
|
|
||||||
|
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int second))
|
||||||
|
second = 0;
|
||||||
|
|
||||||
twocharvalue[0] = vdDateTime[14];
|
twocharvalue[0] = vdDateTime[14];
|
||||||
twocharvalue[1] = vdDateTime[15];
|
twocharvalue[1] = vdDateTime[15];
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "hundredths = \"{0}\"",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler", "hundredths = \"{0}\"",
|
||||||
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
StringHandlers.CToString(twocharvalue, Encoding.ASCII));
|
||||||
|
|
||||||
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int hundredths))
|
if(!int.TryParse(StringHandlers.CToString(twocharvalue, Encoding.ASCII), out int hundredths))
|
||||||
hundredths = 0;
|
hundredths = 0;
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ISO9600ToDateTime handler",
|
DicConsole.DebugWriteLine("ISO9600ToDateTime handler",
|
||||||
"decodedDT = new DateTime({0}, {1}, {2}, {3}, {4}, {5}, {6}, DateTimeKind.Unspecified);",
|
"decodedDT = new DateTime({0}, {1}, {2}, {3}, {4}, {5}, {6}, DateTimeKind.Unspecified);",
|
||||||
year, month, day, hour, minute, second, hundredths * 10);
|
year, month, day, hour, minute, second, hundredths * 10);
|
||||||
DateTime decodedDt = new DateTime(year, month, day, hour, minute, second, hundredths * 10,
|
|
||||||
|
var decodedDt = new DateTime(year, month, day, hour, minute, second, hundredths * 10,
|
||||||
DateTimeKind.Unspecified);
|
DateTimeKind.Unspecified);
|
||||||
|
|
||||||
return decodedDt;
|
return decodedDt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a VMS timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a VMS timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="vmsDate">VMS timestamp (tenths of microseconds since day 0 of the Julian Date)</param>
|
/// <param name="vmsDate">VMS timestamp (tenths of microseconds since day 0 of the Julian Date)</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
/// <remarks>C# works in UTC, VMS on Julian Date, some displacement may occur on disks created outside UTC</remarks>
|
/// <remarks>C# works in UTC, VMS on Julian Date, some displacement may occur on disks created outside UTC</remarks>
|
||||||
public static DateTime VmsToDateTime(ulong vmsDate)
|
public static DateTime VmsToDateTime(ulong vmsDate)
|
||||||
{
|
{
|
||||||
double delta = vmsDate * 0.0001; // Tenths of microseconds to milliseconds, will lose some detail
|
double delta = vmsDate * 0.0001; // Tenths of microseconds to milliseconds, will lose some detail
|
||||||
|
|
||||||
return JulianEpoch.AddMilliseconds(delta);
|
return JulianEpoch.AddMilliseconds(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts an Amiga timestamp to a .NET DateTime</summary>
|
||||||
/// Converts an Amiga timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="days">Days since the 1st Jan. 1978</param>
|
/// <param name="days">Days since the 1st Jan. 1978</param>
|
||||||
/// <param name="minutes">Minutes since o'clock</param>
|
/// <param name="minutes">Minutes since o'clock</param>
|
||||||
/// <param name="ticks">Ticks</param>
|
/// <param name="ticks">Ticks</param>
|
||||||
@@ -198,12 +197,11 @@ namespace DiscImageChef
|
|||||||
{
|
{
|
||||||
DateTime temp = AmigaEpoch.AddDays(days);
|
DateTime temp = AmigaEpoch.AddDays(days);
|
||||||
temp = temp.AddMinutes(minutes);
|
temp = temp.AddMinutes(minutes);
|
||||||
|
|
||||||
return temp.AddMilliseconds(ticks * 20);
|
return temp.AddMilliseconds(ticks * 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts an UCSD Pascal timestamp to a .NET DateTime</summary>
|
||||||
/// Converts an UCSD Pascal timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dateRecord">UCSD Pascal timestamp</param>
|
/// <param name="dateRecord">UCSD Pascal timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UcsdPascalToDateTime(short dateRecord)
|
public static DateTime UcsdPascalToDateTime(short dateRecord)
|
||||||
@@ -215,12 +213,11 @@ namespace DiscImageChef
|
|||||||
DicConsole.DebugWriteLine("UCSDPascalToDateTime handler",
|
DicConsole.DebugWriteLine("UCSDPascalToDateTime handler",
|
||||||
"dateRecord = 0x{0:X4}, year = {1}, month = {2}, day = {3}", dateRecord, year,
|
"dateRecord = 0x{0:X4}, year = {1}, month = {2}, day = {3}", dateRecord, year,
|
||||||
month, day);
|
month, day);
|
||||||
|
|
||||||
return new DateTime(year, month, day);
|
return new DateTime(year, month, day);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a DOS timestamp to a .NET DateTime</summary>
|
||||||
/// Converts a DOS timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="date">Date</param>
|
/// <param name="date">Date</param>
|
||||||
/// <param name="time">Time</param>
|
/// <param name="time">Time</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
@@ -235,20 +232,26 @@ namespace DiscImageChef
|
|||||||
|
|
||||||
DicConsole.DebugWriteLine("DOSToDateTime handler", "date = 0x{0:X4}, year = {1}, month = {2}, day = {3}",
|
DicConsole.DebugWriteLine("DOSToDateTime handler", "date = 0x{0:X4}, year = {1}, month = {2}, day = {3}",
|
||||||
date, year, month, day);
|
date, year, month, day);
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("DOSToDateTime handler",
|
DicConsole.DebugWriteLine("DOSToDateTime handler",
|
||||||
"time = 0x{0:X4}, hour = {1}, minute = {2}, second = {3}", time, hour, minute,
|
"time = 0x{0:X4}, hour = {1}, minute = {2}, second = {3}", time, hour, minute,
|
||||||
second);
|
second);
|
||||||
|
|
||||||
DateTime dosdate;
|
DateTime dosdate;
|
||||||
try { dosdate = new DateTime(year, month, day, hour, minute, second); }
|
|
||||||
catch(ArgumentOutOfRangeException) { dosdate = new DateTime(1980, 1, 1, 0, 0, 0); }
|
try
|
||||||
|
{
|
||||||
|
dosdate = new DateTime(year, month, day, hour, minute, second);
|
||||||
|
}
|
||||||
|
catch(ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
dosdate = new DateTime(1980, 1, 1, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return dosdate;
|
return dosdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a CP/M timestamp to .NET DateTime</summary>
|
||||||
/// Converts a CP/M timestamp to .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="timestamp">CP/M timestamp</param>
|
/// <param name="timestamp">CP/M timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime CpmToDateTime(byte[] timestamp)
|
public static DateTime CpmToDateTime(byte[] timestamp)
|
||||||
@@ -264,9 +267,7 @@ namespace DiscImageChef
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts an ECMA timestamp to a .NET DateTime</summary>
|
||||||
/// Converts an ECMA timestamp to a .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="typeAndTimeZone">Timezone</param>
|
/// <param name="typeAndTimeZone">Timezone</param>
|
||||||
/// <param name="year">Year</param>
|
/// <param name="year">Year</param>
|
||||||
/// <param name="month">Month</param>
|
/// <param name="month">Month</param>
|
||||||
@@ -278,77 +279,79 @@ namespace DiscImageChef
|
|||||||
/// <param name="hundredsOfMicroseconds">Hundreds of microseconds</param>
|
/// <param name="hundredsOfMicroseconds">Hundreds of microseconds</param>
|
||||||
/// <param name="microseconds">Microseconds</param>
|
/// <param name="microseconds">Microseconds</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static DateTime EcmaToDateTime(ushort typeAndTimeZone, short year, byte month, byte day,
|
public static DateTime EcmaToDateTime(ushort typeAndTimeZone, short year, byte month, byte day, byte hour,
|
||||||
byte hour,
|
byte minute, byte second, byte centiseconds, byte hundredsOfMicroseconds,
|
||||||
byte minute, byte second, byte centiseconds,
|
|
||||||
byte hundredsOfMicroseconds,
|
|
||||||
byte microseconds)
|
byte microseconds)
|
||||||
{
|
{
|
||||||
byte specification = (byte)((typeAndTimeZone & 0xF000) >> 12);
|
byte specification = (byte)((typeAndTimeZone & 0xF000) >> 12);
|
||||||
|
|
||||||
long ticks = (long)centiseconds * 100000 + (long)hundredsOfMicroseconds * 1000 +
|
long ticks = (long)centiseconds * 100000 + (long)hundredsOfMicroseconds * 1000 +
|
||||||
(long)microseconds * 10;
|
(long)microseconds * 10;
|
||||||
|
|
||||||
if(specification == 0)
|
if(specification == 0)
|
||||||
return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc).AddTicks(ticks);
|
return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc).AddTicks(ticks);
|
||||||
|
|
||||||
ushort preOffset = (ushort)(typeAndTimeZone & 0xFFF);
|
ushort preOffset = (ushort)(typeAndTimeZone & 0xFFF);
|
||||||
short offset;
|
short offset;
|
||||||
|
|
||||||
if((preOffset & 0x800) == 0x800) offset = (short)(preOffset | 0xF000);
|
if((preOffset & 0x800) == 0x800)
|
||||||
else offset = (short)(preOffset & 0x7FF);
|
offset = (short)(preOffset | 0xF000);
|
||||||
|
else
|
||||||
|
offset = (short)(preOffset & 0x7FF);
|
||||||
|
|
||||||
if(offset == -2047)
|
if(offset == -2047)
|
||||||
return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified).AddTicks(ticks);
|
return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified).AddTicks(ticks);
|
||||||
|
|
||||||
if(offset < -1440 || offset > 1440) offset = 0;
|
if(offset < -1440 ||
|
||||||
|
offset > 1440)
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
return new DateTimeOffset(year, month, day, hour, minute, second, new TimeSpan(0, offset, 0))
|
return new DateTimeOffset(year, month, day, hour, minute, second, new TimeSpan(0, offset, 0)).
|
||||||
.AddTicks(ticks).DateTime;
|
AddTicks(ticks).DateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Convers a Solaris high resolution timestamp to .NET DateTime</summary>
|
||||||
/// Convers a Solaris high resolution timestamp to .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hrTimeStamp">Solaris high resolution timestamp</param>
|
/// <param name="hrTimeStamp">Solaris high resolution timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime UnixHrTimeToDateTime(ulong hrTimeStamp) => UnixEpoch.AddTicks((long)(hrTimeStamp / 100));
|
public static DateTime UnixHrTimeToDateTime(ulong hrTimeStamp) => UnixEpoch.AddTicks((long)(hrTimeStamp / 100));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts an OS-9 timestamp to .NET DateTime</summary>
|
||||||
/// Converts an OS-9 timestamp to .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="date">OS-9 timestamp</param>
|
/// <param name="date">OS-9 timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime Os9ToDateTime(byte[] date)
|
public static DateTime Os9ToDateTime(byte[] date)
|
||||||
{
|
{
|
||||||
if(date == null || date.Length != 3 && date.Length != 5) return DateTime.MinValue;
|
if(date == null ||
|
||||||
|
date.Length != 3 && date.Length != 5)
|
||||||
|
return DateTime.MinValue;
|
||||||
|
|
||||||
DateTime os9Date;
|
DateTime os9Date;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
os9Date = date.Length == 5
|
os9Date = date.Length == 5 ? new DateTime(1900 + date[0], date[1], date[2], date[3], date[4], 0)
|
||||||
? new DateTime(1900 + date[0], date[1], date[2], date[3], date[4], 0)
|
|
||||||
: new DateTime(1900 + date[0], date[1], date[2], 0, 0, 0);
|
: new DateTime(1900 + date[0], date[1], date[2], 0, 0, 0);
|
||||||
}
|
}
|
||||||
catch(ArgumentOutOfRangeException) { os9Date = new DateTime(1900, 0, 0, 0, 0, 0); }
|
catch(ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
os9Date = new DateTime(1900, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return os9Date;
|
return os9Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a LIF timestamp to .NET DateTime</summary>
|
||||||
/// Converts a LIF timestamp to .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="date">LIF timestamp</param>
|
/// <param name="date">LIF timestamp</param>
|
||||||
/// <returns>.NET DateTime</returns>
|
/// <returns>.NET DateTime</returns>
|
||||||
public static DateTime LifToDateTime(byte[] date)
|
public static DateTime LifToDateTime(byte[] date)
|
||||||
{
|
{
|
||||||
if(date == null || date.Length != 6) return new DateTime(1970, 1, 1, 0, 0, 0);
|
if(date == null ||
|
||||||
|
date.Length != 6)
|
||||||
|
return new DateTime(1970, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
return LifToDateTime(date[0], date[1], date[2], date[3], date[4], date[5]);
|
return LifToDateTime(date[0], date[1], date[2], date[3], date[4], date[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a LIF timestamp to .NET DateTime</summary>
|
||||||
/// Converts a LIF timestamp to .NET DateTime
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="year">Yer</param>
|
/// <param name="year">Yer</param>
|
||||||
/// <param name="month">Month</param>
|
/// <param name="month">Month</param>
|
||||||
/// <param name="day">Day</param>
|
/// <param name="day">Day</param>
|
||||||
@@ -367,12 +370,17 @@ namespace DiscImageChef
|
|||||||
int ihour = (hour >> 4) * 10 + (hour & 0xF);
|
int ihour = (hour >> 4) * 10 + (hour & 0xF);
|
||||||
int isecond = (second >> 4) * 10 + (second & 0xF);
|
int isecond = (second >> 4) * 10 + (second & 0xF);
|
||||||
|
|
||||||
if(iyear >= 70) iyear += 1900;
|
if(iyear >= 70)
|
||||||
else iyear += 2000;
|
iyear += 1900;
|
||||||
|
else
|
||||||
|
iyear += 2000;
|
||||||
|
|
||||||
return new DateTime(iyear, imonth, iday, ihour, iminute, isecond);
|
return new DateTime(iyear, imonth, iday, ihour, iminute, isecond);
|
||||||
}
|
}
|
||||||
catch(ArgumentOutOfRangeException) { return new DateTime(1970, 1, 1, 0, 0, 0); }
|
catch(ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
return new DateTime(1970, 1, 1, 0, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
198
Marshal.cs
198
Marshal.cs
@@ -40,36 +40,30 @@ namespace DiscImageChef.Helpers
|
|||||||
/// <summary>Provides methods to marshal binary data into C# structs</summary>
|
/// <summary>Provides methods to marshal binary data into C# structs</summary>
|
||||||
public static class Marshal
|
public static class Marshal
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Returns the size of an unmanaged type in bytes.</summary>
|
||||||
/// Returns the size of an unmanaged type in bytes.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type whose size is to be returned.</typeparam>
|
/// <typeparam name="T">The type whose size is to be returned.</typeparam>
|
||||||
/// <returns>The size, in bytes, of the type that is specified by the <see cref="T" /> generic type parameter.</returns>
|
/// <returns>The size, in bytes, of the type that is specified by the <see cref="T" /> generic type parameter.</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static int SizeOf<T>()
|
public static int SizeOf<T>() => System.Runtime.InteropServices.Marshal.SizeOf<T>();
|
||||||
{
|
|
||||||
return System.Runtime.InteropServices.Marshal.SizeOf<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal little-endian binary data to a structure</summary>
|
||||||
/// Marshal little-endian binary data to a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static T ByteArrayToStructureLittleEndian<T>(byte[] bytes) where T : struct
|
public static T ByteArrayToStructureLittleEndian<T>(byte[] bytes) where T : struct
|
||||||
{
|
{
|
||||||
var ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||||
|
|
||||||
var str =
|
var str =
|
||||||
(T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
|
(T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
|
||||||
|
|
||||||
ptr.Free();
|
ptr.Free();
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal little-endian binary data to a structure</summary>
|
||||||
/// Marshal little-endian binary data to a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <param name="start">Start on the array where the structure begins</param>
|
/// <param name="start">Start on the array where the structure begins</param>
|
||||||
/// <param name="length">Length of the structure in bytes</param>
|
/// <param name="length">Length of the structure in bytes</param>
|
||||||
@@ -79,28 +73,28 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T ByteArrayToStructureLittleEndian<T>(byte[] bytes, int start, int length) where T : struct
|
public static T ByteArrayToStructureLittleEndian<T>(byte[] bytes, int start, int length) where T : struct
|
||||||
{
|
{
|
||||||
Span<byte> span = bytes;
|
Span<byte> span = bytes;
|
||||||
|
|
||||||
return ByteArrayToStructureLittleEndian<T>(span.Slice(start, length).ToArray());
|
return ByteArrayToStructureLittleEndian<T>(span.Slice(start, length).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal big-endian binary data to a structure</summary>
|
||||||
/// Marshal big-endian binary data to a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes) where T : struct
|
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes) where T : struct
|
||||||
{
|
{
|
||||||
var ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||||
|
|
||||||
object str =
|
object str =
|
||||||
(T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
|
(T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
|
||||||
|
|
||||||
ptr.Free();
|
ptr.Free();
|
||||||
|
|
||||||
return(T)SwapStructureMembersEndian(str);
|
return(T)SwapStructureMembersEndian(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal big-endian binary data to a structure</summary>
|
||||||
/// Marshal big-endian binary data to a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <param name="start">Start on the array where the structure begins</param>
|
/// <param name="start">Start on the array where the structure begins</param>
|
||||||
/// <param name="length">Length of the structure in bytes</param>
|
/// <param name="length">Length of the structure in bytes</param>
|
||||||
@@ -110,12 +104,11 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes, int start, int length) where T : struct
|
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes, int start, int length) where T : struct
|
||||||
{
|
{
|
||||||
Span<byte> span = bytes;
|
Span<byte> span = bytes;
|
||||||
|
|
||||||
return ByteArrayToStructureBigEndian<T>(span.Slice(start, length).ToArray());
|
return ByteArrayToStructureBigEndian<T>(span.Slice(start, length).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal PDP-11 binary data to a structure</summary>
|
||||||
/// Marshal PDP-11 binary data to a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
||||||
@@ -123,17 +116,18 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T ByteArrayToStructurePdpEndian<T>(byte[] bytes) where T : struct
|
public static T ByteArrayToStructurePdpEndian<T>(byte[] bytes) where T : struct
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
var ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
GCHandle ptr = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||||
|
|
||||||
object str =
|
object str =
|
||||||
(T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
|
(T)System.Runtime.InteropServices.Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(T));
|
||||||
|
|
||||||
ptr.Free();
|
ptr.Free();
|
||||||
|
|
||||||
return(T)SwapStructureMembersEndianPdp(str);
|
return(T)SwapStructureMembersEndianPdp(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal PDP-11 binary data to a structure</summary>
|
||||||
/// Marshal PDP-11 binary data to a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <param name="start">Start on the array where the structure begins</param>
|
/// <param name="start">Start on the array where the structure begins</param>
|
||||||
/// <param name="length">Length of the structure in bytes</param>
|
/// <param name="length">Length of the structure in bytes</param>
|
||||||
@@ -143,25 +137,24 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T ByteArrayToStructurePdpEndian<T>(byte[] bytes, int start, int length) where T : struct
|
public static T ByteArrayToStructurePdpEndian<T>(byte[] bytes, int start, int length) where T : struct
|
||||||
{
|
{
|
||||||
Span<byte> span = bytes;
|
Span<byte> span = bytes;
|
||||||
|
|
||||||
return ByteArrayToStructurePdpEndian<T>(span.Slice(start, length).ToArray());
|
return ByteArrayToStructurePdpEndian<T>(span.Slice(start, length).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marshal little-endian binary data to a structure. If the structure type contains any non value type, this method
|
/// Marshal little-endian binary data to a structure. If the structure type contains any non value type, this
|
||||||
/// will crash.
|
/// method will crash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static T SpanToStructureLittleEndian<T>(ReadOnlySpan<byte> bytes) where T : struct
|
public static T SpanToStructureLittleEndian<T>(ReadOnlySpan<byte> bytes) where T : struct =>
|
||||||
{
|
MemoryMarshal.Read<T>(bytes);
|
||||||
return MemoryMarshal.Read<T>(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marshal little-endian binary data to a structure. If the structure type contains any non value type, this method
|
/// Marshal little-endian binary data to a structure. If the structure type contains any non value type, this
|
||||||
/// will crash.
|
/// method will crash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">Byte span containing the binary data</param>
|
/// <param name="bytes">Byte span containing the binary data</param>
|
||||||
/// <param name="start">Start on the span where the structure begins</param>
|
/// <param name="start">Start on the span where the structure begins</param>
|
||||||
@@ -170,14 +163,11 @@ namespace DiscImageChef.Helpers
|
|||||||
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static T SpanToStructureLittleEndian<T>(ReadOnlySpan<byte> bytes, int start, int length)
|
public static T SpanToStructureLittleEndian<T>(ReadOnlySpan<byte> bytes, int start, int length)
|
||||||
where T : struct
|
where T : struct => MemoryMarshal.Read<T>(bytes.Slice(start, length));
|
||||||
{
|
|
||||||
return MemoryMarshal.Read<T>(bytes.Slice(start, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marshal big-endian binary data to a structure. If the structure type contains any non value type, this method will
|
/// Marshal big-endian binary data to a structure. If the structure type contains any non value type, this method
|
||||||
/// crash.
|
/// will crash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
@@ -186,12 +176,13 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T SpanToStructureBigEndian<T>(ReadOnlySpan<byte> bytes) where T : struct
|
public static T SpanToStructureBigEndian<T>(ReadOnlySpan<byte> bytes) where T : struct
|
||||||
{
|
{
|
||||||
var str = SpanToStructureLittleEndian<T>(bytes);
|
var str = SpanToStructureLittleEndian<T>(bytes);
|
||||||
|
|
||||||
return(T)SwapStructureMembersEndian(str);
|
return(T)SwapStructureMembersEndian(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marshal big-endian binary data to a structure. If the structure type contains any non value type, this method will
|
/// Marshal big-endian binary data to a structure. If the structure type contains any non value type, this method
|
||||||
/// crash.
|
/// will crash.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">Byte span containing the binary data</param>
|
/// <param name="bytes">Byte span containing the binary data</param>
|
||||||
/// <param name="start">Start on the span where the structure begins</param>
|
/// <param name="start">Start on the span where the structure begins</param>
|
||||||
@@ -202,6 +193,7 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T SpanToStructureBigEndian<T>(ReadOnlySpan<byte> bytes, int start, int length) where T : struct
|
public static T SpanToStructureBigEndian<T>(ReadOnlySpan<byte> bytes, int start, int length) where T : struct
|
||||||
{
|
{
|
||||||
var str = SpanToStructureLittleEndian<T>(bytes.Slice(start, length));
|
var str = SpanToStructureLittleEndian<T>(bytes.Slice(start, length));
|
||||||
|
|
||||||
return(T)SwapStructureMembersEndian(str);
|
return(T)SwapStructureMembersEndian(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +208,7 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T SpanToStructurePdpEndian<T>(ReadOnlySpan<byte> bytes) where T : struct
|
public static T SpanToStructurePdpEndian<T>(ReadOnlySpan<byte> bytes) where T : struct
|
||||||
{
|
{
|
||||||
object str = SpanToStructureLittleEndian<T>(bytes);
|
object str = SpanToStructureLittleEndian<T>(bytes);
|
||||||
|
|
||||||
return(T)SwapStructureMembersEndianPdp(str);
|
return(T)SwapStructureMembersEndianPdp(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,12 +223,13 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T SpanToStructurePdpEndian<T>(ReadOnlySpan<byte> bytes, int start, int length) where T : struct
|
public static T SpanToStructurePdpEndian<T>(ReadOnlySpan<byte> bytes, int start, int length) where T : struct
|
||||||
{
|
{
|
||||||
object str = SpanToStructureLittleEndian<T>(bytes.Slice(start, length));
|
object str = SpanToStructureLittleEndian<T>(bytes.Slice(start, length));
|
||||||
|
|
||||||
return(T)SwapStructureMembersEndianPdp(str);
|
return(T)SwapStructureMembersEndianPdp(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marshal a structure depending on the decoration of <see cref="MarshallingPropertiesAttribute" />. If the decoration
|
/// Marshal a structure depending on the decoration of <see cref="MarshallingPropertiesAttribute" />. If the
|
||||||
/// is not present it will marshal as a reference type containing little endian structure.
|
/// decoration is not present it will marshal as a reference type containing little endian structure.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
@@ -248,56 +242,53 @@ namespace DiscImageChef.Helpers
|
|||||||
public static T MarshalStructure<T>(byte[] bytes) where T : struct
|
public static T MarshalStructure<T>(byte[] bytes) where T : struct
|
||||||
{
|
{
|
||||||
if(!(typeof(T).GetCustomAttribute(typeof(MarshallingPropertiesAttribute)) is MarshallingPropertiesAttribute
|
if(!(typeof(T).GetCustomAttribute(typeof(MarshallingPropertiesAttribute)) is MarshallingPropertiesAttribute
|
||||||
properties)) return ByteArrayToStructureLittleEndian<T>(bytes);
|
properties))
|
||||||
|
return ByteArrayToStructureLittleEndian<T>(bytes);
|
||||||
|
|
||||||
switch(properties.Endian)
|
switch(properties.Endian)
|
||||||
{
|
{
|
||||||
case BitEndian.Little:
|
case BitEndian.Little:
|
||||||
return properties.HasReferences
|
return properties.HasReferences ? ByteArrayToStructureLittleEndian<T>(bytes)
|
||||||
? ByteArrayToStructureLittleEndian<T>(bytes)
|
|
||||||
: SpanToStructureLittleEndian<T>(bytes);
|
: SpanToStructureLittleEndian<T>(bytes);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case BitEndian.Big:
|
case BitEndian.Big:
|
||||||
return properties.HasReferences
|
return properties.HasReferences ? ByteArrayToStructureBigEndian<T>(bytes)
|
||||||
? ByteArrayToStructureBigEndian<T>(bytes)
|
|
||||||
: SpanToStructureBigEndian<T>(bytes);
|
: SpanToStructureBigEndian<T>(bytes);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BitEndian.Pdp:
|
case BitEndian.Pdp:
|
||||||
return properties.HasReferences
|
return properties.HasReferences ? ByteArrayToStructurePdpEndian<T>(bytes)
|
||||||
? ByteArrayToStructurePdpEndian<T>(bytes)
|
|
||||||
: SpanToStructurePdpEndian<T>(bytes);
|
: SpanToStructurePdpEndian<T>(bytes);
|
||||||
default: throw new ArgumentOutOfRangeException();
|
default: throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Swaps all members of a structure</summary>
|
||||||
/// Swaps all members of a structure
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="str"></param>
|
/// <param name="str"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static object SwapStructureMembersEndian(object str)
|
public static object SwapStructureMembersEndian(object str)
|
||||||
{
|
{
|
||||||
var t = str.GetType();
|
Type t = str.GetType();
|
||||||
var fieldInfo = t.GetFields();
|
FieldInfo[] fieldInfo = t.GetFields();
|
||||||
foreach (var fi in fieldInfo)
|
|
||||||
|
foreach(FieldInfo fi in fieldInfo)
|
||||||
if(fi.FieldType == typeof(short))
|
if(fi.FieldType == typeof(short))
|
||||||
{
|
{
|
||||||
var x = (short) fi.GetValue(str);
|
short x = (short)fi.GetValue(str);
|
||||||
fi.SetValue(str, (short)((x << 8) | ((x >> 8) & 0xFF)));
|
fi.SetValue(str, (short)((x << 8) | ((x >> 8) & 0xFF)));
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(int))
|
else if(fi.FieldType == typeof(int))
|
||||||
{
|
{
|
||||||
var x = (int) fi.GetValue(str);
|
int x = (int)fi.GetValue(str);
|
||||||
x = (int)(((x << 8) & 0xFF00FF00) | (((uint)x >> 8) & 0xFF00FF));
|
x = (int)(((x << 8) & 0xFF00FF00) | (((uint)x >> 8) & 0xFF00FF));
|
||||||
fi.SetValue(str, (int)(((uint)x << 16) | (((uint)x >> 16) & 0xFFFF)));
|
fi.SetValue(str, (int)(((uint)x << 16) | (((uint)x >> 16) & 0xFFFF)));
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(long))
|
else if(fi.FieldType == typeof(long))
|
||||||
{
|
{
|
||||||
var x = (long) fi.GetValue(str);
|
long x = (long)fi.GetValue(str);
|
||||||
x = ((x & 0x00000000FFFFFFFF) << 32) | (long)(((ulong)x & 0xFFFFFFFF00000000) >> 32);
|
x = ((x & 0x00000000FFFFFFFF) << 32) | (long)(((ulong)x & 0xFFFFFFFF00000000) >> 32);
|
||||||
x = ((x & 0x0000FFFF0000FFFF) << 16) | (long)(((ulong)x & 0xFFFF0000FFFF0000) >> 16);
|
x = ((x & 0x0000FFFF0000FFFF) << 16) | (long)(((ulong)x & 0xFFFF0000FFFF0000) >> 16);
|
||||||
x = ((x & 0x00FF00FF00FF00FF) << 8) | (long)(((ulong)x & 0xFF00FF00FF00FF00) >> 8);
|
x = ((x & 0x00FF00FF00FF00FF) << 8) | (long)(((ulong)x & 0xFF00FF00FF00FF00) >> 8);
|
||||||
@@ -306,18 +297,18 @@ namespace DiscImageChef.Helpers
|
|||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(ushort))
|
else if(fi.FieldType == typeof(ushort))
|
||||||
{
|
{
|
||||||
var x = (ushort) fi.GetValue(str);
|
ushort x = (ushort)fi.GetValue(str);
|
||||||
fi.SetValue(str, (ushort)((x << 8) | (x >> 8)));
|
fi.SetValue(str, (ushort)((x << 8) | (x >> 8)));
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(uint))
|
else if(fi.FieldType == typeof(uint))
|
||||||
{
|
{
|
||||||
var x = (uint) fi.GetValue(str);
|
uint x = (uint)fi.GetValue(str);
|
||||||
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF);
|
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF);
|
||||||
fi.SetValue(str, (x << 16) | (x >> 16));
|
fi.SetValue(str, (x << 16) | (x >> 16));
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(ulong))
|
else if(fi.FieldType == typeof(ulong))
|
||||||
{
|
{
|
||||||
var x = (ulong) fi.GetValue(str);
|
ulong x = (ulong)fi.GetValue(str);
|
||||||
x = ((x & 0x00000000FFFFFFFF) << 32) | ((x & 0xFFFFFFFF00000000) >> 32);
|
x = ((x & 0x00000000FFFFFFFF) << 32) | ((x & 0xFFFFFFFF00000000) >> 32);
|
||||||
x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x & 0xFFFF0000FFFF0000) >> 16);
|
x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x & 0xFFFF0000FFFF0000) >> 16);
|
||||||
x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x & 0xFF00FF00FF00FF00) >> 8);
|
x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x & 0xFF00FF00FF00FF00) >> 8);
|
||||||
@@ -325,21 +316,26 @@ namespace DiscImageChef.Helpers
|
|||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(float))
|
else if(fi.FieldType == typeof(float))
|
||||||
{
|
{
|
||||||
var flt = (float) fi.GetValue(str);
|
float flt = (float)fi.GetValue(str);
|
||||||
var flt_b = BitConverter.GetBytes(flt);
|
byte[] flt_b = BitConverter.GetBytes(flt);
|
||||||
fi.SetValue(str, BitConverter.ToSingle(new[] {flt_b[3], flt_b[2], flt_b[1], flt_b[0]}, 0));
|
|
||||||
|
fi.SetValue(str, BitConverter.ToSingle(new[]
|
||||||
|
{
|
||||||
|
flt_b[3], flt_b[2], flt_b[1], flt_b[0]
|
||||||
|
}, 0));
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(double))
|
else if(fi.FieldType == typeof(double))
|
||||||
{
|
{
|
||||||
var dbl = (double) fi.GetValue(str);
|
double dbl = (double)fi.GetValue(str);
|
||||||
var dbl_b = BitConverter.GetBytes(dbl);
|
byte[] dbl_b = BitConverter.GetBytes(dbl);
|
||||||
fi.SetValue(str,
|
|
||||||
BitConverter
|
fi.SetValue(str, BitConverter.ToDouble(new[]
|
||||||
.ToDouble(
|
{
|
||||||
new[] {dbl_b[7], dbl_b[6], dbl_b[5], dbl_b[4], dbl_b[3], dbl_b[2], dbl_b[1], dbl_b[0]},
|
dbl_b[7], dbl_b[6], dbl_b[5], dbl_b[4], dbl_b[3], dbl_b[2], dbl_b[1], dbl_b[0]
|
||||||
0));
|
}, 0));
|
||||||
}
|
}
|
||||||
else if (fi.FieldType == typeof(byte) || fi.FieldType == typeof(sbyte))
|
else if(fi.FieldType == typeof(byte) ||
|
||||||
|
fi.FieldType == typeof(sbyte))
|
||||||
{
|
{
|
||||||
// Do nothing, can't byteswap them!
|
// Do nothing, can't byteswap them!
|
||||||
}
|
}
|
||||||
@@ -347,11 +343,14 @@ namespace DiscImageChef.Helpers
|
|||||||
{
|
{
|
||||||
// TODO: Swap GUID
|
// TODO: Swap GUID
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Swap arrays and enums
|
// TODO: Swap arrays and enums
|
||||||
else if (fi.FieldType.IsValueType && !fi.FieldType.IsEnum && !fi.FieldType.IsArray)
|
else if(fi.FieldType.IsValueType &&
|
||||||
|
!fi.FieldType.IsEnum &&
|
||||||
|
!fi.FieldType.IsArray)
|
||||||
{
|
{
|
||||||
var obj = fi.GetValue(str);
|
object obj = fi.GetValue(str);
|
||||||
var strc = SwapStructureMembersEndian(obj);
|
object strc = SwapStructureMembersEndian(obj);
|
||||||
fi.SetValue(str, strc);
|
fi.SetValue(str, strc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,49 +360,58 @@ namespace DiscImageChef.Helpers
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static object SwapStructureMembersEndianPdp(object str)
|
public static object SwapStructureMembersEndianPdp(object str)
|
||||||
{
|
{
|
||||||
var t = str.GetType();
|
Type t = str.GetType();
|
||||||
var fieldInfo = t.GetFields();
|
FieldInfo[] fieldInfo = t.GetFields();
|
||||||
foreach (var fi in fieldInfo)
|
|
||||||
if (fi.FieldType == typeof(short) || fi.FieldType == typeof(long) || fi.FieldType == typeof(ushort) ||
|
foreach(FieldInfo fi in fieldInfo)
|
||||||
fi.FieldType == typeof(ulong) || fi.FieldType == typeof(float) || fi.FieldType == typeof(double) ||
|
if(fi.FieldType == typeof(short) ||
|
||||||
fi.FieldType == typeof(byte) || fi.FieldType == typeof(sbyte) || fi.FieldType == typeof(Guid))
|
fi.FieldType == typeof(long) ||
|
||||||
|
fi.FieldType == typeof(ushort) ||
|
||||||
|
fi.FieldType == typeof(ulong) ||
|
||||||
|
fi.FieldType == typeof(float) ||
|
||||||
|
fi.FieldType == typeof(double) ||
|
||||||
|
fi.FieldType == typeof(byte) ||
|
||||||
|
fi.FieldType == typeof(sbyte) ||
|
||||||
|
fi.FieldType == typeof(Guid))
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(int))
|
else if(fi.FieldType == typeof(int))
|
||||||
{
|
{
|
||||||
var x = (int) fi.GetValue(str);
|
int x = (int)fi.GetValue(str);
|
||||||
fi.SetValue(str, ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16));
|
fi.SetValue(str, ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16));
|
||||||
}
|
}
|
||||||
else if(fi.FieldType == typeof(uint))
|
else if(fi.FieldType == typeof(uint))
|
||||||
{
|
{
|
||||||
var x = (uint) fi.GetValue(str);
|
uint x = (uint)fi.GetValue(str);
|
||||||
fi.SetValue(str, ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16));
|
fi.SetValue(str, ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Swap arrays and enums
|
// TODO: Swap arrays and enums
|
||||||
else if (fi.FieldType.IsValueType && !fi.FieldType.IsEnum && !fi.FieldType.IsArray)
|
else if(fi.FieldType.IsValueType &&
|
||||||
|
!fi.FieldType.IsEnum &&
|
||||||
|
!fi.FieldType.IsArray)
|
||||||
{
|
{
|
||||||
var obj = fi.GetValue(str);
|
object obj = fi.GetValue(str);
|
||||||
var strc = SwapStructureMembersEndianPdp(obj);
|
object strc = SwapStructureMembersEndianPdp(obj);
|
||||||
fi.SetValue(str, strc);
|
fi.SetValue(str, strc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Marshal a structure to little-endian binary data</summary>
|
||||||
/// Marshal a structure to little-endian binary data
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="bytes">Byte array containing the binary data</param>
|
/// <param name="bytes">Byte array containing the binary data</param>
|
||||||
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
/// <typeparam name="T">Type of the structure to marshal</typeparam>
|
||||||
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
/// <returns>The binary data marshalled in a structure with the specified type</returns>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static byte[] StructureToByteArrayLittleEndian<T>(T str) where T : struct
|
public static byte[] StructureToByteArrayLittleEndian<T>(T str) where T : struct
|
||||||
{
|
{
|
||||||
var buf = new byte[SizeOf<T>()];
|
byte[] buf = new byte[SizeOf<T>()];
|
||||||
var ptr = GCHandle.Alloc(buf, GCHandleType.Pinned);
|
GCHandle ptr = GCHandle.Alloc(buf, GCHandleType.Pinned);
|
||||||
System.Runtime.InteropServices.Marshal.StructureToPtr(str, ptr.AddrOfPinnedObject(), false);
|
System.Runtime.InteropServices.Marshal.StructureToPtr(str, ptr.AddrOfPinnedObject(), false);
|
||||||
ptr.Free();
|
ptr.Free();
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,19 +40,10 @@ using System;
|
|||||||
|
|
||||||
namespace DiscImageChef.Helpers
|
namespace DiscImageChef.Helpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Defines properties to help marshalling structs from binary data</summary>
|
||||||
/// Defines properties to help marshalling structs from binary data
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
[AttributeUsage(AttributeTargets.Struct)]
|
||||||
public class MarshallingPropertiesAttribute : Attribute
|
public class MarshallingPropertiesAttribute : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>c</summary>
|
|
||||||
public BitEndian Endian { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// Tells if the structure, or any nested structure, has any non-value type (e.g. arrays, strings, etc).
|
|
||||||
/// </summary>
|
|
||||||
public bool HasReferences { get; set; }
|
|
||||||
|
|
||||||
/// <summary>Defines properties to help marshalling structs from binary data</summary>
|
/// <summary>Defines properties to help marshalling structs from binary data</summary>
|
||||||
/// <param name="endian">Defines properties to help marshalling structs from binary data</param>
|
/// <param name="endian">Defines properties to help marshalling structs from binary data</param>
|
||||||
public MarshallingPropertiesAttribute(BitEndian endian)
|
public MarshallingPropertiesAttribute(BitEndian endian)
|
||||||
@@ -60,5 +51,10 @@ namespace DiscImageChef.Helpers
|
|||||||
Endian = endian;
|
Endian = endian;
|
||||||
HasReferences = true;
|
HasReferences = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>c</summary>
|
||||||
|
public BitEndian Endian { get; }
|
||||||
|
/// <summary>Tells if the structure, or any nested structure, has any non-value type (e.g. arrays, strings, etc).</summary>
|
||||||
|
public bool HasReferences { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,16 +37,12 @@ namespace DiscImageChef
|
|||||||
{
|
{
|
||||||
public static class StringHandlers
|
public static class StringHandlers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>Converts a null-terminated (aka C string) ASCII byte array to a C# string</summary>
|
||||||
/// Converts a null-terminated (aka C string) ASCII byte array to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The corresponding C# string</returns>
|
/// <returns>The corresponding C# string</returns>
|
||||||
/// <param name="CString">A null-terminated (aka C string) ASCII byte array</param>
|
/// <param name="CString">A null-terminated (aka C string) ASCII byte array</param>
|
||||||
public static string CToString(byte[] CString) => CToString(CString, Encoding.ASCII);
|
public static string CToString(byte[] CString) => CToString(CString, Encoding.ASCII);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a null-terminated (aka C string) byte array with the specified encoding to a C# string</summary>
|
||||||
/// Converts a null-terminated (aka C string) byte array with the specified encoding to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The corresponding C# string</returns>
|
/// <returns>The corresponding C# string</returns>
|
||||||
/// <param name="CString">A null-terminated (aka C string) byte array in the specified encoding</param>
|
/// <param name="CString">A null-terminated (aka C string) byte array in the specified encoding</param>
|
||||||
/// <param name="encoding">Encoding.</param>
|
/// <param name="encoding">Encoding.</param>
|
||||||
@@ -54,7 +50,8 @@ namespace DiscImageChef
|
|||||||
/// <param name="start">Start decodint at this position</param>
|
/// <param name="start">Start decodint at this position</param>
|
||||||
public static string CToString(byte[] CString, Encoding encoding, bool twoBytes = false, int start = 0)
|
public static string CToString(byte[] CString, Encoding encoding, bool twoBytes = false, int start = 0)
|
||||||
{
|
{
|
||||||
if(CString == null) return null;
|
if(CString == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
@@ -63,9 +60,11 @@ namespace DiscImageChef
|
|||||||
if(CString[i] == 0)
|
if(CString[i] == 0)
|
||||||
if(twoBytes)
|
if(twoBytes)
|
||||||
{
|
{
|
||||||
if(i + 1 < CString.Length && CString[i + 1] == 0)
|
if(i + 1 < CString.Length &&
|
||||||
|
CString[i + 1] == 0)
|
||||||
{
|
{
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +74,8 @@ namespace DiscImageChef
|
|||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(twoBytes && len % 2 > 0) len--;
|
if(twoBytes && len % 2 > 0)
|
||||||
|
len--;
|
||||||
|
|
||||||
byte[] dest = new byte[len];
|
byte[] dest = new byte[len];
|
||||||
Array.Copy(CString, start, dest, 0, len);
|
Array.Copy(CString, start, dest, 0, len);
|
||||||
@@ -83,30 +83,28 @@ namespace DiscImageChef
|
|||||||
return len == 0 ? "" : encoding.GetString(dest);
|
return len == 0 ? "" : encoding.GetString(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a length-prefixed (aka Pascal string) ASCII byte array to a C# string</summary>
|
||||||
/// Converts a length-prefixed (aka Pascal string) ASCII byte array to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The corresponding C# string</returns>
|
/// <returns>The corresponding C# string</returns>
|
||||||
/// <param name="PascalString">A length-prefixed (aka Pascal string) ASCII byte array</param>
|
/// <param name="PascalString">A length-prefixed (aka Pascal string) ASCII byte array</param>
|
||||||
public static string PascalToString(byte[] PascalString) => PascalToString(PascalString, Encoding.ASCII);
|
public static string PascalToString(byte[] PascalString) => PascalToString(PascalString, Encoding.ASCII);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a length-prefixed (aka Pascal string) ASCII byte array to a C# string</summary>
|
||||||
/// Converts a length-prefixed (aka Pascal string) ASCII byte array to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The corresponding C# string</returns>
|
/// <returns>The corresponding C# string</returns>
|
||||||
/// <param name="PascalString">A length-prefixed (aka Pascal string) ASCII byte array</param>
|
/// <param name="PascalString">A length-prefixed (aka Pascal string) ASCII byte array</param>
|
||||||
/// <param name="encoding">Encoding.</param>
|
/// <param name="encoding">Encoding.</param>
|
||||||
/// <param name="start">Start decodint at this position</param>
|
/// <param name="start">Start decodint at this position</param>
|
||||||
public static string PascalToString(byte[] PascalString, Encoding encoding, int start = 0)
|
public static string PascalToString(byte[] PascalString, Encoding encoding, int start = 0)
|
||||||
{
|
{
|
||||||
if(PascalString == null) return null;
|
if(PascalString == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
byte length = PascalString[start];
|
byte length = PascalString[start];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
for(int i = start + 1; i < length + 1 && i < PascalString.Length; i++)
|
for(int i = start + 1; i < length + 1 && i < PascalString.Length; i++)
|
||||||
{
|
{
|
||||||
if(PascalString[i] == 0) break;
|
if(PascalString[i] == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
@@ -117,43 +115,41 @@ namespace DiscImageChef
|
|||||||
return len == 0 ? "" : encoding.GetString(dest);
|
return len == 0 ? "" : encoding.GetString(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a space (' ', 0x20, ASCII SPACE) padded ASCII byte array to a C# string</summary>
|
||||||
/// Converts a space (' ', 0x20, ASCII SPACE) padded ASCII byte array to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The corresponding C# string</returns>
|
/// <returns>The corresponding C# string</returns>
|
||||||
/// <param name="SpacePaddedString">A space (' ', 0x20, ASCII SPACE) padded ASCII byte array</param>
|
/// <param name="SpacePaddedString">A space (' ', 0x20, ASCII SPACE) padded ASCII byte array</param>
|
||||||
public static string SpacePaddedToString(byte[] SpacePaddedString) =>
|
public static string SpacePaddedToString(byte[] SpacePaddedString) =>
|
||||||
SpacePaddedToString(SpacePaddedString, Encoding.ASCII);
|
SpacePaddedToString(SpacePaddedString, Encoding.ASCII);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts a space (' ', 0x20, ASCII SPACE) padded ASCII byte array to a C# string</summary>
|
||||||
/// Converts a space (' ', 0x20, ASCII SPACE) padded ASCII byte array to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The corresponding C# string</returns>
|
/// <returns>The corresponding C# string</returns>
|
||||||
/// <param name="SpacePaddedString">A space (' ', 0x20, ASCII SPACE) padded ASCII byte array</param>
|
/// <param name="SpacePaddedString">A space (' ', 0x20, ASCII SPACE) padded ASCII byte array</param>
|
||||||
/// <param name="encoding">Encoding.</param>
|
/// <param name="encoding">Encoding.</param>
|
||||||
/// <param name="start">Start decodint at this position</param>
|
/// <param name="start">Start decodint at this position</param>
|
||||||
public static string SpacePaddedToString(byte[] SpacePaddedString, Encoding encoding, int start = 0)
|
public static string SpacePaddedToString(byte[] SpacePaddedString, Encoding encoding, int start = 0)
|
||||||
{
|
{
|
||||||
if(SpacePaddedString == null) return null;
|
if(SpacePaddedString == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
int len = start;
|
int len = start;
|
||||||
|
|
||||||
for(int i = SpacePaddedString.Length; i >= start; i--)
|
for(int i = SpacePaddedString.Length; i >= start; i--)
|
||||||
{
|
{
|
||||||
if(i == start) return "";
|
if(i == start)
|
||||||
|
return"";
|
||||||
|
|
||||||
if(SpacePaddedString[i - 1] == 0x20) continue;
|
if(SpacePaddedString[i - 1] == 0x20)
|
||||||
|
continue;
|
||||||
|
|
||||||
len = i;
|
len = i;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len == 0 ? "" : encoding.GetString(SpacePaddedString, start, len);
|
return len == 0 ? "" : encoding.GetString(SpacePaddedString, start, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Converts an OSTA compressed unicode byte array to a C# string</summary>
|
||||||
/// Converts an OSTA compressed unicode byte array to a C# string
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The C# string.</returns>
|
/// <returns>The C# string.</returns>
|
||||||
/// <param name="dstring">OSTA compressed unicode byte array.</param>
|
/// <param name="dstring">OSTA compressed unicode byte array.</param>
|
||||||
public static string DecompressUnicode(byte[] dstring)
|
public static string DecompressUnicode(byte[] dstring)
|
||||||
@@ -162,16 +158,22 @@ namespace DiscImageChef
|
|||||||
byte compId = dstring[0];
|
byte compId = dstring[0];
|
||||||
string temp = "";
|
string temp = "";
|
||||||
|
|
||||||
if(compId != 8 && compId != 16) return null;
|
if(compId != 8 &&
|
||||||
|
compId != 16)
|
||||||
|
return null;
|
||||||
|
|
||||||
for(int byteIndex = 1; byteIndex < dstring.Length;)
|
for(int byteIndex = 1; byteIndex < dstring.Length;)
|
||||||
{
|
{
|
||||||
if(compId == 16) unicode = (ushort)(dstring[byteIndex++] << 8);
|
if(compId == 16)
|
||||||
else unicode = 0;
|
unicode = (ushort)(dstring[byteIndex++] << 8);
|
||||||
|
else
|
||||||
|
unicode = 0;
|
||||||
|
|
||||||
if(byteIndex < dstring.Length) unicode |= dstring[byteIndex++];
|
if(byteIndex < dstring.Length)
|
||||||
|
unicode |= dstring[byteIndex++];
|
||||||
|
|
||||||
if(unicode == 0) break;
|
if(unicode == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
temp += Encoding.Unicode.GetString(BitConverter.GetBytes(unicode));
|
temp += Encoding.Unicode.GetString(BitConverter.GetBytes(unicode));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ namespace DiscImageChef
|
|||||||
public static uint Swap(uint x)
|
public static uint Swap(uint x)
|
||||||
{
|
{
|
||||||
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF);
|
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0xFF00FF);
|
||||||
|
|
||||||
return(x << 16) | (x >> 16);
|
return(x << 16) | (x >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ namespace DiscImageChef
|
|||||||
public static int Swap(int x)
|
public static int Swap(int x)
|
||||||
{
|
{
|
||||||
x = (int)(((x << 8) & 0xFF00FF00) | (((uint)x >> 8) & 0xFF00FF));
|
x = (int)(((x << 8) & 0xFF00FF00) | (((uint)x >> 8) & 0xFF00FF));
|
||||||
|
|
||||||
return(int)(((uint)x << 16) | (((uint)x >> 16) & 0xFFFF));
|
return(int)(((uint)x << 16) | (((uint)x >> 16) & 0xFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ namespace DiscImageChef
|
|||||||
x = ((x & 0x00000000FFFFFFFF) << 32) | ((x & 0xFFFFFFFF00000000) >> 32);
|
x = ((x & 0x00000000FFFFFFFF) << 32) | ((x & 0xFFFFFFFF00000000) >> 32);
|
||||||
x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x & 0xFFFF0000FFFF0000) >> 16);
|
x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x & 0xFFFF0000FFFF0000) >> 16);
|
||||||
x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x & 0xFF00FF00FF00FF00) >> 8);
|
x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x & 0xFF00FF00FF00FF00) >> 8);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +80,7 @@ namespace DiscImageChef
|
|||||||
x = ((x & 0x00000000FFFFFFFF) << 32) | (long)(((ulong)x & 0xFFFFFFFF00000000) >> 32);
|
x = ((x & 0x00000000FFFFFFFF) << 32) | (long)(((ulong)x & 0xFFFFFFFF00000000) >> 32);
|
||||||
x = ((x & 0x0000FFFF0000FFFF) << 16) | (long)(((ulong)x & 0xFFFF0000FFFF0000) >> 16);
|
x = ((x & 0x0000FFFF0000FFFF) << 16) | (long)(((ulong)x & 0xFFFF0000FFFF0000) >> 16);
|
||||||
x = ((x & 0x00FF00FF00FF00FF) << 8) | (long)(((ulong)x & 0xFF00FF00FF00FF00) >> 8);
|
x = ((x & 0x00FF00FF00FF00FF) << 8) | (long)(((ulong)x & 0xFF00FF00FF00FF00) >> 8);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user