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