File size: 6,776 Bytes
18a519f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
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;
        }
    }
}