]>
Commit | Line | Data |
---|---|---|
bac542e6 A |
1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- |
2 | * | |
3 | * Copyright (c) 2005 Apple Computer, 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 | ||
58 | class BigEndian | |
59 | { | |
60 | public: | |
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); } | |
39a8cd10 A |
66 | |
67 | static int32_t get32(const int32_t& from) INLINE { return OSReadBigInt32(&from, 0); } | |
68 | static void set32(int32_t& into, int32_t value) INLINE { OSWriteBigInt32(&into, 0, value); } | |
bac542e6 A |
69 | |
70 | static uint64_t get64(const uint64_t& from) INLINE { return OSReadBigInt64(&from, 0); } | |
71 | static void set64(uint64_t& into, uint64_t value) INLINE { OSWriteBigInt64(&into, 0, value); } | |
72 | ||
73 | static uint32_t getBits(const uint32_t& from, | |
74 | uint8_t firstBit, uint8_t bitCount) INLINE { return getBitsRaw(get32(from), firstBit, bitCount); } | |
75 | static void setBits(uint32_t& into, uint32_t value, | |
76 | uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = get32(into); setBitsRaw(temp, value, firstBit, bitCount); set32(into, temp); } | |
77 | ||
78 | static uint32_t getBitsRaw(const uint32_t& from, | |
79 | uint8_t firstBit, uint8_t bitCount) INLINE { return ((from >> (32-firstBit-bitCount)) & ((1<<bitCount)-1)); } | |
80 | static void setBitsRaw(uint32_t& into, uint32_t value, | |
81 | uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = into; | |
82 | const uint32_t mask = ((1<<bitCount)-1); | |
83 | temp &= ~(mask << (32-firstBit-bitCount)); | |
84 | temp |= ((value & mask) << (32-firstBit-bitCount)); | |
85 | into = temp; } | |
86 | enum { little_endian = 0 }; | |
87 | }; | |
88 | ||
89 | ||
90 | class LittleEndian | |
91 | { | |
92 | public: | |
93 | static uint16_t get16(const uint16_t& from) INLINE { return OSReadLittleInt16(&from, 0); } | |
94 | static void set16(uint16_t& into, uint16_t value) INLINE { OSWriteLittleInt16(&into, 0, value); } | |
95 | ||
96 | static uint32_t get32(const uint32_t& from) INLINE { return OSReadLittleInt32(&from, 0); } | |
97 | static void set32(uint32_t& into, uint32_t value) INLINE { OSWriteLittleInt32(&into, 0, value); } | |
98 | ||
39a8cd10 A |
99 | static int32_t get32(const int32_t& from) INLINE { return OSReadLittleInt32(&from, 0); } |
100 | static void set32(int32_t& into, int32_t value) INLINE { OSWriteLittleInt32(&into, 0, value); } | |
101 | ||
bac542e6 A |
102 | static uint64_t get64(const uint64_t& from) INLINE { return OSReadLittleInt64(&from, 0); } |
103 | static void set64(uint64_t& into, uint64_t value) INLINE { OSWriteLittleInt64(&into, 0, value); } | |
104 | ||
105 | static uint32_t getBits(const uint32_t& from, | |
106 | uint8_t firstBit, uint8_t bitCount) INLINE { return getBitsRaw(get32(from), firstBit, bitCount); } | |
107 | static void setBits(uint32_t& into, uint32_t value, | |
108 | uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = get32(into); setBitsRaw(temp, value, firstBit, bitCount); set32(into, temp); } | |
109 | ||
110 | static uint32_t getBitsRaw(const uint32_t& from, | |
111 | uint8_t firstBit, uint8_t bitCount) INLINE { return ((from >> firstBit) & ((1<<bitCount)-1)); } | |
112 | static void setBitsRaw(uint32_t& into, uint32_t value, | |
113 | uint8_t firstBit, uint8_t bitCount) INLINE { uint32_t temp = into; | |
114 | const uint32_t mask = ((1<<bitCount)-1); | |
115 | temp &= ~(mask << firstBit); | |
116 | temp |= ((value & mask) << firstBit); | |
117 | into = temp; } | |
118 | enum { little_endian = 1 }; | |
119 | }; | |
120 | ||
121 | ||
122 | template <typename _E> | |
123 | class Pointer32 | |
124 | { | |
125 | public: | |
126 | typedef uint32_t uint_t; | |
127 | typedef _E E; | |
128 | ||
129 | static uint64_t getP(const uint_t& from) INLINE { return _E::get32(from); } | |
19894a12 | 130 | static void setP(uint_t& into, uint64_t value) INLINE { _E::set32(into, (uint32_t)value); } |
412ebb8e A |
131 | |
132 | // Round to a P-size boundary | |
133 | template <typename T> | |
134 | static T round_up(T value) { return (value+3) & ~(T)3; } | |
135 | template <typename T> | |
136 | static T round_down(T value) { return value & ~(T)3; } | |
bac542e6 A |
137 | }; |
138 | ||
139 | ||
140 | template <typename _E> | |
141 | class Pointer64 | |
142 | { | |
143 | public: | |
144 | typedef uint64_t uint_t; | |
145 | typedef _E E; | |
146 | ||
147 | static uint64_t getP(const uint_t& from) INLINE { return _E::get64(from); } | |
148 | static void setP(uint_t& into, uint64_t value) INLINE { _E::set64(into, value); } | |
412ebb8e A |
149 | |
150 | // Round to a P-size boundary | |
151 | template <typename T> | |
152 | static T round_up(T value) { return (value+7) & ~(T)7; } | |
153 | template <typename T> | |
154 | static T round_down(T value) { return value & ~(T)7; } | |
bac542e6 A |
155 | }; |
156 | ||
157 | ||
158 | ||
159 | ||
160 | ||
161 | #endif // __FILE_ABSTRACTION__ | |
162 | ||
163 |