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