A game about forced loneliness, made by TACStudios
1using System;
2using System.Runtime.CompilerServices;
3
4namespace UnityEngine.InputSystem.Utilities
5{
6 /// <summary>
7 /// A four-character code.
8 /// </summary>
9 /// <remarks>
10 /// A four-character code is a struct containing four byte characters totalling a single <c>int</c>.
11 /// FourCCs are frequently used in the input system to identify the format of data sent to or from
12 /// the native backend representing events, input device state or commands sent to input devices.
13 /// </remarks>
14 public struct FourCC : IEquatable<FourCC>
15 {
16 private int m_Code;
17
18 /// <summary>
19 /// Create a FourCC from the given integer.
20 /// </summary>
21 /// <param name="code">FourCC code represented as an <c>int</c>. Character order is
22 /// little endian. "ABCD" is stored with A in the highest order 8 bits and D in the
23 /// lowest order 8 bits.</param>
24 /// <remarks>
25 /// This method does not actually verify whether the four characters in the code
26 /// are printable.
27 /// </remarks>
28 public FourCC(int code)
29 {
30 m_Code = code;
31 }
32
33 /// <summary>
34 /// Create a FourCC from the given four characters.
35 /// </summary>
36 /// <param name="a">First character.</param>
37 /// <param name="b">Second character.</param>
38 /// <param name="c">Third character.</param>
39 /// <param name="d">Fourth character.</param>
40 public FourCC(char a, char b = ' ', char c = ' ', char d = ' ')
41 {
42 m_Code = (a << 24) | (b << 16) | (c << 8) | d;
43 }
44
45 /// <summary>
46 /// Create a FourCC from the given string.
47 /// </summary>
48 /// <param name="str">A string with four characters or less but with at least one character.</param>
49 /// <exception cref="ArgumentException"><paramref name="str"/> is empty or has more than four characters.</exception>
50 /// <exception cref="ArgumentNullException"><paramref name="str"/> is <c>null</c>.</exception>
51 public FourCC(string str)
52 : this()
53 {
54 if (str == null)
55 throw new ArgumentNullException(nameof(str));
56
57 var length = str.Length;
58 if (length < 1 || length > 4)
59 throw new ArgumentException("FourCC string must be one to four characters long!", nameof(str));
60
61 var a = str[0];
62 var b = length > 1 ? str[1] : ' ';
63 var c = length > 2 ? str[2] : ' ';
64 var d = length > 3 ? str[3] : ' ';
65
66 m_Code = (a << 24) | (b << 16) | (c << 8) | d;
67 }
68
69 /// <summary>
70 /// Convert the given FourCC into an <c>int</c>.
71 /// </summary>
72 /// <param name="fourCC">A FourCC.</param>
73 /// <returns>The four characters of the code packed into one <c>int</c>. Character order is
74 /// little endian. "ABCD" is stored with A in the highest order 8 bits and D in the
75 /// lowest order 8 bits.</returns>
76 [MethodImpl(MethodImplOptions.AggressiveInlining)]
77 public static implicit operator int(FourCC fourCC)
78 {
79 return fourCC.m_Code;
80 }
81
82 /// <summary>
83 /// Convert the given <c>int</c> into a FourCC.
84 /// </summary>
85 /// <param name="i">FourCC code represented as an <c>int</c>. Character order is
86 /// little endian. "ABCD" is stored with A in the highest order 8 bits and D in the
87 /// lowest order 8 bits.</param>
88 /// <returns>The FourCC converted from <paramref name="i"/>.</returns>
89 [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 public static implicit operator FourCC(int i)
91 {
92 return new FourCC(i);
93 }
94
95 /// <summary>
96 /// Convert the FourCC into a string in the form of "ABCD".
97 /// </summary>
98 /// <returns>String representation of the FourCC.</returns>
99 public override string ToString()
100 {
101 return
102 $"{(char) (m_Code >> 24)}{(char) ((m_Code & 0xff0000) >> 16)}{(char) ((m_Code & 0xff00) >> 8)}{(char) (m_Code & 0xff)}";
103 }
104
105 /// <summary>
106 /// Compare two FourCCs for equality.
107 /// </summary>
108 /// <param name="other">Another FourCC.</param>
109 /// <returns>True if the two FourCCs are equal, i.e. have the same exact
110 /// character codes.</returns>
111 [MethodImpl(MethodImplOptions.AggressiveInlining)]
112 public bool Equals(FourCC other)
113 {
114 return m_Code == other.m_Code;
115 }
116
117 /// <summary>
118 /// Compare the FourCC to the given object.
119 /// </summary>
120 /// <param name="obj">An object. Can be null.</param>
121 /// <returns>True if <paramref name="obj"/> is a FourCC that has the same
122 /// character code sequence.</returns>
123 public override bool Equals(object obj)
124 {
125 if (ReferenceEquals(null, obj))
126 return false;
127 return obj is FourCC cc && Equals(cc);
128 }
129
130 /// <summary>
131 /// Compute a hash code for the FourCC.
132 /// </summary>
133 /// <returns>Simply returns the FourCC converted to an <c>int</c>.</returns>
134 public override int GetHashCode()
135 {
136 return m_Code;
137 }
138
139 /// <summary>
140 /// Compare two FourCCs for equality.
141 /// </summary>
142 /// <param name="left">First FourCC.</param>
143 /// <param name="right">Second FourCC.</param>
144 /// <returns>True if the two FourCCs are equal, i.e. have the same exact
145 /// character codes.</returns>
146 [MethodImpl(MethodImplOptions.AggressiveInlining)]
147 public static bool operator==(FourCC left, FourCC right)
148 {
149 return left.m_Code == right.m_Code;
150 }
151
152 /// <summary>
153 /// Compare two FourCCs for inequality.
154 /// </summary>
155 /// <param name="left">First FourCC.</param>
156 /// <param name="right">Second FourCC.</param>
157 /// <returns>True if the two FourCCs are not equal, i.e. do not have the same exact
158 /// character codes.</returns>
159 [MethodImpl(MethodImplOptions.AggressiveInlining)]
160 public static bool operator!=(FourCC left, FourCC right)
161 {
162 return left.m_Code != right.m_Code;
163 }
164
165 // Make annoying Microsoft code analyzer happy.
166 [MethodImpl(MethodImplOptions.AggressiveInlining)]
167 public static FourCC FromInt32(int i)
168 {
169 return i;
170 }
171
172 [MethodImpl(MethodImplOptions.AggressiveInlining)]
173 public static int ToInt32(FourCC fourCC)
174 {
175 return fourCC.m_Code;
176 }
177 }
178}