dyld-750.6.tar.gz
[apple/dyld.git] / launch-cache / 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 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); }
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         
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         
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); }
130         static void             setP(uint_t& into, uint64_t value)              INLINE { _E::set32(into, (uint32_t)value); }
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; }
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); }
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; }
155 };
156
157
158
159
160
161 #endif // __FILE_ABSTRACTION__
162
163