/* Copyright (C) 2004-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include void BitmaskImpl::getFieldImpl(const Uint32 src[], unsigned shiftL, unsigned len, Uint32 dst[]) { /* Copy whole words of src to dst, shifting src left * by shiftL. Undefined bits of the last written dst word * should be zeroed. */ assert(shiftL < 32); unsigned shiftR = 32 - shiftL; unsigned undefined = shiftL ? ~0 : 0; /* Merge first word with previously set bits if there's a shift */ * dst = shiftL ? * dst : 0; /* Treat the zero-shift case separately to avoid * trampling or reading past the end of src */ if (shiftL == 0) { while(len >= 32) { * dst++ = * src++; len -=32; } if (len != 0) { /* Last word has some bits set */ Uint32 mask= ((1 << len) -1); // 0000111 * dst = (* src) & mask; } } else // shiftL !=0, need to build each word from two words shifted { while(len >= 32) { * dst++ |= (* src) << shiftL; * dst = ((* src++) >> shiftR) & undefined; len -= 32; } /* Have space for shiftR more bits in the current dst word * is that enough? */ if(len <= shiftR) { /* Fit the remaining bits in the current dst word */ * dst |= ((* src) & ((1 << len) - 1)) << shiftL; } else { /* Need to write to two dst words */ * dst++ |= ((* src) << shiftL); * dst = ((* src) >> shiftR) & ((1 << (len - shiftR)) - 1) & undefined; } } } void BitmaskImpl::setFieldImpl(Uint32 dst[], unsigned shiftL, unsigned len, const Uint32 src[]) { /** * * abcd ef00 * 00ab cdef */ assert(shiftL < 32); unsigned shiftR = 32 - shiftL; unsigned undefined = shiftL ? ~0 : 0; while(len >= 32) { * dst = (* src++) >> shiftL; * dst++ |= ((* src) << shiftR) & undefined; len -= 32; } /* Copy last bits */ Uint32 mask = ((1 << len) -1); * dst = (* dst & ~mask); if(len <= shiftR) { /* Remaining bits fit in current word */ * dst |= ((* src++) >> shiftL) & mask; } else { /* Remaining bits update 2 words */ * dst |= ((* src++) >> shiftL); * dst |= ((* src) & ((1 << (len - shiftR)) - 1)) << shiftR ; } } /* Bitmask testcase code moved from here to * storage/ndb/test/ndbapi/testBitfield.cpp * to get coverage from automated testing */