]> git.saurik.com Git - apple/ld64.git/blob - src/FileAbstraction.hpp
ld64-59.3.tar.gz
[apple/ld64.git] / src / FileAbstraction.hpp
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); }
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
87 class LittleEndian
88 {
89 public:
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
116 template <typename _E>
117 class Pointer32
118 {
119 public:
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
128 template <typename _E>
129 class Pointer64
130 {
131 public:
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 #endif // __FILE_ABSTRACTION__
144
145