• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /* -*- Mode: C; tab-width: 4 -*-
2   *
3   * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4   *
5   * Licensed under the Apache License, Version 2.0 (the "License");
6   * you may not use this file except in compliance with the License.
7   * You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  //---------------------------------------------------------------------------------------------------------------------------
19  /*!	@header		CommonServices
20  
21  	Common Services for Mac OS X, Linux, Palm, VxWorks, Windows, and Windows CE.
22  */
23  
24  #ifndef	__COMMON_SERVICES__
25  #define	__COMMON_SERVICES__
26  
27  #ifdef	__cplusplus
28  	extern "C" {
29  #endif
30  
31  #if 0
32  #pragma mark == Target ==
33  #endif
34  
35  //===========================================================================================================================
36  //	 Target
37  //===========================================================================================================================
38  
39  // Macintosh
40  
41  #if( !defined( TARGET_OS_MAC ) )
42  	#if( ( macintosh || __MACH__ ) && !KERNEL )
43  		// ConditionalMacros.h in CoreServices will define this TARGET_* flag.
44  	#else
45  		#define	TARGET_OS_MAC			0
46  	#endif
47  #endif
48  
49  #if( !defined( TARGET_API_MAC_OSX_KERNEL ) )
50  	#if( __MACH__ && KERNEL )
51  		#define	TARGET_API_MAC_OSX_KERNEL		1
52  	#else
53  		#define	TARGET_API_MAC_OSX_KERNEL		0
54  	#endif
55  #endif
56  
57  // FreeBSD
58  
59  #if( !defined( TARGET_OS_FREEBSD ) )
60  	#if( defined( __FreeBSD__ ) )
61  		#define TARGET_OS_FREEBSD		1
62  	#else
63  		#define TARGET_OS_FREEBSD		0
64  	#endif
65  #endif
66  
67  // Linux
68  
69  #if( !defined( TARGET_OS_LINUX ) )
70  	#if( defined( __linux__ ) )
71  		#define	TARGET_OS_LINUX			1
72  	#else
73  		#define	TARGET_OS_LINUX			0
74  	#endif
75  #endif
76  
77  // Solaris
78  
79  #if( !defined( TARGET_OS_SOLARIS ) )
80  	#if( defined(solaris) || (defined(__SVR4) && defined(sun)) )
81  		#define	TARGET_OS_SOLARIS		1
82  	#else
83  		#define	TARGET_OS_SOLARIS		0
84  	#endif
85  #endif
86  
87  // Palm
88  
89  #if( !defined( TARGET_OS_PALM ) )
90  	#if( defined( __PALMOS_TRAPS__ ) || defined( __PALMOS_ARMLET__ ) )
91  		#define	TARGET_OS_PALM			1
92  	#else
93  		#define	TARGET_OS_PALM			0
94  	#endif
95  #endif
96  
97  // VxWorks
98  
99  #if( !defined( TARGET_OS_VXWORKS ) )
100  
101  	// No predefined macro for VxWorks so just assume VxWorks if nothing else is set.
102  
103  	#if( !macintosh && !__MACH__  && !defined( __FreeBSD__ ) && !defined( __linux__ ) && !defined ( __SVR4 ) && !defined ( __sun ) && !defined( __PALMOS_TRAPS__ ) && !defined( __PALMOS_ARMLET__ ) && !defined( _WIN32 ) )
104  		#define	TARGET_OS_VXWORKS		1
105  	#else
106  		#define	TARGET_OS_VXWORKS		0
107  	#endif
108  #endif
109  
110  // Windows
111  
112  #if( !defined( TARGET_OS_WIN32 ) )
113  	#if( macintosh || __MACH__ )
114  		// ConditionalMacros.h in CoreServices will define this TARGET_* flag.
115  	#else
116  		#if( defined( _WIN32 ) )
117  			#define	TARGET_OS_WIN32		1
118  		#else
119  			#define	TARGET_OS_WIN32		0
120  		#endif
121  	#endif
122  #endif
123  
124  // Windows CE
125  
126  #if( !defined( TARGET_OS_WINDOWS_CE ) )
127  	#if( defined( _WIN32_WCE ) )
128  		#define	TARGET_OS_WINDOWS_CE	1
129  	#else
130  		#define	TARGET_OS_WINDOWS_CE	0
131  	#endif
132  #endif
133  
134  #if 0
135  #pragma mark == Includes ==
136  #endif
137  
138  //===========================================================================================================================
139  //	 Includes
140  //===========================================================================================================================
141  
142  #if( !KERNEL )
143  	#if defined(WIN32) && !defined(_WSPIAPI_COUNTOF)
144  		#define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
145  	#endif
146  	#include	<stddef.h>
147  #endif
148  
149  #if( ( macintosh || __MACH__ ) && !KERNEL )
150  
151  	#if( defined( __MWERKS__ ) )
152  		#if( __option( c9x ) )
153  			#include	<stdbool.h>
154  		#endif
155  	#else
156  		#include	<stdbool.h>
157  	#endif
158  
159  	#include	<stdint.h>
160  
161  	#if( __MACH__ )
162  
163  		// Mac OS X
164  
165  		#include	<sys/types.h>
166  		#include	<netinet/in.h>
167  		#include	<arpa/inet.h>
168  		#include	<fcntl.h>
169  		#include	<pthread.h>
170  		#include	<sys/ioctl.h>
171  		#include	<sys/socket.h>
172  		#include	<unistd.h>
173  
174  	#else
175  
176  		// Classic Mac OS
177  
178  		#include	<ConditionalMacros.h>
179  		#include	<MacTypes.h>
180  
181  	#endif
182  
183  #elif( KERNEL )
184  
185  	// Mac OS X Kernel
186  
187  	#include	<stdint.h>
188  
189  	#include	<libkern/OSTypes.h>
190  	#include	<sys/types.h>
191  
192  #elif( TARGET_OS_FREEBSD )
193  
194  	// FreeBSD
195  	#include	<stdint.h>
196  	#include	<pthread.h>
197  	#include	<netinet/in.h>
198  	#include	<arpa/inet.h>
199  	#include	<sys/socket.h>
200  
201  #elif( TARGET_OS_LINUX )
202  
203  	// Linux
204  
205  	#include	<stdint.h>
206  	#include	<arpa/inet.h>
207  
208  #elif( TARGET_OS_SOLARIS )
209  
210  	// Solaris
211  
212  	#include	<stdint.h>
213  
214  	#include	<arpa/inet.h>
215  	#include	<arpa/nameser.h>
216  
217  	#if ( defined( BYTE_ORDER ) && defined( LITTLE_ENDIAN ) && ( BYTE_ORDER == LITTLE_ENDIAN ) )
218  		#define TARGET_RT_LITTLE_ENDIAN		1
219  	#endif
220  	#if ( defined( BYTE_ORDER ) && defined( BIG_ENDIAN ) && ( BYTE_ORDER == BIG_ENDIAN ) )
221  		#define TARGET_RT_BIG_ENDIAN		1
222  	#endif
223  
224  #elif( TARGET_OS_PALM )
225  
226  	// Palm (no special includes yet).
227  
228  #elif( TARGET_OS_VXWORKS )
229  
230  	// VxWorks
231  
232  	#include	"vxWorks.h"
233  
234  #elif( TARGET_OS_WIN32 )
235  
236  	// Windows
237  
238  	#if( !defined( WIN32_WINDOWS ) )
239  		#define	WIN32_WINDOWS		0x0401
240  	#endif
241  
242  	#if( !defined( _WIN32_WINDOWS ) )
243  		#define	_WIN32_WINDOWS		0x0401
244  	#endif
245  
246  	#if( !defined( WIN32_LEAN_AND_MEAN ) )
247  		#define	WIN32_LEAN_AND_MEAN			// Needed to avoid redefinitions by Windows interfaces.
248  	#endif
249  
250  	#if( defined( __MWERKS__ ) )
251  
252  		#if( __option( c9x ) )
253  			#include	<stdbool.h>
254  		#endif
255  
256  		#include	<stdint.h>
257  
258  	#elif( defined( _MSC_VER ) )
259  
260  		#pragma warning( disable:4127 )		// Disable "conditional expression is constant" warning for debug macros.
261  		#pragma warning( disable:4706 )		// Disable "assignment within conditional expression" for Microsoft headers.
262  
263  	#endif
264  
265  	#include	<windows.h>
266  	#include	<winsock2.h>
267  	#include	<Ws2tcpip.h>
268  
269  	#if( defined( _MSC_VER ) )
270  		#pragma warning( default:4706 )
271  	#endif
272  
273  #else
274  	#error unknown OS - update this file to support your OS
275  #endif
276  
277  #if( !defined( TARGET_BUILD_MAIN ) )
278  	#if( !TARGET_OS_VXWORKS )
279  		#define	TARGET_BUILD_MAIN		1
280  	#endif
281  #endif
282  
283  #if( __GNUC__ || !TARGET_OS_VXWORKS )
284  	#define	TARGET_LANGUAGE_C_LIKE		1
285  #else
286  	#define	TARGET_LANGUAGE_C_LIKE		0
287  #endif
288  
289  #if 0
290  #pragma mark == CPU ==
291  #endif
292  
293  //===========================================================================================================================
294  //	CPU
295  //===========================================================================================================================
296  
297  // PowerPC
298  
299  #if( !defined( TARGET_CPU_PPC ) )
300  	#if( defined( __ppc__ ) || defined( __PPC__ ) || defined( powerpc ) || defined( ppc ) || defined( _M_MPPC ) )
301  		#define	TARGET_CPU_PPC				1
302  	#else
303  		#define	TARGET_CPU_PPC				0
304  	#endif
305  #endif
306  
307  // x86
308  
309  #if( !defined( TARGET_CPU_X86 ) )
310  	#if( __INTEL__ || defined( __i386__ ) || defined( i386 ) || defined( intel ) || defined( _M_IX86 ) )
311  		#define	TARGET_CPU_X86				1
312  	#else
313  		#define	TARGET_CPU_X86				0
314  	#endif
315  #endif
316  
317  // MIPS
318  
319  #if( !defined( TARGET_CPU_MIPS ) )
320  	#if( __MIPS__ || defined( MIPS32 ) || defined( R3000 ) || defined( R4000 ) || defined( R4650 ) || defined( _M_MRX000 ) )
321  		#define	TARGET_CPU_MIPS				1
322  	#else
323  		#define	TARGET_CPU_MIPS				0
324  	#endif
325  #endif
326  
327  #if( !defined( TARGET_CPU_PPC ) && !defined( TARGET_CPU_X86 ) && !defined( TARGET_CPU_MIPS ) )
328  	#error unknown CPU - update this file to support your CPU
329  #endif
330  
331  #if 0
332  #pragma mark == Byte Order ==
333  #endif
334  
335  //===========================================================================================================================
336  //	Byte Order
337  //===========================================================================================================================
338  
339  // TARGET_RT_LITTLE_ENDIAN
340  
341  #if( !defined( TARGET_RT_LITTLE_ENDIAN ) )
342  	#if( MIPSEL || IL_LITTLE_ENDIAN || defined( __LITTLE_ENDIAN__ ) 										|| \
343  		 ( defined(   BYTE_ORDER ) && defined(   LITTLE_ENDIAN ) && (   BYTE_ORDER ==   LITTLE_ENDIAN ) )	|| \
344  		 ( defined(  _BYTE_ORDER ) && defined(  _LITTLE_ENDIAN ) && (  _BYTE_ORDER ==  _LITTLE_ENDIAN ) )	|| \
345  		 ( defined( __BYTE_ORDER ) && defined( __LITTLE_ENDIAN ) && ( __BYTE_ORDER == __LITTLE_ENDIAN ) )	|| \
346  		 TARGET_CPU_X86 || ( defined( TARGET_RT_BIG_ENDIAN ) && !TARGET_RT_BIG_ENDIAN ) )
347  		#define	TARGET_RT_LITTLE_ENDIAN		1
348  	#else
349  		#define	TARGET_RT_LITTLE_ENDIAN		0
350  	#endif
351  #endif
352  
353  // TARGET_RT_BIG_ENDIAN
354  
355  #if( !defined( TARGET_RT_BIG_ENDIAN ) )
356  	#if( MIPSEB || IL_BIG_ENDIAN || defined( __BIG_ENDIAN__ ) 										|| \
357  		 ( defined(   BYTE_ORDER ) && defined(   BIG_ENDIAN ) && (   BYTE_ORDER ==   BIG_ENDIAN ) )	|| \
358  		 ( defined(  _BYTE_ORDER ) && defined(  _BIG_ENDIAN ) && (  _BYTE_ORDER ==  _BIG_ENDIAN ) )	|| \
359  		 ( defined( __BYTE_ORDER ) && defined( __BIG_ENDIAN ) && ( __BYTE_ORDER == __BIG_ENDIAN ) )	|| \
360  		( defined( TARGET_RT_LITTLE_ENDIAN ) && !TARGET_RT_LITTLE_ENDIAN ) )
361  		#define	TARGET_RT_BIG_ENDIAN		1
362  	#else
363  		#define	TARGET_RT_BIG_ENDIAN		0
364  	#endif
365  #endif
366  
367  #if( defined( TARGET_RT_LITTLE_ENDIAN ) && !defined( TARGET_RT_BIG_ENDIAN ) )
368  	#if( TARGET_RT_LITTLE_ENDIAN )
369  		#define	TARGET_RT_BIG_ENDIAN		0
370  	#else
371  		#define	TARGET_RT_BIG_ENDIAN		1
372  	#endif
373  #endif
374  
375  #if( defined( TARGET_RT_BIG_ENDIAN ) && !defined( TARGET_RT_LITTLE_ENDIAN ) )
376  	#if( TARGET_RT_BIG_ENDIAN )
377  		#define	TARGET_RT_LITTLE_ENDIAN		0
378  	#else
379  		#define	TARGET_RT_LITTLE_ENDIAN		1
380  	#endif
381  #endif
382  
383  #if( !defined( TARGET_RT_LITTLE_ENDIAN ) || !defined( TARGET_RT_BIG_ENDIAN ) )
384  	#error unknown byte order - update this file to support your byte order
385  #endif
386  
387  // TARGET_RT_BYTE_ORDER
388  
389  #if( !defined( TARGET_RT_BYTE_ORDER_BIG_ENDIAN ) )
390  	#define	TARGET_RT_BYTE_ORDER_BIG_ENDIAN			1234
391  #endif
392  
393  #if( !defined( TARGET_RT_BYTE_ORDER_LITTLE_ENDIAN ) )
394  	#define	TARGET_RT_BYTE_ORDER_LITTLE_ENDIAN		4321
395  #endif
396  
397  #if( !defined( TARGET_RT_BYTE_ORDER ) )
398  	#if( TARGET_RT_LITTLE_ENDIAN )
399  		#define	TARGET_RT_BYTE_ORDER				TARGET_RT_BYTE_ORDER_LITTLE_ENDIAN
400  	#else
401  		#define	TARGET_RT_BYTE_ORDER				TARGET_RT_BYTE_ORDER_BIG_ENDIAN
402  	#endif
403  #endif
404  
405  #if 0
406  #pragma mark == Constants ==
407  #endif
408  
409  //===========================================================================================================================
410  //	Constants
411  //===========================================================================================================================
412  
413  #if( !TARGET_OS_MAC )
414  	#define CR		'\r'
415  #endif
416  
417  #define LF			'\n'
418  #define	CRSTR		"\r"
419  #define	LFSTR		"\n"
420  #define CRLF		"\r\n"
421  #define CRCR 		"\r\r"
422  
423  #if 0
424  #pragma mark == Compatibility ==
425  #endif
426  
427  //===========================================================================================================================
428  //	Compatibility
429  //===========================================================================================================================
430  
431  // Macros to allow the same code to work on Windows and other sockets API-compatible platforms.
432  
433  #if( TARGET_OS_WIN32 )
434  	#define	close_compat( X )		closesocket( X )
435  	#define	errno_compat()			(int) GetLastError()
436  	#define	set_errno_compat( X )	SetLastError( X )
437  	#define	EWOULDBLOCK_compat		WSAEWOULDBLOCK
438  	#define	ETIMEDOUT_compat		WSAETIMEDOUT
439  	#define	ENOTCONN_compat			WSAENOTCONN
440  	#define	IsValidSocket( X )		( ( X ) != INVALID_SOCKET )
441  	#define	kInvalidSocketRef		INVALID_SOCKET
442  	#if( TARGET_LANGUAGE_C_LIKE )
443  		typedef SOCKET				SocketRef;
444  	#endif
445  #else
446  	#define	close_compat( X )		close( X )
447  	#define	errno_compat()			errno
448  	#define	set_errno_compat( X )	do { errno = ( X ); } while( 0 )
449  	#define	EWOULDBLOCK_compat		EWOULDBLOCK
450  	#define	ETIMEDOUT_compat		ETIMEDOUT
451  	#define	ENOTCONN_compat			ENOTCONN
452  	#define	IsValidSocket( X )		( ( X ) >= 0 )
453  	#define	kInvalidSocketRef		-1
454  	#if( TARGET_LANGUAGE_C_LIKE )
455  		typedef int					SocketRef;
456  	#endif
457  #endif
458  
459  // socklen_t is not defined on the following platforms so emulate it if not defined:
460  //
461  // - Pre-Panther Mac OS X. Panther defines SO_NOADDRERR so trigger off that.
462  // - Windows SDK prior to 2003. 2003+ SDK's define EAI_AGAIN so trigger off that.
463  // - VxWorks
464  
465  #if( TARGET_LANGUAGE_C_LIKE )
466  	#if( ( TARGET_OS_MAC && !defined( SO_NOADDRERR ) ) || ( TARGET_OS_WIN32 && !defined( EAI_AGAIN ) ) || TARGET_OS_VXWORKS )
467  		typedef int						socklen_t;
468  	#endif
469  #endif
470  
471  // ssize_t is not defined on the following platforms so emulate it if not defined:
472  //
473  // - Mac OS X when not building with BSD headers
474  // - Windows
475  
476  #if( TARGET_LANGUAGE_C_LIKE )
477  	#if( !defined(_SSIZE_T) && ( TARGET_OS_WIN32 || !defined( _BSD_SSIZE_T_DEFINED_ ) ) && !TARGET_OS_FREEBSD && !TARGET_OS_LINUX && !TARGET_OS_VXWORKS && !TARGET_OS_MAC)
478  		typedef int						ssize_t;
479  	#endif
480  #endif
481  
482  // sockaddr_storage is not supported on non-IPv6 machines so alias it to an IPv4-compatible structure.
483  
484  #if( TARGET_LANGUAGE_C_LIKE )
485  	#if( !defined( AF_INET6 ) )
486  		#define	sockaddr_storage		sockaddr_in
487  		#define	ss_family				sin_family
488  	#endif
489  #endif
490  
491  //---------------------------------------------------------------------------------------------------------------------------
492  /*!	@defined	SOCKADDR_IS_IP_LOOPBACK
493  
494  	@abstract	Determines if a sockaddr is an IPv4 or IPv6 loopback address (if IPv6 is supported).
495  */
496  
497  #if( defined( AF_INET6 ) )
498  	#define	SOCKADDR_IS_IP_LOOPBACK( SA )															\
499  		( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET )   							\
500  		? ( ( (const struct sockaddr_in *)( SA ) )->sin_addr.s_addr == htonl( INADDR_LOOPBACK ) )	\
501  		: ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET6 ) 							\
502  			? IN6_IS_ADDR_LOOPBACK( &( (const struct sockaddr_in6 *)( SA ) )->sin6_addr ) 			\
503  			: 0
504  #else
505  	#define	SOCKADDR_IS_IP_LOOPBACK( SA )															\
506  		( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET )  								\
507  		? ( ( (const struct sockaddr_in *)( SA ) )->sin_addr.s_addr == htonl( INADDR_LOOPBACK ) ) 	\
508  		: 0
509  #endif
510  
511  //---------------------------------------------------------------------------------------------------------------------------
512  /*!	@defined	SOCKADDR_IS_IP_LINK_LOCAL
513  
514  	@abstract	Determines if a sockaddr is an IPv4 or IPv6 link-local address (if IPv6 is supported).
515  */
516  
517  #if( defined( AF_INET6 ) )
518  	#define	SOCKADDR_IS_IP_LINK_LOCAL( SA )																\
519  		( ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET )   								\
520  		  ? ( ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 0 ] == 169 ) && 	\
521  			  ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 1 ] == 254 ) )	\
522  		  : IN6_IS_ADDR_LOOPBACK( &( (const struct sockaddr_in6 *)( SA ) )->sin6_addr ) )
523  #else
524  	#define	SOCKADDR_IS_IP_LINK_LOCAL( SA )																\
525  		( ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET )   								\
526  		  ? ( ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 0 ] == 169 ) && 	\
527  			  ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 1 ] == 254 ) )	\
528  		  : 0 )
529  #endif
530  
531  // _beginthreadex and _endthreadex are not supported on Windows CE 2.1 or later (the C runtime issues with leaking
532  // resources have apparently been resolved and they seem to have just ripped out support for the API) so map it to
533  // CreateThread on Windows CE.
534  
535  #if( TARGET_OS_WINDOWS_CE )
536  	#define	_beginthreadex_compat( SECURITY_PTR, STACK_SIZE, START_ADDRESS, ARG_LIST, FLAGS, THREAD_ID_PTR )			\
537  		(uintptr_t) CreateThread( SECURITY_PTR, STACK_SIZE, (LPTHREAD_START_ROUTINE) START_ADDRESS, ARG_LIST, FLAGS, 	\
538  					  (LPDWORD) THREAD_ID_PTR )
539  
540  	#define	_endthreadex_compat( RESULT )		ExitThread( (DWORD) RESULT )
541  #elif( TARGET_OS_WIN32 )
542  	#define	_beginthreadex_compat				_beginthreadex
543  	#define	_endthreadex_compat					_endthreadex
544  #endif
545  
546  // The C99 "inline" keyword is not supported by Microsoft compilers, but they do support __inline so map it when needed.
547  
548  #if( defined( _MSC_VER ) )
549  	#define	inline_compat		__inline
550  #else
551  	#define	inline_compat		inline
552  #endif
553  
554  // Calling conventions
555  
556  #if( !defined( CALLBACK_COMPAT ) )
557  	#if( TARGET_OS_WIN32 || TARGET_OS_WINDOWS_CE )
558  		#define	CALLBACK_COMPAT		CALLBACK
559  	#else
560  		#define	CALLBACK_COMPAT
561  	#endif
562  #endif
563  
564  #if 0
565  #pragma mark == Macros ==
566  #endif
567  
568  //---------------------------------------------------------------------------------------------------------------------------
569  /*!	@defined	kSizeCString
570  
571  	@abstract	A meta-value to pass to supported routines to indicate the size should be calculated with strlen.
572  */
573  
574  #define	kSizeCString		( (size_t) -1 )
575  
576  //---------------------------------------------------------------------------------------------------------------------------
577  /*!	@defined	sizeof_array
578  
579  	@abstract	Determines the number of elements in an array.
580  */
581  
582  #define	sizeof_array( X )		( sizeof( X ) / sizeof( X[ 0 ] ) )
583  
584  //---------------------------------------------------------------------------------------------------------------------------
585  /*!	@defined	sizeof_element
586  
587  	@abstract	Determines the size of an array element.
588  */
589  
590  #define	sizeof_element( X )		sizeof( X[ 0 ] )
591  
592  //---------------------------------------------------------------------------------------------------------------------------
593  /*!	@defined	sizeof_string
594  
595  	@abstract	Determines the size of a constant C string, excluding the null terminator.
596  */
597  
598  #define	sizeof_string( X )		( sizeof( ( X ) ) - 1 )
599  
600  //---------------------------------------------------------------------------------------------------------------------------
601  /*!	@defined	sizeof_field
602  
603  	@abstract	Determines the size of a field of a type.
604  */
605  
606  #define	sizeof_field( TYPE, FIELD )		sizeof( ( ( (TYPE *) 0 )->FIELD ) )
607  
608  //---------------------------------------------------------------------------------------------------------------------------
609  /*!	@function	RoundUp
610  
611  	@abstract	Rounds X up to a multiple of Y.
612  */
613  
614  #define	RoundUp( X, Y )		( ( X ) + ( ( Y ) - ( ( X ) % ( Y ) ) ) )
615  
616  //---------------------------------------------------------------------------------------------------------------------------
617  /*!	@function	IsAligned
618  
619  	@abstract	Returns non-zero if X is aligned to a Y byte boundary and 0 if not. Y must be a power of 2.
620  */
621  
622  #define	IsAligned( X, Y )		( ( ( X ) & ( ( Y ) - 1 ) ) == 0 )
623  
624  //---------------------------------------------------------------------------------------------------------------------------
625  /*!	@function	IsFieldAligned
626  
627  	@abstract	Returns non-zero if FIELD of type TYPE is aligned to a Y byte boundary and 0 if not. Y must be a power of 2.
628  */
629  
630  #define	IsFieldAligned( X, TYPE, FIELD, Y )		IsAligned( ( (uintptr_t)( X ) ) + offsetof( TYPE, FIELD ), ( Y ) )
631  
632  //---------------------------------------------------------------------------------------------------------------------------
633  /*!	@function	AlignDown
634  
635  	@abstract	Aligns X down to a Y byte boundary. Y must be a power of 2.
636  */
637  
638  #define	AlignDown( X, Y )		( ( X ) & ~( ( Y ) - 1 ) )
639  
640  //---------------------------------------------------------------------------------------------------------------------------
641  /*!	@function	AlignUp
642  
643  	@abstract	Aligns X up to a Y byte boundary. Y must be a power of 2.
644  */
645  
646  #define	AlignUp( X, Y )		( ( ( X ) + ( ( Y ) - 1 ) ) & ~( ( Y ) - 1 ) )
647  
648  //---------------------------------------------------------------------------------------------------------------------------
649  /*!	@function	Min
650  
651  	@abstract	Returns the lesser of X and Y.
652  */
653  
654  #if( !defined( Min ) )
655  	#define	Min( X, Y )		( ( ( X ) < ( Y ) ) ? ( X ) : ( Y ) )
656  #endif
657  
658  //---------------------------------------------------------------------------------------------------------------------------
659  /*!	@function	Max
660  
661  	@abstract	Returns the greater of X and Y.
662  */
663  
664  #if( !defined( Max ) )
665  	#define	Max( X, Y )		( ( ( X ) > ( Y ) ) ? ( X ) : ( Y ) )
666  #endif
667  
668  //---------------------------------------------------------------------------------------------------------------------------
669  /*!	@function	InsertBits
670  
671  	@abstract	Inserts BITS (both 0 and 1 bits) into X, controlled by MASK and SHIFT, and returns the result.
672  
673  	@discussion
674  
675  	MASK is the bitmask of the bits in the final position.
676  	SHIFT is the number of bits to shift left for 1 to reach the first bit position of MASK.
677  
678  	For example, if you wanted to insert 0x3 into the leftmost 4 bits of a 32-bit value:
679  
680  	InsertBits( 0, 0x3, 0xF0000000U, 28 ) == 0x30000000
681  */
682  
683  #define	InsertBits( X, BITS, MASK, SHIFT )		( ( ( X ) & ~( MASK ) ) | ( ( ( BITS ) << ( SHIFT ) ) & ( MASK ) ) )
684  
685  //---------------------------------------------------------------------------------------------------------------------------
686  /*!	@function	ExtractBits
687  
688  	@abstract	Extracts bits from X, controlled by MASK and SHIFT, and returns the result.
689  
690  	@discussion
691  
692  	MASK is the bitmask of the bits in the final position.
693  	SHIFT is the number of bits to shift right to right justify MASK.
694  
695  	For example, if you had a 32-bit value (e.g. 0x30000000) wanted the left-most 4 bits (e.g. 3 in this example):
696  
697  	ExtractBits( 0x30000000U, 0xF0000000U, 28 ) == 0x3
698  */
699  
700  #define	ExtractBits( X, MASK, SHIFT )			( ( ( X ) >> ( SHIFT ) ) & ( ( MASK ) >> ( SHIFT ) ) )
701  
702  //---------------------------------------------------------------------------------------------------------------------------
703  /*!	@function	Stringify
704  
705  	@abstract	Stringify's an expression.
706  
707  	@discussion
708  
709  	Stringify macros to process raw text passed via -D options to C string constants. The double-wrapping is necessary
710  	because the C preprocessor doesn't perform its normal argument expansion pre-scan with stringified macros so the
711  	-D macro needs to be expanded once via the wrapper macro then stringified so the raw text is stringified. Otherwise,
712  	the replacement value would be used instead of the symbolic name (only for preprocessor symbols like #defines).
713  
714  	For example:
715  
716  		#define	kMyConstant		1
717  
718  		printf( "%s", Stringify( kMyConstant ) );			// Prints "kMyConstant"
719  		printf( "%s", StringifyExpansion( kMyConstant ) );	// Prints "1"
720  
721  	Non-preprocessor symbols do not have this issue. For example:
722  
723  		enum
724  		{
725  			kMyConstant = 1
726  		};
727  
728  		printf( "%s", Stringify( kMyConstant ) );			// Prints "kMyConstant"
729  		printf( "%s", StringifyExpansion( kMyConstant ) );	// Prints "kMyConstant"
730  
731  	See <http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html> for more info on C preprocessor pre-scanning.
732  */
733  
734  #define	Stringify( X )				# X
735  #define	StringifyExpansion( X )		Stringify( X )
736  
737  #if 0
738  #pragma mark == Types ==
739  #endif
740  
741  #if( TARGET_LANGUAGE_C_LIKE )
742  //===========================================================================================================================
743  //	 Standard Types
744  //===========================================================================================================================
745  
746  #if( !defined( INT8_MIN ) )
747  
748  	#define INT8_MIN					SCHAR_MIN
749  
750  	#if( defined( _MSC_VER ) )
751  
752  		// C99 stdint.h not supported in VC++/VS.NET yet.
753  
754  		typedef INT8					int8_t;
755  		typedef UINT8					uint8_t;
756  		typedef INT16					int16_t;
757  		typedef UINT16					uint16_t;
758  		typedef INT32					int32_t;
759  		typedef UINT32					uint32_t;
760  		typedef __int64					int64_t;
761  		typedef unsigned __int64		uint64_t;
762  
763  	#elif( TARGET_OS_VXWORKS && ( TORNADO_VERSION < 220 ) )
764  		typedef long long				int64_t;
765  		typedef unsigned long long		uint64_t;
766  	#endif
767  
768  	typedef int8_t						int_least8_t;
769  	typedef int16_t						int_least16_t;
770  	typedef int32_t						int_least32_t;
771  	typedef int64_t						int_least64_t;
772  
773  	typedef uint8_t						uint_least8_t;
774  	typedef uint16_t					uint_least16_t;
775  	typedef uint32_t					uint_least32_t;
776  	typedef uint64_t					uint_least64_t;
777  
778  	typedef int8_t						int_fast8_t;
779  	typedef int16_t						int_fast16_t;
780  	typedef int32_t						int_fast32_t;
781  	typedef int64_t						int_fast64_t;
782  
783  	typedef uint8_t						uint_fast8_t;
784  	typedef uint16_t					uint_fast16_t;
785  	typedef uint32_t					uint_fast32_t;
786  	typedef uint64_t					uint_fast64_t;
787  
788  	#if( !defined( _MSC_VER ) || TARGET_OS_WINDOWS_CE )
789  		typedef long int				intptr_t;
790  		typedef unsigned long int		uintptr_t;
791  	#endif
792  
793  #endif
794  
795  // Macros for minimum-width integer constants
796  
797  #if( !defined( INT8_C ) )
798  	#define INT8_C( value )			value
799  #endif
800  
801  #if( !defined( INT16_C ) )
802  	#define INT16_C( value )		value
803  #endif
804  
805  #if( !defined( INT32_C ) )
806  	#define INT32_C( value )		value ## L
807  #endif
808  
809  #if( !defined( INT64_C ) )
810  	#if( defined( _MSC_VER ) )
811  		#define INT64_C( value )	value ## i64
812  	#else
813  		#define INT64_C( value )	value ## LL
814  	#endif
815  #endif
816  
817  #if( !defined( UINT8_C ) )
818  	#define UINT8_C( value )		value ## U
819  #endif
820  
821  #if( !defined( UINT16_C ) )
822  	#define UINT16_C( value )		value ## U
823  #endif
824  
825  #if( !defined( UINT32_C ) )
826  	#define UINT32_C( value )		value ## UL
827  #endif
828  
829  #if( !defined( UINT64_C ) )
830  	#if( defined( _MSC_VER ) )
831  		#define UINT64_C( value )	value ## UI64
832  	#else
833  		#define UINT64_C( value )	value ## ULL
834  	#endif
835  #endif
836  
837  #if 0
838  #pragma mark == bool ==
839  #endif
840  
841  //===========================================================================================================================
842  //	 Boolean Constants and Types
843  //===========================================================================================================================
844  
845  // C++ defines bool, true, and false. Metrowerks allows this to be controlled by the "bool" option though.
846  // C99 defines __bool_true_false_are_defined when bool, true, and false are defined.
847  // MacTypes.h defines true and false (Mac builds only).
848  //
849  // Note: The Metrowerks has to be in its own block because Microsoft Visual Studio .NET does not completely
850  // short-circuit and gets confused by the option( bool ) portion of the conditional.
851  
852  #if( defined( __MWERKS__ ) )
853  
854  	// Note: The following test is done on separate lines because CodeWarrior doesn't like it all on one line.
855  
856  	#if( !__bool_true_false_are_defined && ( !defined( __cplusplus ) || !__option( bool ) ) )
857  		#define	COMMON_SERVICES_NEEDS_BOOL		1
858  	#else
859  		#define	COMMON_SERVICES_NEEDS_BOOL		0
860  	#endif
861  
862  	// Workaround when building with CodeWarrior, but using the Apple stdbool.h header, which uses _Bool.
863  
864  	#if( __bool_true_false_are_defined && !defined( __cplusplus ) && !__option( c9x ) )
865  		#define _Bool	int
866  	#endif
867  
868  	// Workaround when building with CodeWarrior for C++ with bool disabled and using the Apple stdbool.h header,
869  	// which defines true and false to map to C++ true and false (which are not enabled). Serenity Now!
870  
871  	#if( __bool_true_false_are_defined && defined( __cplusplus ) && !__option( bool ) )
872  		#define	true	1
873  		#define	false	0
874  	#endif
875  #else
876  	#define	COMMON_SERVICES_NEEDS_BOOL			( !defined( __cplusplus ) && !__bool_true_false_are_defined )
877  #endif
878  
879  #if( COMMON_SERVICES_NEEDS_BOOL )
880  
881  	typedef int		bool;
882  
883  	#define	bool	bool
884  
885  	#if( !defined( __MACTYPES__ ) && !defined( true ) && !defined( false ) )
886  		#define true	1
887  		#define false	0
888  	#endif
889  
890  	#define __bool_true_false_are_defined		1
891  #endif
892  
893  // IOKit IOTypes.h typedef's bool if TYPE_BOOL is not defined so define it here to prevent redefinition by IOTypes.h.
894  
895  #if( TARGET_API_MAC_OSX_KERNEL )
896  	#define TYPE_BOOL		1
897  #endif
898  
899  //---------------------------------------------------------------------------------------------------------------------------
900  /*!	@typedef	CStr255
901  
902  	@abstract	255 character null-terminated (C-style) string.
903  */
904  
905  #if( TARGET_LANGUAGE_C_LIKE )
906  	typedef char	CStr255[ 256 ];
907  #endif
908  
909  #endif	// TARGET_LANGUAGE_C_LIKE
910  
911  //---------------------------------------------------------------------------------------------------------------------------
912  /*!	@defined	TYPE_LONGLONG_NATIVE
913  
914  	@abstract	Defines whether long long (or its equivalent) is natively supported or requires special libraries.
915  */
916  
917  #if( !defined( TYPE_LONGLONG_NATIVE ) )
918  	#if( !TARGET_OS_VXWORKS )
919  		#define	TYPE_LONGLONG_NATIVE			1
920  	#else
921  		#define	TYPE_LONGLONG_NATIVE			0
922  	#endif
923  #endif
924  
925  //---------------------------------------------------------------------------------------------------------------------------
926  /*!	@defined	long_long_compat
927  
928  	@abstract	Compatibility type to map to the closest thing to long long and unsigned long long.
929  
930  	@discussion
931  
932  	Neither long long nor unsigned long long are supported by Microsoft compilers, but they do support proprietary
933  	"__int64" and "unsigned __int64" equivalents so map to those types if the real long long is not supported.
934  */
935  
936  #if( TARGET_LANGUAGE_C_LIKE )
937  	#if( TARGET_OS_WIN32 )
938  		typedef __int64					long_long_compat;
939  		typedef unsigned __int64		unsigned_long_long_compat;
940  	#else
941  		typedef signed long long		long_long_compat;
942  		typedef unsigned long long		unsigned_long_long_compat;
943  	#endif
944  #endif
945  
946  #if 0
947  #pragma mark == Errors ==
948  #endif
949  
950  //---------------------------------------------------------------------------------------------------------------------------
951  /*!	@enum		OSStatus
952  
953  	@abstract	Status Code
954  
955  	@constant	kNoErr						    0 No error occurred.
956  	@constant	kInProgressErr				    1 Operation in progress.
957  	@constant	kUnknownErr					-6700 Unknown error occurred.
958  	@constant	kOptionErr					-6701 Option was not acceptable.
959  	@constant	kSelectorErr				-6702 Selector passed in is invalid or unknown.
960  	@constant	kExecutionStateErr			-6703 Call made in the wrong execution state (e.g. called at interrupt time).
961  	@constant	kPathErr					-6704 Path is invalid, too long, or otherwise not usable.
962  	@constant	kParamErr					-6705 Parameter is incorrect, missing, or not appropriate.
963  	@constant	kParamCountErr				-6706 Incorrect or unsupported number of parameters.
964  	@constant	kCommandErr					-6707 Command invalid or not supported.
965  	@constant	kIDErr						-6708 Unknown, invalid, or inappropriate identifier.
966  	@constant	kStateErr					-6709 Not in appropriate state to perform operation.
967  	@constant	kRangeErr					-6710 Index is out of range or not valid.
968  	@constant	kRequestErr					-6711 Request was improperly formed or not appropriate.
969  	@constant	kResponseErr				-6712 Response was incorrect or out of sequence.
970  	@constant	kChecksumErr				-6713 Checksum does not match the actual data.
971  	@constant	kNotHandledErr				-6714 Operation was not handled (or not handled completely).
972  	@constant	kVersionErr					-6715 Version is not incorrect or not compatibile.
973  	@constant	kSignatureErr				-6716 Signature did not match what was expected.
974  	@constant	kFormatErr					-6717 Unknown, invalid, or inappropriate file/data format.
975  	@constant	kNotInitializedErr			-6718 Action request before needed services were initialized.
976  	@constant	kAlreadyInitializedErr		-6719 Attempt made to initialize when already initialized.
977  	@constant	kNotInUseErr				-6720 Object not in use (e.g. cannot abort if not already in use).
978  	@constant	kInUseErr					-6721 Object is in use (e.g. cannot reuse active param blocks).
979  	@constant	kTimeoutErr					-6722 Timeout occurred.
980  	@constant	kCanceledErr				-6723 Operation canceled (successful cancel).
981  	@constant	kAlreadyCanceledErr			-6724 Operation has already been canceled.
982  	@constant	kCannotCancelErr			-6725 Operation could not be canceled (maybe already done or invalid).
983  	@constant	kDeletedErr					-6726 Object has already been deleted.
984  	@constant	kNotFoundErr				-6727 Something was not found.
985  	@constant	kNoMemoryErr				-6728 Not enough memory was available to perform the operation.
986  	@constant	kNoResourcesErr				-6729 Resources unavailable to perform the operation.
987  	@constant	kDuplicateErr				-6730 Duplicate found or something is a duplicate.
988  	@constant	kImmutableErr				-6731 Entity is not changeable.
989  	@constant	kUnsupportedDataErr			-6732 Data is unknown or not supported.
990  	@constant	kIntegrityErr				-6733 Data is corrupt.
991  	@constant	kIncompatibleErr			-6734 Data is not compatible or it is in an incompatible format.
992  	@constant	kUnsupportedErr				-6735 Feature or option is not supported.
993  	@constant	kUnexpectedErr				-6736 Error occurred that was not expected.
994  	@constant	kValueErr					-6737 Value is not appropriate.
995  	@constant	kNotReadableErr				-6738 Could not read or reading is not allowed.
996  	@constant	kNotWritableErr				-6739 Could not write or writing is not allowed.
997  	@constant	kBadReferenceErr			-6740 An invalid or inappropriate reference was specified.
998  	@constant	kFlagErr					-6741 An invalid, inappropriate, or unsupported flag was specified.
999  	@constant	kMalformedErr				-6742 Something was not formed correctly.
1000  	@constant	kSizeErr					-6743 Size was too big, too small, or not appropriate.
1001  	@constant	kNameErr					-6744 Name was not correct, allowed, or appropriate.
1002  	@constant	kNotReadyErr				-6745 Device or service is not ready.
1003  	@constant	kReadErr					-6746 Could not read.
1004  	@constant	kWriteErr					-6747 Could not write.
1005  	@constant	kMismatchErr				-6748 Something does not match.
1006  	@constant	kDateErr					-6749 Date is invalid or out-of-range.
1007  	@constant	kUnderrunErr				-6750 Less data than expected.
1008  	@constant	kOverrunErr					-6751 More data than expected.
1009  	@constant	kEndingErr					-6752 Connection, session, or something is ending.
1010  	@constant	kConnectionErr				-6753 Connection failed or could not be established.
1011  	@constant	kAuthenticationErr			-6754 Authentication failed or is not supported.
1012  	@constant	kOpenErr					-6755 Could not open file, pipe, device, etc.
1013  	@constant	kTypeErr					-6756 Incorrect or incompatible type (e.g. file, data, etc.).
1014  	@constant	kSkipErr					-6757 Items should be or was skipped.
1015  	@constant	kNoAckErr					-6758 No acknowledge.
1016  	@constant	kCollisionErr				-6759 Collision occurred (e.g. two on bus at same time).
1017  	@constant	kBackoffErr					-6760 Backoff in progress and operation intentionally failed.
1018  	@constant	kNoAddressAckErr			-6761 No acknowledge of address.
1019  	@constant	kBusyErr					-6762 Cannot perform because something is busy.
1020  	@constant	kNoSpaceErr					-6763 Not enough space to perform operation.
1021  */
1022  
1023  #if( TARGET_LANGUAGE_C_LIKE )
1024  	#if( !TARGET_OS_MAC && !TARGET_API_MAC_OSX_KERNEL )
1025  		typedef int32_t		OSStatus;
1026  	#endif
1027  #endif
1028  
1029  #define kNoErr						0
1030  #define kInProgressErr				1
1031  
1032  // Generic error codes are in the range -6700 to -6779.
1033  
1034  #define kGenericErrorBase			-6700	// Starting error code for all generic errors.
1035  
1036  #define kUnknownErr					-6700
1037  #define kOptionErr					-6701
1038  #define kSelectorErr				-6702
1039  #define kExecutionStateErr			-6703
1040  #define kPathErr					-6704
1041  #define kParamErr					-6705
1042  #define kParamCountErr				-6706
1043  #define kCommandErr					-6707
1044  #define kIDErr						-6708
1045  #define kStateErr					-6709
1046  #define kRangeErr					-6710
1047  #define kRequestErr					-6711
1048  #define kResponseErr				-6712
1049  #define kChecksumErr				-6713
1050  #define kNotHandledErr				-6714
1051  #define kVersionErr					-6715
1052  #define kSignatureErr				-6716
1053  #define kFormatErr					-6717
1054  #define kNotInitializedErr			-6718
1055  #define kAlreadyInitializedErr		-6719
1056  #define kNotInUseErr				-6720
1057  #define kInUseErr					-6721
1058  #define kTimeoutErr					-6722
1059  #define kCanceledErr				-6723
1060  #define kAlreadyCanceledErr			-6724
1061  #define kCannotCancelErr			-6725
1062  #define kDeletedErr					-6726
1063  #define kNotFoundErr				-6727
1064  #define kNoMemoryErr				-6728
1065  #define kNoResourcesErr				-6729
1066  #define kDuplicateErr				-6730
1067  #define kImmutableErr				-6731
1068  #define kUnsupportedDataErr			-6732
1069  #define kIntegrityErr				-6733
1070  #define kIncompatibleErr			-6734
1071  #define kUnsupportedErr				-6735
1072  #define kUnexpectedErr				-6736
1073  #define kValueErr					-6737
1074  #define kNotReadableErr				-6738
1075  #define kNotWritableErr				-6739
1076  #define	kBadReferenceErr			-6740
1077  #define	kFlagErr					-6741
1078  #define	kMalformedErr				-6742
1079  #define	kSizeErr					-6743
1080  #define	kNameErr					-6744
1081  #define	kNotReadyErr				-6745
1082  #define	kReadErr					-6746
1083  #define	kWriteErr					-6747
1084  #define	kMismatchErr				-6748
1085  #define	kDateErr					-6749
1086  #define	kUnderrunErr				-6750
1087  #define	kOverrunErr					-6751
1088  #define	kEndingErr					-6752
1089  #define	kConnectionErr				-6753
1090  #define	kAuthenticationErr			-6754
1091  #define	kOpenErr					-6755
1092  #define	kTypeErr					-6756
1093  #define	kSkipErr					-6757
1094  #define	kNoAckErr					-6758
1095  #define	kCollisionErr				-6759
1096  #define	kBackoffErr					-6760
1097  #define	kNoAddressAckErr			-6761
1098  #define	kBusyErr					-6762
1099  #define	kNoSpaceErr					-6763
1100  
1101  #define kGenericErrorEnd			-6779	// Last generic error code (inclusive)
1102  
1103  #if 0
1104  #pragma mark == Mac Compatibility ==
1105  #endif
1106  
1107  //===========================================================================================================================
1108  //	Mac Compatibility
1109  //===========================================================================================================================
1110  
1111  //---------------------------------------------------------------------------------------------------------------------------
1112  /*!	@enum		Duration
1113  
1114  	@abstract	Type used to specify a duration of time.
1115  
1116  	@constant	kDurationImmediate			Indicates no delay/wait time.
1117  	@constant	kDurationMicrosecond		Microsecond units.
1118  	@constant	kDurationMillisecond		Millisecond units.
1119  	@constant	kDurationSecond				Second units.
1120  	@constant	kDurationMinute				Minute units.
1121  	@constant	kDurationHour				Hour units.
1122  	@constant	kDurationDay				Day units.
1123  	@constant	kDurationForever			Infinite period of time (no timeout).
1124  
1125  	@discussion
1126  
1127  	Duration values are intended to be multiplied by the specific interval to achieve an actual duration. For example,
1128  	to wait for 5 seconds you would use "5 * kDurationSecond".
1129  */
1130  
1131  #if( TARGET_LANGUAGE_C_LIKE )
1132  	#if( !TARGET_OS_MAC )
1133  		typedef	int32_t		Duration;
1134  	#endif
1135  #endif
1136  
1137  #define	kDurationImmediate				0L
1138  #define	kDurationMicrosecond			-1L
1139  #define	kDurationMillisecond			1L
1140  #define	kDurationSecond					( 1000L * kDurationMillisecond )
1141  #define	kDurationMinute					( 60L * kDurationSecond )
1142  #define	kDurationHour					( 60L * kDurationMinute )
1143  #define	kDurationDay					( 24L * kDurationHour )
1144  #define	kDurationForever				0x7FFFFFFFL
1145  
1146  // Seconds <-> Minutes <-> Hours <-> Days <-> Weeks <-> Months <-> Years conversions
1147  
1148  #define kNanosecondsPerMicrosecond		1000
1149  #define kNanosecondsPerMillisecond		1000000
1150  #define kNanosecondsPerSecond			1000000000
1151  #define kMicrosecondsPerSecond			1000000
1152  #define kMicrosecondsPerMillisecond		1000
1153  #define kMillisecondsPerSecond			1000
1154  #define kSecondsPerMinute				60
1155  #define kSecondsPerHour					( 60 * 60 )				// 3600
1156  #define kSecondsPerDay					( 60 * 60 * 24 )		// 86400
1157  #define kSecondsPerWeek					( 60 * 60 * 24 * 7 )	// 604800
1158  #define kMinutesPerHour					60
1159  #define kMinutesPerDay					( 60 * 24 )				// 1440
1160  #define kHoursPerDay					24
1161  #define kDaysPerWeek					7
1162  #define kWeeksPerYear					52
1163  #define kMonthsPerYear					12
1164  
1165  //---------------------------------------------------------------------------------------------------------------------------
1166  /*!	@defined	VersionStages
1167  
1168  	@abstract	NumVersion-style version stages.
1169  */
1170  
1171  #define	kVersionStageDevelopment		0x20
1172  #define	kVersionStageAlpha				0x40
1173  #define	kVersionStageBeta				0x60
1174  #define	kVersionStageFinal				0x80
1175  
1176  //---------------------------------------------------------------------------------------------------------------------------
1177  /*!	@function	NumVersionBuild
1178  
1179  	@abstract	Builds a 32-bit Mac-style NumVersion value (e.g. NumVersionBuild( 1, 2, 3, kVersionStageBeta, 4 ) -> 1.2.3b4).
1180  */
1181  
1182  #define	NumVersionBuild( MAJOR, MINOR, BUGFIX, STAGE, REV )	\
1183  	( ( ( ( MAJOR )  & 0xFF ) << 24 ) |						\
1184  	  ( ( ( MINOR )  & 0x0F ) << 20 ) |						\
1185  	  ( ( ( BUGFIX ) & 0x0F ) << 16 ) |						\
1186  	  ( ( ( STAGE )  & 0xFF ) <<  8 ) |						\
1187  	  ( ( ( REV )    & 0xFF )       ) )
1188  
1189  #define	NumVersionExtractMajor( VERSION )				( (uint8_t)( ( ( VERSION ) >> 24 ) & 0xFF ) )
1190  #define	NumVersionExtractMinorAndBugFix( VERSION )		( (uint8_t)( ( ( VERSION ) >> 16 ) & 0xFF ) )
1191  #define	NumVersionExtractMinor( VERSION )				( (uint8_t)( ( ( VERSION ) >> 20 ) & 0x0F ) )
1192  #define	NumVersionExtractBugFix( VERSION )				( (uint8_t)( ( ( VERSION ) >> 16 ) & 0x0F ) )
1193  #define	NumVersionExtractStage( VERSION )				( (uint8_t)( ( ( VERSION ) >>  8 ) & 0xFF ) )
1194  #define	NumVersionExtractRevision( VERSION )			( (uint8_t)(   ( VERSION )         & 0xFF ) )
1195  
1196  //---------------------------------------------------------------------------------------------------------------------------
1197  /*!	@function	NumVersionCompare
1198  
1199  	@abstract	Compares two NumVersion values and returns the following values:
1200  
1201  		left < right -> -1
1202  		left > right ->  1
1203  		left = right ->  0
1204  */
1205  
1206  #if( TARGET_LANGUAGE_C_LIKE )
1207  	int	NumVersionCompare( uint32_t inLeft, uint32_t inRight );
1208  #endif
1209  
1210  #if 0
1211  #pragma mark == Binary Constants ==
1212  #endif
1213  
1214  //---------------------------------------------------------------------------------------------------------------------------
1215  /*!	@defined	binary_4
1216  
1217  	@abstract	Macro to generate an 4-bit constant using binary notation (e.g. binary_4( 1010 ) == 0xA).
1218  */
1219  
1220  #define	binary_4( a )						binary_4_hex_wrap( hex_digit4( a ) )
1221  #define binary_4_hex_wrap( a )				binary_4_hex( a )
1222  #define binary_4_hex( a )					( 0x ## a )
1223  
1224  //---------------------------------------------------------------------------------------------------------------------------
1225  /*!	@defined	binary_8
1226  
1227  	@abstract	Macro to generate an 8-bit constant using binary notation (e.g. binary_8( 01111011 ) == 0x7B).
1228  */
1229  
1230  #define	binary_8( a )						binary_8_hex_wrap( hex_digit8( a ) )
1231  #define binary_8_hex_wrap( a )				binary_8_hex( a )
1232  #define binary_8_hex( a )					( 0x ## a )
1233  
1234  //---------------------------------------------------------------------------------------------------------------------------
1235  /*!	@defined	binary_16
1236  
1237  	@abstract	Macro to generate an 16-bit constant using binary notation (e.g. binary_16( 01111011, 01111011 ) == 0x7B7B).
1238  */
1239  
1240  #define	binary_16( a, b )					binary_16_hex_wrap( hex_digit8( a ), hex_digit8( b ) )
1241  #define binary_16_hex_wrap( a, b )			binary_16_hex( a, b )
1242  #define binary_16_hex( a, b )				( 0x ## a ## b )
1243  
1244  //---------------------------------------------------------------------------------------------------------------------------
1245  /*!	@defined	binary_32
1246  
1247  	@abstract	Macro to generate an 32-bit constant using binary notation
1248  				(e.g. binary_32( 01111011, 01111011, 01111011, 01111011 ) == 0x7B7B7B7B).
1249  */
1250  
1251  #define	binary_32( a, b, c, d )				binary_32_hex_wrap( hex_digit8( a ), hex_digit8( b ), hex_digit8( c ), hex_digit8( d ) )
1252  #define binary_32_hex_wrap( a, b, c, d )	binary_32_hex( a, b, c, d )
1253  #define binary_32_hex( a, b, c, d )			( 0x ## a ## b ## c ## d )
1254  
1255  // Binary Constant Helpers
1256  
1257  #define hex_digit8( a )						HEX_DIGIT_ ## a
1258  #define hex_digit4( a )						HEX_DIGIT_ ## 0000 ## a
1259  
1260  #define HEX_DIGIT_00000000					00
1261  #define HEX_DIGIT_00000001					01
1262  #define HEX_DIGIT_00000010					02
1263  #define HEX_DIGIT_00000011					03
1264  #define HEX_DIGIT_00000100					04
1265  #define HEX_DIGIT_00000101					05
1266  #define HEX_DIGIT_00000110					06
1267  #define HEX_DIGIT_00000111					07
1268  #define HEX_DIGIT_00001000					08
1269  #define HEX_DIGIT_00001001					09
1270  #define HEX_DIGIT_00001010					0A
1271  #define HEX_DIGIT_00001011					0B
1272  #define HEX_DIGIT_00001100					0C
1273  #define HEX_DIGIT_00001101					0D
1274  #define HEX_DIGIT_00001110					0E
1275  #define HEX_DIGIT_00001111					0F
1276  #define HEX_DIGIT_00010000					10
1277  #define HEX_DIGIT_00010001					11
1278  #define HEX_DIGIT_00010010					12
1279  #define HEX_DIGIT_00010011					13
1280  #define HEX_DIGIT_00010100					14
1281  #define HEX_DIGIT_00010101					15
1282  #define HEX_DIGIT_00010110					16
1283  #define HEX_DIGIT_00010111					17
1284  #define HEX_DIGIT_00011000					18
1285  #define HEX_DIGIT_00011001					19
1286  #define HEX_DIGIT_00011010					1A
1287  #define HEX_DIGIT_00011011					1B
1288  #define HEX_DIGIT_00011100					1C
1289  #define HEX_DIGIT_00011101					1D
1290  #define HEX_DIGIT_00011110					1E
1291  #define HEX_DIGIT_00011111					1F
1292  #define HEX_DIGIT_00100000					20
1293  #define HEX_DIGIT_00100001					21
1294  #define HEX_DIGIT_00100010					22
1295  #define HEX_DIGIT_00100011					23
1296  #define HEX_DIGIT_00100100					24
1297  #define HEX_DIGIT_00100101					25
1298  #define HEX_DIGIT_00100110					26
1299  #define HEX_DIGIT_00100111					27
1300  #define HEX_DIGIT_00101000					28
1301  #define HEX_DIGIT_00101001					29
1302  #define HEX_DIGIT_00101010					2A
1303  #define HEX_DIGIT_00101011					2B
1304  #define HEX_DIGIT_00101100					2C
1305  #define HEX_DIGIT_00101101					2D
1306  #define HEX_DIGIT_00101110					2E
1307  #define HEX_DIGIT_00101111					2F
1308  #define HEX_DIGIT_00110000					30
1309  #define HEX_DIGIT_00110001					31
1310  #define HEX_DIGIT_00110010					32
1311  #define HEX_DIGIT_00110011					33
1312  #define HEX_DIGIT_00110100					34
1313  #define HEX_DIGIT_00110101					35
1314  #define HEX_DIGIT_00110110					36
1315  #define HEX_DIGIT_00110111					37
1316  #define HEX_DIGIT_00111000					38
1317  #define HEX_DIGIT_00111001					39
1318  #define HEX_DIGIT_00111010					3A
1319  #define HEX_DIGIT_00111011					3B
1320  #define HEX_DIGIT_00111100					3C
1321  #define HEX_DIGIT_00111101					3D
1322  #define HEX_DIGIT_00111110					3E
1323  #define HEX_DIGIT_00111111					3F
1324  #define HEX_DIGIT_01000000					40
1325  #define HEX_DIGIT_01000001					41
1326  #define HEX_DIGIT_01000010					42
1327  #define HEX_DIGIT_01000011					43
1328  #define HEX_DIGIT_01000100					44
1329  #define HEX_DIGIT_01000101					45
1330  #define HEX_DIGIT_01000110					46
1331  #define HEX_DIGIT_01000111					47
1332  #define HEX_DIGIT_01001000					48
1333  #define HEX_DIGIT_01001001					49
1334  #define HEX_DIGIT_01001010					4A
1335  #define HEX_DIGIT_01001011					4B
1336  #define HEX_DIGIT_01001100					4C
1337  #define HEX_DIGIT_01001101					4D
1338  #define HEX_DIGIT_01001110					4E
1339  #define HEX_DIGIT_01001111					4F
1340  #define HEX_DIGIT_01010000					50
1341  #define HEX_DIGIT_01010001					51
1342  #define HEX_DIGIT_01010010					52
1343  #define HEX_DIGIT_01010011					53
1344  #define HEX_DIGIT_01010100					54
1345  #define HEX_DIGIT_01010101					55
1346  #define HEX_DIGIT_01010110					56
1347  #define HEX_DIGIT_01010111					57
1348  #define HEX_DIGIT_01011000					58
1349  #define HEX_DIGIT_01011001					59
1350  #define HEX_DIGIT_01011010					5A
1351  #define HEX_DIGIT_01011011					5B
1352  #define HEX_DIGIT_01011100					5C
1353  #define HEX_DIGIT_01011101					5D
1354  #define HEX_DIGIT_01011110					5E
1355  #define HEX_DIGIT_01011111					5F
1356  #define HEX_DIGIT_01100000					60
1357  #define HEX_DIGIT_01100001					61
1358  #define HEX_DIGIT_01100010					62
1359  #define HEX_DIGIT_01100011					63
1360  #define HEX_DIGIT_01100100					64
1361  #define HEX_DIGIT_01100101					65
1362  #define HEX_DIGIT_01100110					66
1363  #define HEX_DIGIT_01100111					67
1364  #define HEX_DIGIT_01101000					68
1365  #define HEX_DIGIT_01101001					69
1366  #define HEX_DIGIT_01101010					6A
1367  #define HEX_DIGIT_01101011					6B
1368  #define HEX_DIGIT_01101100					6C
1369  #define HEX_DIGIT_01101101					6D
1370  #define HEX_DIGIT_01101110					6E
1371  #define HEX_DIGIT_01101111					6F
1372  #define HEX_DIGIT_01110000					70
1373  #define HEX_DIGIT_01110001					71
1374  #define HEX_DIGIT_01110010					72
1375  #define HEX_DIGIT_01110011					73
1376  #define HEX_DIGIT_01110100					74
1377  #define HEX_DIGIT_01110101					75
1378  #define HEX_DIGIT_01110110					76
1379  #define HEX_DIGIT_01110111					77
1380  #define HEX_DIGIT_01111000					78
1381  #define HEX_DIGIT_01111001					79
1382  #define HEX_DIGIT_01111010					7A
1383  #define HEX_DIGIT_01111011					7B
1384  #define HEX_DIGIT_01111100					7C
1385  #define HEX_DIGIT_01111101					7D
1386  #define HEX_DIGIT_01111110					7E
1387  #define HEX_DIGIT_01111111					7F
1388  #define HEX_DIGIT_10000000					80
1389  #define HEX_DIGIT_10000001					81
1390  #define HEX_DIGIT_10000010					82
1391  #define HEX_DIGIT_10000011					83
1392  #define HEX_DIGIT_10000100					84
1393  #define HEX_DIGIT_10000101					85
1394  #define HEX_DIGIT_10000110					86
1395  #define HEX_DIGIT_10000111					87
1396  #define HEX_DIGIT_10001000					88
1397  #define HEX_DIGIT_10001001					89
1398  #define HEX_DIGIT_10001010					8A
1399  #define HEX_DIGIT_10001011					8B
1400  #define HEX_DIGIT_10001100					8C
1401  #define HEX_DIGIT_10001101					8D
1402  #define HEX_DIGIT_10001110					8E
1403  #define HEX_DIGIT_10001111					8F
1404  #define HEX_DIGIT_10010000					90
1405  #define HEX_DIGIT_10010001					91
1406  #define HEX_DIGIT_10010010					92
1407  #define HEX_DIGIT_10010011					93
1408  #define HEX_DIGIT_10010100					94
1409  #define HEX_DIGIT_10010101					95
1410  #define HEX_DIGIT_10010110					96
1411  #define HEX_DIGIT_10010111					97
1412  #define HEX_DIGIT_10011000					98
1413  #define HEX_DIGIT_10011001					99
1414  #define HEX_DIGIT_10011010					9A
1415  #define HEX_DIGIT_10011011					9B
1416  #define HEX_DIGIT_10011100					9C
1417  #define HEX_DIGIT_10011101					9D
1418  #define HEX_DIGIT_10011110					9E
1419  #define HEX_DIGIT_10011111					9F
1420  #define HEX_DIGIT_10100000					A0
1421  #define HEX_DIGIT_10100001					A1
1422  #define HEX_DIGIT_10100010					A2
1423  #define HEX_DIGIT_10100011					A3
1424  #define HEX_DIGIT_10100100					A4
1425  #define HEX_DIGIT_10100101					A5
1426  #define HEX_DIGIT_10100110					A6
1427  #define HEX_DIGIT_10100111					A7
1428  #define HEX_DIGIT_10101000					A8
1429  #define HEX_DIGIT_10101001					A9
1430  #define HEX_DIGIT_10101010					AA
1431  #define HEX_DIGIT_10101011					AB
1432  #define HEX_DIGIT_10101100					AC
1433  #define HEX_DIGIT_10101101					AD
1434  #define HEX_DIGIT_10101110					AE
1435  #define HEX_DIGIT_10101111					AF
1436  #define HEX_DIGIT_10110000					B0
1437  #define HEX_DIGIT_10110001					B1
1438  #define HEX_DIGIT_10110010					B2
1439  #define HEX_DIGIT_10110011					B3
1440  #define HEX_DIGIT_10110100					B4
1441  #define HEX_DIGIT_10110101					B5
1442  #define HEX_DIGIT_10110110					B6
1443  #define HEX_DIGIT_10110111					B7
1444  #define HEX_DIGIT_10111000					B8
1445  #define HEX_DIGIT_10111001					B9
1446  #define HEX_DIGIT_10111010					BA
1447  #define HEX_DIGIT_10111011					BB
1448  #define HEX_DIGIT_10111100					BC
1449  #define HEX_DIGIT_10111101					BD
1450  #define HEX_DIGIT_10111110					BE
1451  #define HEX_DIGIT_10111111					BF
1452  #define HEX_DIGIT_11000000					C0
1453  #define HEX_DIGIT_11000001					C1
1454  #define HEX_DIGIT_11000010					C2
1455  #define HEX_DIGIT_11000011					C3
1456  #define HEX_DIGIT_11000100					C4
1457  #define HEX_DIGIT_11000101					C5
1458  #define HEX_DIGIT_11000110					C6
1459  #define HEX_DIGIT_11000111					C7
1460  #define HEX_DIGIT_11001000					C8
1461  #define HEX_DIGIT_11001001					C9
1462  #define HEX_DIGIT_11001010					CA
1463  #define HEX_DIGIT_11001011					CB
1464  #define HEX_DIGIT_11001100					CC
1465  #define HEX_DIGIT_11001101					CD
1466  #define HEX_DIGIT_11001110					CE
1467  #define HEX_DIGIT_11001111					CF
1468  #define HEX_DIGIT_11010000					D0
1469  #define HEX_DIGIT_11010001					D1
1470  #define HEX_DIGIT_11010010					D2
1471  #define HEX_DIGIT_11010011					D3
1472  #define HEX_DIGIT_11010100					D4
1473  #define HEX_DIGIT_11010101					D5
1474  #define HEX_DIGIT_11010110					D6
1475  #define HEX_DIGIT_11010111					D7
1476  #define HEX_DIGIT_11011000					D8
1477  #define HEX_DIGIT_11011001					D9
1478  #define HEX_DIGIT_11011010					DA
1479  #define HEX_DIGIT_11011011					DB
1480  #define HEX_DIGIT_11011100					DC
1481  #define HEX_DIGIT_11011101					DD
1482  #define HEX_DIGIT_11011110					DE
1483  #define HEX_DIGIT_11011111					DF
1484  #define HEX_DIGIT_11100000					E0
1485  #define HEX_DIGIT_11100001					E1
1486  #define HEX_DIGIT_11100010					E2
1487  #define HEX_DIGIT_11100011					E3
1488  #define HEX_DIGIT_11100100					E4
1489  #define HEX_DIGIT_11100101					E5
1490  #define HEX_DIGIT_11100110					E6
1491  #define HEX_DIGIT_11100111					E7
1492  #define HEX_DIGIT_11101000					E8
1493  #define HEX_DIGIT_11101001					E9
1494  #define HEX_DIGIT_11101010					EA
1495  #define HEX_DIGIT_11101011					EB
1496  #define HEX_DIGIT_11101100					EC
1497  #define HEX_DIGIT_11101101					ED
1498  #define HEX_DIGIT_11101110					EE
1499  #define HEX_DIGIT_11101111					EF
1500  #define HEX_DIGIT_11110000					F0
1501  #define HEX_DIGIT_11110001					F1
1502  #define HEX_DIGIT_11110010					F2
1503  #define HEX_DIGIT_11110011					F3
1504  #define HEX_DIGIT_11110100					F4
1505  #define HEX_DIGIT_11110101					F5
1506  #define HEX_DIGIT_11110110					F6
1507  #define HEX_DIGIT_11110111					F7
1508  #define HEX_DIGIT_11111000					F8
1509  #define HEX_DIGIT_11111001					F9
1510  #define HEX_DIGIT_11111010					FA
1511  #define HEX_DIGIT_11111011					FB
1512  #define HEX_DIGIT_11111100					FC
1513  #define HEX_DIGIT_11111101					FD
1514  #define HEX_DIGIT_11111110					FE
1515  #define HEX_DIGIT_11111111					FF
1516  
1517  #if 0
1518  #pragma mark == Debugging ==
1519  #endif
1520  
1521  //---------------------------------------------------------------------------------------------------------------------------
1522  /*!	@function	CommonServicesTest
1523  
1524  	@abstract	Unit test.
1525  */
1526  
1527  #if( DEBUG )
1528  	#if( TARGET_LANGUAGE_C_LIKE )
1529  		OSStatus	CommonServicesTest( void );
1530  	#endif
1531  #endif
1532  
1533  #ifdef	__cplusplus
1534  	}
1535  #endif
1536  
1537  #endif	// __COMMON_SERVICES__
1538