]>
Commit | Line | Data |
---|---|---|
1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- | |
2 | * | |
3 | * Copyright (c) 2005 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 | ||
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 int32_t sint_t; | |
122 | typedef _E E; | |
123 | ||
124 | static uint64_t getP(const uint_t& from) INLINE { return _E::get32(from); } | |
125 | static void setP(uint_t& into, uint64_t value) INLINE { _E::set32(into, value); } | |
126 | }; | |
127 | ||
128 | ||
129 | template <typename _E> | |
130 | class Pointer64 | |
131 | { | |
132 | public: | |
133 | typedef uint64_t uint_t; | |
134 | typedef int64_t sint_t; | |
135 | typedef _E E; | |
136 | ||
137 | static uint64_t getP(const uint_t& from) INLINE { return _E::get64(from); } | |
138 | static void setP(uint_t& into, uint64_t value) INLINE { _E::set64(into, value); } | |
139 | }; | |
140 | ||
141 | ||
142 | ||
143 | ||
144 | ||
145 | #endif // __FILE_ABSTRACTION__ | |
146 | ||
147 |