d192ca5e07b05dc89aa033d45eb315896ff119e6
[ardour.git] / libs / backends / wavesaudio / wavesapi / BasicTypes / WCFourCC.h
1 /*
2     Copyright (C) 2014 Waves Audio Ltd.
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __WCFourCC_h__
21         #define __WCFourCC_h__
22         
23 /* Copy to include
24 #include "BasicTypes/WCFourCC.h"
25 */
26
27 //#include "BasicTypes/WTByteOrder.h"
28 #include "WCFixedString.h"
29
30
31 // These are preprocessor macros rather than inline functions because most compilers can't
32 // resolve functions at compile-time.
33 #if _BYTEORDER_BIG_ENDIAN==1
34         #define FOURCC_BIG(a, b, c, d)    ((uint32_t(a)<<24)|(uint32_t(b)<<16)|(uint32_t(c)<< 8)|(uint32_t(d)<< 0))
35         #define FOURCC_LITTLE(a, b, c, d) ((uint32_t(a)<< 0)|(uint32_t(b)<< 8)|(uint32_t(c)<<16)|(uint32_t(d)<<24))
36         #define FOURCC_COMPILER(a, b, c, d) FOURCC_BIG(a,b,c,d)
37 #elif _BYTEORDER_BIG_ENDIAN==0
38         #define FOURCC_BIG(a, b, c, d)    ((uint32_t(a)<< 0)|(uint32_t(b)<< 8)|(uint32_t(c)<<16)|(uint32_t(d)<<24))
39         #define FOURCC_LITTLE(a, b, c, d) ((uint32_t(a)<<24)|(uint32_t(b)<<16)|(uint32_t(c)<< 8)|(uint32_t(d)<< 0))
40         #define FOURCC_COMPILER(a, b, c, d) FOURCC_LITTLE(a,b,c,d)
41 #else
42         #error _BYTEORDER_BIG_ENDIAN not defined proparly
43 #endif // _BYTEORDER_HPP_BIG_ENDIAN
44
45 typedef uint32_t WTFourCharCode;
46
47 #ifndef kEnableWCFourCCDebug
48         #define kEnableWCFourCCDebug 0 // set to 1 to enable debug members
49 #endif
50
51
52 class WCFourCC
53 {
54 private:
55         template<class _iter> 
56         static WTFourCharCode stored_from_iter(_iter& i)
57         {
58                 return s_stored_byte_order==wvNS::wvBO::byte_order_big_endian ? FOURCC_BIG(i[0], i[1], i[2], i[3]) : FOURCC_LITTLE(i[0], i[1], i[2], i[3]);
59         }
60
61 public:
62
63         //      static const WCFourCC kDefaultFourCC_prv;
64
65         static WCFourCC kDefaultFourCC_prv() { return WCFourCC(); }
66
67         // change this line will change the byte order in which WCFourCC keeps the four char code
68         static const wvNS::wvBO::byte_order_type s_stored_byte_order = wvNS::wvBO::compiler_byte_order;
69
70         WCFourCC(const char a, const char b, const char c, const char d) : 
71                 m_stored_value(s_stored_byte_order==wvNS::wvBO::compiler_byte_order ? FOURCC_BIG(a,b,c,d) : FOURCC_LITTLE(a,b,c,d))
72         {
73 #if kEnableWCFourCCDebug == 1
74                 m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0';
75 #endif
76         }
77
78         WCFourCC() :
79                 m_stored_value(FOURCC_BIG('?','?','?','?'))      // since the four chars are the same, there is no need to choose between big & little
80         {
81 #if kEnableWCFourCCDebug == 1
82                 m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0';
83 #endif
84         }
85
86         WCFourCC(const WTFourCharCode in_fourCharCode, const wvNS::wvBO::byte_order_type in_byteOrder = wvNS::wvBO::compiler_byte_order) :
87                 m_stored_value(in_byteOrder==s_stored_byte_order ? in_fourCharCode : wvNS::wvBO::swap32(in_fourCharCode))
88         {
89 #if kEnableWCFourCCDebug == 1
90                 m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0';
91 #endif
92         }
93
94         explicit WCFourCC(const char* in_source_string) :
95                 m_stored_value(stored_from_iter(in_source_string))
96         {
97 #if kEnableWCFourCCDebug == 1
98                 m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0';
99 #endif
100         }
101
102         explicit WCFourCC(const WCFixedStringBase& in_source_string) :
103                 m_stored_value(stored_from_iter(in_source_string))
104         {
105 #if kEnableWCFourCCDebug == 1
106                 m_c_str_stored_value[sizeof(WTFourCharCode)] = '\0';
107 #endif
108         }
109
110         WTFourCharCode GetAsSomeEndian(const wvNS::wvBO::byte_order_type in_byteOrder) const
111         {
112                 return s_stored_byte_order==in_byteOrder ? m_stored_value : wvNS::wvBO::swap32(m_stored_value);
113         }
114
115         WTFourCharCode GetAsBigEndian() const
116         {
117                 return s_stored_byte_order==wvNS::wvBO::byte_order_big_endian ? m_stored_value : wvNS::wvBO::swap32(m_stored_value);
118         }
119
120         WTFourCharCode GetAsLittleEndian() const
121         {
122                 return s_stored_byte_order==wvNS::wvBO::byte_order_little_endian ? m_stored_value : wvNS::wvBO::swap32(m_stored_value);
123         }
124
125         WTFourCharCode GetAsCompilerEndian() const
126         {
127                 return s_stored_byte_order==wvNS::wvBO::compiler_byte_order ? m_stored_value : wvNS::wvBO::swap32(m_stored_value);
128         }
129
130         WTFourCharCode GetAsStored() const
131         {
132                 return m_stored_value;
133         }
134
135         char operator[](const unsigned int in_character_index) const
136         {
137                 return char(m_stored_value >> (8 * (s_stored_byte_order==wvNS::wvBO::compiler_byte_order ? 3-in_character_index : in_character_index)));
138         }
139
140         char& operator[](const unsigned int in_character_index)
141         {
142                 return reinterpret_cast<char*>(&m_stored_value)[s_stored_byte_order==wvNS::wvBO::byte_order_little_endian ? 3-in_character_index : in_character_index];
143         }
144     
145     static size_t size()
146     {
147         return sizeof(WTFourCharCode);
148     }
149
150         static size_t max_size()
151         {
152                 return size();
153         }
154     
155         static size_t capacity()
156         {
157                 return size();
158         }
159     
160         WCFixedString4 GetString() const
161         {
162                 WCFixedString4 retVal;
163                 retVal << operator[](0) << operator[](1) << operator[](2) << operator[](3);
164
165                 return retVal;
166         }
167
168 #if kEnableWCFourCCDebug == 1
169         const char* c_str() const
170         {
171                 return m_c_str_stored_value;
172         }
173 #endif
174
175 protected:
176
177 private:
178 #if kEnableWCFourCCDebug == 1
179         union
180         {
181 #endif
182                 WTFourCharCode m_stored_value;
183 #if kEnableWCFourCCDebug == 1
184                 char m_c_str_stored_value[sizeof(WTFourCharCode)+1];
185         };
186 #endif
187
188         WCFourCC& operator=(const WTFourCharCode); // we want initialization from literal to be dome through the constructor
189 };
190
191 inline bool operator<(const WCFourCC in_left, const WCFourCC in_right)
192 {
193         return in_left.GetAsSomeEndian(WCFourCC::s_stored_byte_order) < in_right.GetAsSomeEndian(WCFourCC::s_stored_byte_order);
194 }
195 inline bool operator==(const WCFourCC in_left, const WCFourCC in_right)
196 {
197         return in_left.GetAsSomeEndian(WCFourCC::s_stored_byte_order) == in_right.GetAsSomeEndian(WCFourCC::s_stored_byte_order);
198 }
199
200 inline bool operator!=(const WCFourCC in_left, const WCFourCC in_right)
201 {
202         return ! operator==(in_left, in_right);
203 }
204
205
206 #define kDefaultFourCC WCFourCC::kDefaultFourCC_prv()
207
208 static const WCFourCC kZeroFourCC(0, wvNS::wvBO::compiler_byte_order);
209         
210 #endif //#if !defined(__WCFourCC_h__)
211
212
213