179 lines
6.6 KiB
C#
179 lines
6.6 KiB
C#
|
using System;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
|
||
|
namespace UnityEngine.InputSystem.Utilities
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// A four-character code.
|
||
|
/// </summary>
|
||
|
/// <remarks>
|
||
|
/// A four-character code is a struct containing four byte characters totalling a single <c>int</c>.
|
||
|
/// FourCCs are frequently used in the input system to identify the format of data sent to or from
|
||
|
/// the native backend representing events, input device state or commands sent to input devices.
|
||
|
/// </remarks>
|
||
|
public struct FourCC : IEquatable<FourCC>
|
||
|
{
|
||
|
private int m_Code;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Create a FourCC from the given integer.
|
||
|
/// </summary>
|
||
|
/// <param name="code">FourCC code represented as an <c>int</c>. Character order is
|
||
|
/// little endian. "ABCD" is stored with A in the highest order 8 bits and D in the
|
||
|
/// lowest order 8 bits.</param>
|
||
|
/// <remarks>
|
||
|
/// This method does not actually verify whether the four characters in the code
|
||
|
/// are printable.
|
||
|
/// </remarks>
|
||
|
public FourCC(int code)
|
||
|
{
|
||
|
m_Code = code;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Create a FourCC from the given four characters.
|
||
|
/// </summary>
|
||
|
/// <param name="a">First character.</param>
|
||
|
/// <param name="b">Second character.</param>
|
||
|
/// <param name="c">Third character.</param>
|
||
|
/// <param name="d">Fourth character.</param>
|
||
|
public FourCC(char a, char b = ' ', char c = ' ', char d = ' ')
|
||
|
{
|
||
|
m_Code = (a << 24) | (b << 16) | (c << 8) | d;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Create a FourCC from the given string.
|
||
|
/// </summary>
|
||
|
/// <param name="str">A string with four characters or less but with at least one character.</param>
|
||
|
/// <exception cref="ArgumentException"><paramref name="str"/> is empty or has more than four characters.</exception>
|
||
|
/// <exception cref="ArgumentNullException"><paramref name="str"/> is <c>null</c>.</exception>
|
||
|
public FourCC(string str)
|
||
|
: this()
|
||
|
{
|
||
|
if (str == null)
|
||
|
throw new ArgumentNullException(nameof(str));
|
||
|
|
||
|
var length = str.Length;
|
||
|
if (length < 1 || length > 4)
|
||
|
throw new ArgumentException("FourCC string must be one to four characters long!", nameof(str));
|
||
|
|
||
|
var a = str[0];
|
||
|
var b = length > 1 ? str[1] : ' ';
|
||
|
var c = length > 2 ? str[2] : ' ';
|
||
|
var d = length > 3 ? str[3] : ' ';
|
||
|
|
||
|
m_Code = (a << 24) | (b << 16) | (c << 8) | d;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Convert the given FourCC into an <c>int</c>.
|
||
|
/// </summary>
|
||
|
/// <param name="fourCC">A FourCC.</param>
|
||
|
/// <returns>The four characters of the code packed into one <c>int</c>. Character order is
|
||
|
/// little endian. "ABCD" is stored with A in the highest order 8 bits and D in the
|
||
|
/// lowest order 8 bits.</returns>
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public static implicit operator int(FourCC fourCC)
|
||
|
{
|
||
|
return fourCC.m_Code;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Convert the given <c>int</c> into a FourCC.
|
||
|
/// </summary>
|
||
|
/// <param name="i">FourCC code represented as an <c>int</c>. Character order is
|
||
|
/// little endian. "ABCD" is stored with A in the highest order 8 bits and D in the
|
||
|
/// lowest order 8 bits.</param>
|
||
|
/// <returns>The FourCC converted from <paramref name="i"/>.</returns>
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public static implicit operator FourCC(int i)
|
||
|
{
|
||
|
return new FourCC(i);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Convert the FourCC into a string in the form of "ABCD".
|
||
|
/// </summary>
|
||
|
/// <returns>String representation of the FourCC.</returns>
|
||
|
public override string ToString()
|
||
|
{
|
||
|
return
|
||
|
$"{(char) (m_Code >> 24)}{(char) ((m_Code & 0xff0000) >> 16)}{(char) ((m_Code & 0xff00) >> 8)}{(char) (m_Code & 0xff)}";
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Compare two FourCCs for equality.
|
||
|
/// </summary>
|
||
|
/// <param name="other">Another FourCC.</param>
|
||
|
/// <returns>True if the two FourCCs are equal, i.e. have the same exact
|
||
|
/// character codes.</returns>
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public bool Equals(FourCC other)
|
||
|
{
|
||
|
return m_Code == other.m_Code;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Compare the FourCC to the given object.
|
||
|
/// </summary>
|
||
|
/// <param name="obj">An object. Can be null.</param>
|
||
|
/// <returns>True if <paramref name="obj"/> is a FourCC that has the same
|
||
|
/// character code sequence.</returns>
|
||
|
public override bool Equals(object obj)
|
||
|
{
|
||
|
if (ReferenceEquals(null, obj))
|
||
|
return false;
|
||
|
return obj is FourCC cc && Equals(cc);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Compute a hash code for the FourCC.
|
||
|
/// </summary>
|
||
|
/// <returns>Simply returns the FourCC converted to an <c>int</c>.</returns>
|
||
|
public override int GetHashCode()
|
||
|
{
|
||
|
return m_Code;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Compare two FourCCs for equality.
|
||
|
/// </summary>
|
||
|
/// <param name="left">First FourCC.</param>
|
||
|
/// <param name="right">Second FourCC.</param>
|
||
|
/// <returns>True if the two FourCCs are equal, i.e. have the same exact
|
||
|
/// character codes.</returns>
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public static bool operator==(FourCC left, FourCC right)
|
||
|
{
|
||
|
return left.m_Code == right.m_Code;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Compare two FourCCs for inequality.
|
||
|
/// </summary>
|
||
|
/// <param name="left">First FourCC.</param>
|
||
|
/// <param name="right">Second FourCC.</param>
|
||
|
/// <returns>True if the two FourCCs are not equal, i.e. do not have the same exact
|
||
|
/// character codes.</returns>
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public static bool operator!=(FourCC left, FourCC right)
|
||
|
{
|
||
|
return left.m_Code != right.m_Code;
|
||
|
}
|
||
|
|
||
|
// Make annoying Microsoft code analyzer happy.
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public static FourCC FromInt32(int i)
|
||
|
{
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||
|
public static int ToInt32(FourCC fourCC)
|
||
|
{
|
||
|
return fourCC.m_Code;
|
||
|
}
|
||
|
}
|
||
|
}
|