]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/bit.c
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #undef setbit /* defined in param.h on Linux */
24 static int getbit(char *ptr
, int bit
);
25 static void setbit(char *ptr
, int bit
, int val
);
39 return (*ptr
& mask
) >> shift
;
79 p
= (char *)obj
+ byteize(bitoff
);
80 bit
= bitoffs(bitoff
);
81 signext
= (flags
& BVSIGNED
) != 0;
82 z4
= ((intptr_t)p
& 0xf) == 0 && bit
== 0;
83 if (nbits
== 64 && z4
)
84 return be64_to_cpu(*(__be64
*)p
);
85 z3
= ((intptr_t)p
& 0x7) == 0 && bit
== 0;
86 if (nbits
== 32 && z3
) {
88 return (__s32
)be32_to_cpu(*(__be32
*)p
);
90 return (__u32
)be32_to_cpu(*(__be32
*)p
);
92 z2
= ((intptr_t)p
& 0x3) == 0 && bit
== 0;
93 if (nbits
== 16 && z2
) {
95 return (__s16
)be16_to_cpu(*(__be16
*)p
);
97 return (__u16
)be16_to_cpu(*(__be16
*)p
);
99 z1
= ((intptr_t)p
& 0x1) == 0 && bit
== 0;
100 if (nbits
== 8 && z1
) {
108 for (i
= 0, rval
= 0LL; i
< nbits
; i
++) {
109 if (getbit(p
, bit
+ i
)) {
110 /* If the last bit is on and we care about sign
111 * bits and we don't have a full 64 bit
112 * container, turn all bits on between the
113 * sign bit and the most sig bit.
116 /* handle endian swap here */
117 #if __BYTE_ORDER == LITTLE_ENDIAN
118 if (i
== 0 && signext
&& nbits
< 64)
119 rval
= -1LL << nbits
;
120 rval
|= 1LL << (nbits
- i
- 1);
122 if ((i
== (nbits
- 1)) && signext
&& nbits
< 64)
123 rval
|= (-1LL << nbits
);
124 rval
|= 1LL << (nbits
- i
- 1);
132 * The input data can be 8, 16, 32, and 64 sized numeric values
133 * aligned on a byte boundry, or odd sized numbers stored on odd
134 * aligned offset (for example the bmbt fields).
136 * The input data sent to this routine has been converted to big endian
137 * and has been adjusted in the array so that the first input bit is to
138 * be written in the first bit in the output.
140 * If the field length and the output buffer are byte aligned, then use
141 * memcpy from the input to the output, but if either entries are not byte
142 * aligned, then loop over the entire bit range reading the input value
143 * and set/clear the matching bit in the output.
145 * example when ibuf is not multiple of a byte in length:
147 * ibuf: | BBBBBBBB | bbbxxxxx |
149 * obuf+bitoff: | xBBBBBBB | Bbbbxxxx |
154 void *obuf
, /* start of buffer to write into */
155 int bitoff
, /* bit offset into the output buffer */
156 int nbits
, /* number of bits to write */
157 void *ibuf
) /* source bits */
163 if (bitoff
% NBBY
|| nbits
% NBBY
) {
164 for (bit
= 0; bit
< nbits
; bit
++)
165 setbit(out
, bit
+ bitoff
, getbit(in
, bit
));
167 memcpy(out
+ byteize(bitoff
), in
, byteize(nbits
));