1/*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 *
28 * HISTORY
29 *   gvdl    20050620    Created
30 */
31
32/*!
33@header OSEndianTypes
34@abstract C++ inline types for byte swapping
35@discussion
36The OSEndianTypes consist of a number of types that are used very similarly to the traditional MacOS C scalar integers types, eg. UInt32 and SInt32.
37@copyright 2005 Apple Computer, Inc. All rights reserved.
38@updated 2005-07-25
39*/
40
41// Header doc magic trick for simple documentation
42#if 0
43/*!  @typedef BigUInt16
44@abstract A Big-endian unsigned integer scalar size 16 - UInt16 */
45typedef class BigUInt16 BigUInt16;
46#endif
47
48#if 0
49/*! @typedef BigSInt16
50@abstract A Big-endian signed integer scalar size 16 - SInt16 */
51typedef class BigSInt16 BigSInt16;
52
53/*! @typedef BigUInt32
54@abstract A Big-endian unsigned integer scalar size 32 - UInt32 */
55typedef class BigUInt32 BigUInt32;
56
57/*! @typedef BigSInt32
58@abstract A Big-endian signed integer scalar size 32 - SInt32 */
59typedef class BigSInt32 BigSInt32;
60
61/*! @typedef BigUInt64
62@abstract A Big-endian unsigned integer scalar size 64 - UInt64 */
63typedef class BigUInt64 BigUInt64;
64
65/*! @typedef BigSInt64
66@abstract A Big-endian signed integer scalar size 64 - SInt64 */
67typedef class BigSInt64 BigSInt64;
68
69/*! @typedef LittleUInt16
70@abstract A Little-endian unsigned integer scalar size 16 - UInt16 */
71typedef class LittleUInt16 LittleUInt16;
72
73/*! @typedef LittleSInt16
74@abstract A Little-endian signed integer scalar size 16 - SInt16 */
75typedef class LittleSInt16 LittleSInt16;
76
77/*! @typedef LittleUInt32
78@abstract A Little-endian unsigned integer scalar size 32 - UInt32 */
79typedef class LittleUInt32 LittleUInt32;
80
81/*! @typedef LittleSInt32
82@abstract A Little-endian signed integer scalar size 32 - SInt32 */
83typedef class LittleSInt32 LittleSInt32;
84
85/*! @typedef LittleUInt64
86@abstract A Little-endian unsigned integer scalar size 64 - UInt64 */
87typedef class LittleUInt64 LittleUInt64;
88
89/*! @typedef LittleSInt64
90@abstract A Little-endian signed integer scalar size 64 - SInt64 */
91typedef class LittleSInt64 LittleSInt64;
92
93*/
94#endif
95
96#ifndef _OS_OSENDIANHELPER_H
97#define _OS_OSENDIANHELPER_H
98
99#if __cplusplus
100
101#include <libkern/OSTypes.h>
102#include <libkern/OSByteOrder.h>
103
104// Probably should really be using templates, this is one of the few cases
105// where they do make sense.  But as the kernel is not allowed to export
106// template based C++ APIs we have to use sophisticated macros instead
107#define __OSEndianSignIntSizeDEF(argname, argend, argtype, argsize) {	\
108public:									\
109    typedef argtype ## argsize		Value;				\
110									\
111private:								\
112    typedef UInt ## argsize		UValue;				\
113    UValue mValue;							\
114									\
115    void writeValue(Value v) {						\
116	if (__builtin_constant_p(v))					\
117	    mValue = OSSwapHostTo ## argend ## ConstInt ## argsize(v);	\
118	else								\
119	    OSWrite ## argend ## Int ## argsize(&mValue, 0, (UValue) v);\
120    };									\
121									\
122    Value readValue() const {						\
123	return (Value) OSRead ## argend ## Int ## argsize(&mValue, 0);	\
124    };									\
125									\
126public:									\
127    argname() { };							\
128									\
129    argname (Value v) { writeValue(v); };				\
130    argname  &operator = (Value v) { writeValue(v); return *this; }	\
131									\
132    Value get() const { return readValue(); };				\
133    operator Value () const { return readValue(); };			\
134}
135
136class BigUInt16    __OSEndianSignIntSizeDEF(BigUInt16,    Big,    UInt, 16);
137class BigSInt16    __OSEndianSignIntSizeDEF(BigSInt16,    Big,    SInt, 16);
138class BigUInt32    __OSEndianSignIntSizeDEF(BigUInt32,    Big,    UInt, 32);
139class BigSInt32    __OSEndianSignIntSizeDEF(BigSInt32,    Big,    SInt, 32);
140class BigUInt64    __OSEndianSignIntSizeDEF(BigUInt64,    Big,    UInt, 64);
141class BigSInt64    __OSEndianSignIntSizeDEF(BigSInt64,    Big,    SInt, 64);
142class LittleUInt16 __OSEndianSignIntSizeDEF(LittleUInt16, Little, UInt, 16);
143class LittleSInt16 __OSEndianSignIntSizeDEF(LittleSInt16, Little, SInt, 16);
144class LittleUInt32 __OSEndianSignIntSizeDEF(LittleUInt32, Little, UInt, 32);
145class LittleSInt32 __OSEndianSignIntSizeDEF(LittleSInt32, Little, SInt, 32);
146class LittleUInt64 __OSEndianSignIntSizeDEF(LittleUInt64, Little, UInt, 64);
147class LittleSInt64 __OSEndianSignIntSizeDEF(LittleSInt64, Little, SInt, 64);
148
149#undef __OSEndianSignIntSizeDEF
150
151#endif /* __cplusplus */
152
153#endif /* ! _OS_OSENDIANHELPER_H */
154
155
156