Make sure MSVC knows which version of 'floor()' we want
[ardour.git] / libs / appleutility / CoreAudio / PublicUtility / CAXException.h
1 /*
2      File: CAXException.h
3  Abstract: Part of CoreAudio Utility Classes
4   Version: 1.1
5
6  Disclaimer: IMPORTANT:  This Apple software is supplied to you by Apple
7  Inc. ("Apple") in consideration of your agreement to the following
8  terms, and your use, installation, modification or redistribution of
9  this Apple software constitutes acceptance of these terms.  If you do
10  not agree with these terms, please do not use, install, modify or
11  redistribute this Apple software.
12
13  In consideration of your agreement to abide by the following terms, and
14  subject to these terms, Apple grants you a personal, non-exclusive
15  license, under Apple's copyrights in this original Apple software (the
16  "Apple Software"), to use, reproduce, modify and redistribute the Apple
17  Software, with or without modifications, in source and/or binary forms;
18  provided that if you redistribute the Apple Software in its entirety and
19  without modifications, you must retain this notice and the following
20  text and disclaimers in all such redistributions of the Apple Software.
21  Neither the name, trademarks, service marks or logos of Apple Inc. may
22  be used to endorse or promote products derived from the Apple Software
23  without specific prior written permission from Apple.  Except as
24  expressly stated in this notice, no other rights or licenses, express or
25  implied, are granted by Apple herein, including but not limited to any
26  patent rights that may be infringed by your derivative works or by other
27  works in which the Apple Software may be incorporated.
28
29  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
30  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34
35  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42  POSSIBILITY OF SUCH DAMAGE.
43
44  Copyright (C) 2014 Apple Inc. All Rights Reserved.
45
46 */
47 #ifndef __CAXException_h__
48 #define __CAXException_h__
49
50 #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
51         #include <CoreFoundation/CoreFoundation.h>
52 #else
53         #include <ConditionalMacros.h>
54         #include <CoreFoundation.h>
55 #endif
56 #include "CADebugMacros.h"
57 #include <ctype.h>
58 //#include <stdio.h>
59 #include <string.h>
60
61
62 class CAX4CCString {
63 public:
64         CAX4CCString(OSStatus error) {
65                 // see if it appears to be a 4-char-code
66                 UInt32 beErr = CFSwapInt32HostToBig(error);
67                 char *str = mStr;
68                 memcpy(str + 1, &beErr, 4);
69                 if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
70                         str[0] = str[5] = '\'';
71                         str[6] = '\0';
72                 } else if (error > -200000 && error < 200000)
73                         // no, format it as an integer
74                         snprintf(str, sizeof(mStr), "%d", (int)error);
75                 else
76                         snprintf(str, sizeof(mStr), "0x%x", (int)error);
77         }
78         const char *get() const { return mStr; }
79         operator const char *() const { return mStr; }
80 private:
81         char mStr[16];
82 };
83
84 class CAX4CCStringNoQuote {
85 public:
86         CAX4CCStringNoQuote(OSStatus error) {
87                 // see if it appears to be a 4-char-code
88                 UInt32 beErr = CFSwapInt32HostToBig(error);
89                 char *str = mStr;
90                 memcpy(str, &beErr, 4);
91                 if (isprint(str[0]) && isprint(str[1]) && isprint(str[2]) && isprint(str[3])) {
92                         str[4] = '\0';
93                 } else if (error > -200000 && error < 200000)
94                         // no, format it as an integer
95                         snprintf(str, sizeof(mStr), "%d", (int)error);
96                 else
97                         snprintf(str, sizeof(mStr), "0x%x", (int)error);
98         }
99         const char *get() const { return mStr; }
100         operator const char *() const { return mStr; }
101 private:
102         char mStr[16];
103 };
104
105
106 // An extended exception class that includes the name of the failed operation
107 class CAXException {
108 public:
109         CAXException(const char *operation, OSStatus err) :
110                 mError(err)
111                 {
112                         if (operation == NULL)
113                                 mOperation[0] = '\0';
114                         else if (strlen(operation) >= sizeof(mOperation)) {
115                                 memcpy(mOperation, operation, sizeof(mOperation) - 1);
116                                 mOperation[sizeof(mOperation) - 1] = '\0';
117                         } else
118
119                         strlcpy(mOperation, operation, sizeof(mOperation));
120                 }
121
122         char *FormatError(char *str, size_t strsize) const
123         {
124                 return FormatError(str, strsize, mError);
125         }
126
127         char                            mOperation[256];
128         const OSStatus          mError;
129
130         // -------------------------------------------------
131
132         typedef void (*WarningHandler)(const char *msg, OSStatus err);
133
134         static char *FormatError(char *str, size_t strsize, OSStatus error)
135         {
136                 strlcpy(str, CAX4CCString(error), strsize);
137                 return str;
138         }
139
140         static void Warning(const char *s, OSStatus error)
141         {
142                 if (sWarningHandler)
143                         (*sWarningHandler)(s, error);
144         }
145
146         static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; }
147 private:
148         static WarningHandler   sWarningHandler;
149 };
150
151 #if     DEBUG || CoreAudio_Debug
152         #define XThrowIfError(error, operation)                                                                         \
153                 do {                                                                                                                                    \
154                         OSStatus __err = error;                                                                                         \
155                         if (__err) {                                                                                                            \
156                                 DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
157                                 __THROW_STOP;                                                                                                                   \
158                                 throw CAXException(operation, __err);                                                   \
159                         }                                                                                                                                       \
160                 } while (0)
161
162         #define XThrowIf(condition, error, operation)                                                           \
163                 do {                                                                                                                                    \
164                         if (condition) {                                                                                                        \
165                                 OSStatus __err = error;                                                                                 \
166                                 DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
167                                 __THROW_STOP;                                                                                                                   \
168                                 throw CAXException(operation, __err);                                                   \
169                         }                                                                                                                                       \
170                 } while (0)
171
172         #define XRequireNoError(error, label)                                                                           \
173                 do {                                                                                                                                    \
174                         OSStatus __err = error;                                                                                         \
175                         if (__err) {                                                                                                            \
176                                 DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
177                                 STOP;                                                                                                                   \
178                                 goto label;                                                                                                             \
179                         }                                                                                                                                       \
180                 } while (0)
181
182         #define XAssert(assertion)                                                                                                      \
183                 do {                                                                                                                                    \
184                         if (!(assertion)) {                                                                                                     \
185                                 DebugMessageN3("%s:%d: error: failed assertion: %s", __FILE__, __LINE__, #assertion);           \
186                                 __ASSERT_STOP;                                                                                                                  \
187                         }                                                                                                                                       \
188                 } while (0)
189
190         #define XAssertNoError(error)                                                                                           \
191                 do {                                                                                                                                    \
192                         OSStatus __err = error;                                                                                         \
193                         if (__err) {                                                                                                            \
194                                 DebugMessageN4("%s:%d: error %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
195                                 STOP;                                                                                                                   \
196                         }                                                                                                                                       \
197                 } while (0)
198
199         #define ca_require_noerr(errorCode, exceptionLabel)                                                     \
200                 do                                                                                                                                              \
201                 {                                                                                                                                               \
202                         int evalOnceErrorCode = (errorCode);                                                            \
203                         if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                                      \
204                         {                                                                                                                                       \
205                                 DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d",   \
206                                         #errorCode,     evalOnceErrorCode,                                                              \
207                                         #exceptionLabel,                                                                                        \
208                                         __FILE__,                                                                                                       \
209                                         __LINE__);                                                                                                      \
210                                 goto exceptionLabel;                                                                                    \
211                         }                                                                                                                                       \
212                 } while ( 0 )
213
214         #define ca_verify_noerr(errorCode)                                                                                      \
215                 do                                                                                                                                              \
216                 {                                                                                                                                               \
217                         int evalOnceErrorCode = (errorCode);                                                            \
218                         if ( __builtin_expect(0 != evalOnceErrorCode, 0) )                                      \
219                         {                                                                                                                                       \
220                                 DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d",                               \
221                                         #errorCode,     evalOnceErrorCode,                                                              \
222                                         __FILE__,                                                                                                       \
223                                         __LINE__);                                                                                                      \
224                         }                                                                                                                                       \
225                 } while ( 0 )
226
227         #define ca_debug_string(message)                                                                                        \
228                 do                                                                                                                                              \
229                 {                                                                                                                                               \
230                         DebugMessageN3("ca_debug_string: %s %s:%d",                                                     \
231                                 message,                                                                                                                \
232                                 __FILE__,                                                                                                               \
233                                 __LINE__);                                                                                                              \
234                 } while ( 0 )
235
236
237         #define ca_verify(assertion)                                                                                            \
238                 do                                                                                                                                              \
239                 {                                                                                                                                               \
240                         if ( __builtin_expect(!(assertion), 0) )                                                        \
241                         {                                                                                                                                       \
242                                 DebugMessageN3("ca_verify: %s %s:%d",                                                   \
243                                         #assertion,                                                                                                     \
244                                         __FILE__,                                                                                                       \
245                                         __LINE__);                                                                                                      \
246                         }                                                                                                                                       \
247                 } while ( 0 )
248
249         #define ca_require(assertion, exceptionLabel)                                                           \
250                 do                                                                                                                                              \
251                 {                                                                                                                                               \
252                         if ( __builtin_expect(!(assertion), 0) )                                                        \
253                         {                                                                                                                                       \
254                                 DebugMessageN4("ca_require: %s %s %s:%d",                                               \
255                                         #assertion,                                                                                                     \
256                                         #exceptionLabel,                                                                                        \
257                                         __FILE__,                                                                                                       \
258                                         __LINE__);                                                                                                      \
259                                 goto exceptionLabel;                                                                                    \
260                         }                                                                                                                                       \
261                 } while ( 0 )
262
263    #define ca_check(assertion)                                                                                                  \
264       do                                                                                                                                                \
265       {                                                                                                                                                 \
266           if ( __builtin_expect(!(assertion), 0) )                                                              \
267           {                                                                                                                                             \
268               DebugMessageN3("ca_check: %s %s:%d",                                                      \
269                   #assertion,                                                                                                   \
270                   __FILE__,                                                                                                             \
271                   __LINE__);                                                                                                    \
272           }                                                                                                                                             \
273       } while ( 0 )
274
275 #else
276         #define XThrowIfError(error, operation)                                                                         \
277                 do {                                                                                                                                    \
278                         OSStatus __err = error;                                                                                         \
279                         if (__err) {                                                                                                            \
280                                 throw CAXException(operation, __err);                                                   \
281                         }                                                                                                                                       \
282                 } while (0)
283
284         #define XThrowIf(condition, error, operation)                                                           \
285                 do {                                                                                                                                    \
286                         if (condition) {                                                                                                        \
287                                 OSStatus __err = error;                                                                                 \
288                                 throw CAXException(operation, __err);                                                   \
289                         }                                                                                                                                       \
290                 } while (0)
291
292         #define XRequireNoError(error, label)                                                                           \
293                 do {                                                                                                                                    \
294                         OSStatus __err = error;                                                                                         \
295                         if (__err) {                                                                                                            \
296                                 goto label;                                                                                                             \
297                         }                                                                                                                                       \
298                 } while (0)
299
300         #define XAssert(assertion)                                                                                                      \
301                 do {                                                                                                                                    \
302                         if (!(assertion)) {                                                                                                     \
303                         }                                                                                                                                       \
304                 } while (0)
305
306         #define XAssertNoError(error)                                                                                           \
307                 do {                                                                                                                                    \
308                         /*OSStatus __err =*/ error;                                                                                     \
309                 } while (0)
310
311         #define ca_require_noerr(errorCode, exceptionLabel)                                                     \
312                 do                                                                                                                                              \
313                 {                                                                                                                                               \
314                         if ( __builtin_expect(0 != (errorCode), 0) )                                            \
315                         {                                                                                                                                       \
316                                 goto exceptionLabel;                                                                                    \
317                         }                                                                                                                                       \
318                 } while ( 0 )
319
320         #define ca_verify_noerr(errorCode)                                                                                      \
321                 do                                                                                                                                              \
322                 {                                                                                                                                               \
323                         if ( 0 != (errorCode) )                                                                                         \
324                         {                                                                                                                                       \
325                         }                                                                                                                                       \
326                 } while ( 0 )
327
328         #define ca_debug_string(message)
329
330         #define ca_verify(assertion)                                                                                            \
331                 do                                                                                                                                              \
332                 {                                                                                                                                               \
333                         if ( !(assertion) )                                                                                                     \
334                         {                                                                                                                                       \
335                         }                                                                                                                                       \
336                 } while ( 0 )
337
338         #define ca_require(assertion, exceptionLabel)                                                           \
339                 do                                                                                                                                              \
340                 {                                                                                                                                               \
341                         if ( __builtin_expect(!(assertion), 0) )                                                        \
342                         {                                                                                                                                       \
343                                 goto exceptionLabel;                                                                                    \
344                         }                                                                                                                                       \
345                 } while ( 0 )
346
347    #define ca_check(assertion)                                                                                                  \
348                 do                                                                                                                                              \
349                 {                                                                                                                                               \
350                         if ( !(assertion) )                                                                                                     \
351                         {                                                                                                                                       \
352                         }                                                                                                                                       \
353                 } while ( 0 )
354
355
356 #endif
357
358 #define XThrow(error, operation) XThrowIf(true, error, operation)
359 #define XThrowIfErr(error) XThrowIfError(error, #error)
360
361 #endif // __CAXException_h__