]>
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
34 return (*ptr
& mask
) >> shift
;
74 p
= (char *)obj
+ byteize(bitoff
);
75 bit
= bitoffs(bitoff
);
76 signext
= (flags
& BVSIGNED
) != 0;
77 z4
= ((intptr_t)p
& 0xf) == 0 && bit
== 0;
78 if (nbits
== 64 && z4
)
79 return be64_to_cpu(*(__be64
*)p
);
80 z3
= ((intptr_t)p
& 0x7) == 0 && bit
== 0;
81 if (nbits
== 32 && z3
) {
83 return (__s32
)be32_to_cpu(*(__be32
*)p
);
85 return (__u32
)be32_to_cpu(*(__be32
*)p
);
87 z2
= ((intptr_t)p
& 0x3) == 0 && bit
== 0;
88 if (nbits
== 16 && z2
) {
90 return (__s16
)be16_to_cpu(*(__be16
*)p
);
92 return (__u16
)be16_to_cpu(*(__be16
*)p
);
94 z1
= ((intptr_t)p
& 0x1) == 0 && bit
== 0;
95 if (nbits
== 8 && z1
) {
103 for (i
= 0, rval
= 0LL; i
< nbits
; i
++) {
104 if (getbit_l(p
, bit
+ i
)) {
105 /* If the last bit is on and we care about sign
106 * bits and we don't have a full 64 bit
107 * container, turn all bits on between the
108 * sign bit and the most sig bit.
111 /* handle endian swap here */
112 #if __BYTE_ORDER == LITTLE_ENDIAN
113 if (i
== 0 && signext
&& nbits
< 64)
114 rval
= (~0ULL) << nbits
;
115 rval
|= 1ULL << (nbits
- i
- 1);
117 if ((i
== (nbits
- 1)) && signext
&& nbits
< 64)
118 rval
|= ((~0ULL) << nbits
);
119 rval
|= 1ULL << (nbits
- i
- 1);
127 * The input data can be 8, 16, 32, and 64 sized numeric values
128 * aligned on a byte boundry, or odd sized numbers stored on odd
129 * aligned offset (for example the bmbt fields).
131 * The input data sent to this routine has been converted to big endian
132 * and has been adjusted in the array so that the first input bit is to
133 * be written in the first bit in the output.
135 * If the field length and the output buffer are byte aligned, then use
136 * memcpy from the input to the output, but if either entries are not byte
137 * aligned, then loop over the entire bit range reading the input value
138 * and set/clear the matching bit in the output.
140 * example when ibuf is not multiple of a byte in length:
142 * ibuf: | BBBBBBBB | bbbxxxxx |
144 * obuf+bitoff: | xBBBBBBB | Bbbbxxxx |
149 void *obuf
, /* start of buffer to write into */
150 int bitoff
, /* bit offset into the output buffer */
151 int nbits
, /* number of bits to write */
152 void *ibuf
) /* source bits */
158 if (bitoff
% NBBY
|| nbits
% NBBY
) {
159 for (bit
= 0; bit
< nbits
; bit
++)
160 setbit_l(out
, bit
+ bitoff
, getbit_l(in
, bit
));
162 memcpy(out
+ byteize(bitoff
), in
, byteize(nbits
));