]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/bit.c
Update copyright dates (again)
[thirdparty/xfsprogs-dev.git] / db / bit.c
CommitLineData
2bd0ea18 1/*
0d3e0b37 2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
2bd0ea18
NS
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include <libxfs.h>
34#include "bit.h"
35
36#undef setbit /* defined in param.h on Linux */
37
38static int getbit(char *ptr, int bit);
39static void setbit(char *ptr, int bit, int val);
40
41static int
42getbit(
43 char *ptr,
44 int bit)
45{
46 int mask;
47 int shift;
48
49 ptr += byteize(bit);
50 bit = bitoffs(bit);
51 shift = 7 - bit;
52 mask = 1 << shift;
53 return (*ptr & mask) >> shift;
54}
55
56static void
57setbit(
58 char *ptr,
59 int bit,
60 int val)
61{
62 int mask;
63 int shift;
64
65 ptr += byteize(bit);
66 bit = bitoffs(bit);
67 shift = 7 - bit;
68 mask = (1 << shift);
69 if (val) {
70 *ptr |= mask;
71 } else {
72 mask = ~mask;
73 *ptr &= mask;
74 }
75}
76
77__int64_t
78getbitval(
79 void *obj,
80 int bitoff,
81 int nbits,
82 int flags)
83{
84 int bit;
85 int i;
86 char *p;
87 __int64_t rval;
88 int signext;
89 int z1, z2, z3, z4;
90
91 ASSERT(nbits<=64);
92
93 p = (char *)obj + byteize(bitoff);
94 bit = bitoffs(bitoff);
95 signext = (flags & BVSIGNED) != 0;
96 z4 = ((__psint_t)p & 0xf) == 0 && bit == 0;
97 if (nbits == 64 && z4) {
98 if (signext)
99 return (__int64_t)INT_GET(*(__int64_t *)p, ARCH_CONVERT);
100 else
101 return (__int64_t)INT_GET(*(__uint64_t *)p, ARCH_CONVERT);
102 }
103 z3 = ((__psint_t)p & 0x7) == 0 && bit == 0;
104 if (nbits == 32 && z3) {
105 if (signext)
106 return (__int64_t)INT_GET(*(__int32_t *)p, ARCH_CONVERT);
107 else
108 return (__int64_t)INT_GET(*(__uint32_t *)p, ARCH_CONVERT);
109 }
110 z2 = ((__psint_t)p & 0x3) == 0 && bit == 0;
111 if (nbits == 16 && z2) {
112 if (signext)
113 return (__int64_t)INT_GET(*(__int16_t *)p, ARCH_CONVERT);
114 else
115 return (__int64_t)INT_GET(*(__uint16_t *)p, ARCH_CONVERT);
116 }
117 z1 = ((__psint_t)p & 0x1) == 0 && bit == 0;
118 if (nbits == 8 && z1) {
119 if (signext)
120 return (__int64_t)INT_GET(*(__int8_t *)p, ARCH_CONVERT);
121 else
122 return (__int64_t)INT_GET(*(__uint8_t *)p, ARCH_CONVERT);
123 }
124
125
126 for (i = 0, rval = 0LL; i < nbits; i++) {
127 if (getbit(p, bit + i)) {
128 /* If the last bit is on and we care about sign
129 * bits and we don't have a full 64 bit
130 * container, turn all bits on between the
131 * sign bit and the most sig bit.
132 */
133
134 /* handle endian swap here */
135#if __BYTE_ORDER == LITTLE_ENDIAN
136 if (i == 0 && signext && nbits < 64)
137 rval = -1LL << nbits;
138 rval |= 1LL << (nbits - i - 1);
139#else
140 if ((i == (nbits - 1)) && signext && nbits < 64)
141 rval |= (-1LL << nbits);
06ac6550 142 rval |= 1LL << (nbits - i - 1);
2bd0ea18
NS
143#endif
144 }
145 }
146 return rval;
147}
148
149void
150setbitval(
151 void *obuf, /* buffer to write into */
152 int bitoff, /* bit offset of where to write */
153 int nbits, /* number of bits to write */
154 void *ibuf) /* source bits */
155{
156 char *in = (char *)ibuf;
157 char *out = (char *)obuf;
158
159 int bit;
160
161#if BYTE_ORDER == LITTLE_ENDIAN
162 int big = 0;
163#else
164 int big = 1;
165#endif
166
167 /* only need to swap LE integers */
e4103ff2 168 if (big || (nbits!=8 && nbits!=32 && nbits!=64) ) {
2bd0ea18
NS
169 /* We don't have type info, so we can only assume
170 * that 2,4 & 8 byte values are integers. sigh.
171 */
172
173 /* byte aligned ? */
174 if (bitoff%NBBY) {
175 /* no - bit copy */
176 for (bit=0; bit<nbits; bit++)
177 setbit(out, bit+bitoff, getbit(in, bit));
178 } else {
179 /* yes - byte copy */
180 memcpy(out+byteize(bitoff), in, byteize(nbits));
181 }
182
183 } else {
184 int ibit;
185 int obit;
186
187 /* we need to endian swap this value */
188
189 out+=byteize(bitoff);
190 obit=bitoffs(bitoff);
191
192 ibit=nbits-NBBY;
193
194 for (bit=0; bit<nbits; bit++) {
195 setbit(out, bit+obit, getbit(in, ibit));
196 if (ibit%NBBY==NBBY-1)
197 ibit-=NBBY*2-1;
198 else
199 ibit++;
200 }
201 }
202}