1 /* Copyright (C) 2004-2005 MySQL AB
2 Use is subject to license terms
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
17 #include <Bitmask.hpp>
18 #include <NdbOut.hpp>
19
20 void
getFieldImpl(const Uint32 src[],unsigned shiftL,unsigned len,Uint32 dst[])21 BitmaskImpl::getFieldImpl(const Uint32 src[],
22 unsigned shiftL, unsigned len, Uint32 dst[])
23 {
24 /* Copy whole words of src to dst, shifting src left
25 * by shiftL. Undefined bits of the last written dst word
26 * should be zeroed.
27 */
28 assert(shiftL < 32);
29
30 unsigned shiftR = 32 - shiftL;
31 unsigned undefined = shiftL ? ~0 : 0;
32
33 /* Merge first word with previously set bits if there's a shift */
34 * dst = shiftL ? * dst : 0;
35
36 /* Treat the zero-shift case separately to avoid
37 * trampling or reading past the end of src
38 */
39 if (shiftL == 0)
40 {
41 while(len >= 32)
42 {
43 * dst++ = * src++;
44 len -=32;
45 }
46
47 if (len != 0)
48 {
49 /* Last word has some bits set */
50 Uint32 mask= ((1 << len) -1); // 0000111
51 * dst = (* src) & mask;
52 }
53 }
54 else // shiftL !=0, need to build each word from two words shifted
55 {
56 while(len >= 32)
57 {
58 * dst++ |= (* src) << shiftL;
59 * dst = ((* src++) >> shiftR) & undefined;
60 len -= 32;
61 }
62
63 /* Have space for shiftR more bits in the current dst word
64 * is that enough?
65 */
66 if(len <= shiftR)
67 {
68 /* Fit the remaining bits in the current dst word */
69 * dst |= ((* src) & ((1 << len) - 1)) << shiftL;
70 }
71 else
72 {
73 /* Need to write to two dst words */
74 * dst++ |= ((* src) << shiftL);
75 * dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined;
76 }
77 }
78 }
79
80 void
setFieldImpl(Uint32 dst[],unsigned shiftL,unsigned len,const Uint32 src[])81 BitmaskImpl::setFieldImpl(Uint32 dst[],
82 unsigned shiftL, unsigned len, const Uint32 src[])
83 {
84 /**
85 *
86 * abcd ef00
87 * 00ab cdef
88 */
89 assert(shiftL < 32);
90 unsigned shiftR = 32 - shiftL;
91 unsigned undefined = shiftL ? ~0 : 0;
92 while(len >= 32)
93 {
94 * dst = (* src++) >> shiftL;
95 * dst++ |= ((* src) << shiftR) & undefined;
96 len -= 32;
97 }
98
99 /* Copy last bits */
100 Uint32 mask = ((1 << len) -1);
101 * dst = (* dst & ~mask);
102 if(len <= shiftR)
103 {
104 /* Remaining bits fit in current word */
105 * dst |= ((* src++) >> shiftL) & mask;
106 }
107 else
108 {
109 /* Remaining bits update 2 words */
110 * dst |= ((* src++) >> shiftL);
111 * dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ;
112 }
113 }
114
115 /* Bitmask testcase code moved from here to
116 * storage/ndb/test/ndbapi/testBitfield.cpp
117 * to get coverage from automated testing
118 */
119