1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2005-2008 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24#ifndef __FILE_ABSTRACTION__
25#define __FILE_ABSTRACTION__
26
27
28#include <stdint.h>
29#include <string.h>
30#include <libkern/OSByteOrder.h>
31
32#ifdef __OPTIMIZE__
33#define INLINE	__attribute__((always_inline))
34#else
35#define INLINE
36#endif
37
38//
39// This abstraction layer is for use with file formats that have 64-bit/32-bit and Big-Endian/Little-Endian variants
40//
41// For example: to make a utility that handles 32-bit little enidan files use:  Pointer32<LittleEndian>
42//
43//
44//		get16()			read a 16-bit number from an E endian struct
45//		set16()			write a 16-bit number to an E endian struct
46//		get32()			read a 32-bit number from an E endian struct
47//		set32()			write a 32-bit number to an E endian struct
48//		get64()			read a 64-bit number from an E endian struct
49//		set64()			write a 64-bit number to an E endian struct
50//
51//		getBits()		read a bit field from an E endian struct (bitCount=number of bits in field, firstBit=bit index of field)
52//		setBits()		write a bit field to an E endian struct (bitCount=number of bits in field, firstBit=bit index of field)
53//
54//		getBitsRaw()	read a bit field from a struct with native endianness
55//		setBitsRaw()	write a bit field from a struct with native endianness
56//
57
58class BigEndian
59{
60public:
61	static uint16_t	get16(const uint16_t& from)				INLINE { return OSReadBigInt16(&from, 0); }
62	static void		set16(uint16_t& into, uint16_t value)	INLINE { OSWriteBigInt16(&into, 0, value); }
63
64	static uint32_t	get32(const uint32_t& from)				INLINE { return OSReadBigInt32(&from, 0); }
65	static void		set32(uint32_t& into, uint32_t value)	INLINE { OSWriteBigInt32(&into, 0, value); }
66
67	static uint64_t get64(const uint64_t& from)				INLINE { return OSReadBigInt64(&from, 0); }
68	static void		set64(uint64_t& into, uint64_t value)	INLINE { OSWriteBigInt64(&into, 0, value); }
69
70	static uint32_t	getBits(const uint32_t& from,
71						uint8_t firstBit, uint8_t bitCount)	INLINE { return getBitsRaw(get32(from), firstBit, bitCount); }
72	static void		setBits(uint32_t& into, uint32_t value,
73						uint8_t firstBit, uint8_t bitCount)	INLINE { uint32_t temp = get32(into); setBitsRaw(temp, value, firstBit, bitCount); set32(into, temp); }
74
75	static uint32_t	getBitsRaw(const uint32_t& from,
76						uint8_t firstBit, uint8_t bitCount)	INLINE { return ((from >> (32-firstBit-bitCount)) & ((1<<bitCount)-1)); }
77	static void		setBitsRaw(uint32_t& into, uint32_t value,
78						uint8_t firstBit, uint8_t bitCount)	INLINE { uint32_t temp = into;
79																							const uint32_t mask = ((1<<bitCount)-1);
80																							temp &= ~(mask << (32-firstBit-bitCount));
81																							temp |= ((value & mask) << (32-firstBit-bitCount));
82																							into = temp; }
83	enum { little_endian = 0 };
84};
85
86
87class LittleEndian
88{
89public:
90	static uint16_t	get16(const uint16_t& from)				INLINE { return OSReadLittleInt16(&from, 0); }
91	static void		set16(uint16_t& into, uint16_t value)	INLINE { OSWriteLittleInt16(&into, 0, value); }
92
93	static uint32_t	get32(const uint32_t& from)				INLINE { return OSReadLittleInt32(&from, 0); }
94	static void		set32(uint32_t& into, uint32_t value)	INLINE { OSWriteLittleInt32(&into, 0, value); }
95
96	static uint64_t get64(const uint64_t& from)				INLINE { return OSReadLittleInt64(&from, 0); }
97	static void		set64(uint64_t& into, uint64_t value)	INLINE { OSWriteLittleInt64(&into, 0, value); }
98
99	static uint32_t	getBits(const uint32_t& from,
100						uint8_t firstBit, uint8_t bitCount)	INLINE { return getBitsRaw(get32(from), firstBit, bitCount); }
101	static void		setBits(uint32_t& into, uint32_t value,
102						uint8_t firstBit, uint8_t bitCount)	INLINE { uint32_t temp = get32(into); setBitsRaw(temp, value, firstBit, bitCount); set32(into, temp); }
103
104	static uint32_t	getBitsRaw(const uint32_t& from,
105						uint8_t firstBit, uint8_t bitCount)	INLINE { return ((from >> firstBit) & ((1<<bitCount)-1)); }
106	static void		setBitsRaw(uint32_t& into, uint32_t value,
107						uint8_t firstBit, uint8_t bitCount)	INLINE {  uint32_t temp = into;
108																							const uint32_t mask = ((1<<bitCount)-1);
109																							temp &= ~(mask << firstBit);
110																							temp |= ((value & mask) << firstBit);
111																							into = temp; }
112	enum { little_endian = 1 };
113};
114
115
116template <typename _E>
117class Pointer32
118{
119public:
120	typedef uint32_t	uint_t;
121	typedef _E			E;
122
123	static uint64_t	getP(const uint_t& from)				INLINE { return _E::get32(from); }
124	static void		setP(uint_t& into, uint64_t value)		INLINE { _E::set32(into, value); }
125};
126
127
128template <typename _E>
129class Pointer64
130{
131public:
132	typedef uint64_t	uint_t;
133	typedef _E			E;
134
135	static uint64_t	getP(const uint_t& from)				INLINE { return _E::get64(from); }
136	static void		setP(uint_t& into, uint64_t value)		INLINE { _E::set64(into, value); }
137};
138
139
140
141
142
143
144#endif // __FILE_ABSTRACTION__
145
146
147