diff options
Diffstat (limited to 'binfilter/bf_sfx2/source/bastyp/sfx2_bitset.cxx')
-rw-r--r-- | binfilter/bf_sfx2/source/bastyp/sfx2_bitset.cxx | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/binfilter/bf_sfx2/source/bastyp/sfx2_bitset.cxx b/binfilter/bf_sfx2/source/bastyp/sfx2_bitset.cxx new file mode 100644 index 000000000000..bd9178b2f8ed --- /dev/null +++ b/binfilter/bf_sfx2/source/bastyp/sfx2_bitset.cxx @@ -0,0 +1,273 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <tools/debug.hxx> +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "bitset.hxx" + +#include <string.h> // memset(), memcpy() +#include <limits.h> // USHRT_MAX +namespace binfilter { + +//==================================================================== +// add nOffset to each bit-value in the set + +/*N*/ BitSet BitSet::operator<<( USHORT nOffset ) const +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ // create a work-copy, return it if nothing to shift +/*N*/ BitSet aSet(*this); +/*N*/ if ( nOffset == 0 ) +/*N*/ return aSet; +/*N*/ +/*N*/ // compute the shiftment in long-words and bits +/*N*/ USHORT nBlockDiff = nOffset / 32; +/*N*/ ULONG nBitValDiff = nOffset % 32; +/*N*/ +/*N*/ // compute the new number of bits +/*N*/ for ( USHORT nBlock = 0; nBlock < nBlockDiff; ++nBlock ) +/*?*/ aSet.nCount -= CountBits( *(aSet.pBitmap+nBlock) ); +/*N*/ aSet.nCount -= CountBits( *(aSet.pBitmap+nBlockDiff) >> (32-nBitValDiff) ); +/*N*/ +/*N*/ // shift complete long-words +/*N*/ USHORT nTarget, nSource; +/*N*/ for ( nTarget = 0, nSource = nBlockDiff; +/*N*/ (nSource+1) < aSet.nBlocks; +/*N*/ ++nTarget, ++nSource ) +/*N*/ *(aSet.pBitmap+nTarget) = +/*N*/ ( *(aSet.pBitmap+nSource) << nBitValDiff ) | +/*N*/ ( *(aSet.pBitmap+nSource+1) >> (32-nBitValDiff) ); +/*N*/ +/*N*/ // shift the remainder (if in total minor 32 bits, only this) +/*N*/ *(aSet.pBitmap+nTarget) = *(aSet.pBitmap+nSource) << nBitValDiff; +/*N*/ +/*N*/ // determine the last used block +/*N*/ while ( *(aSet.pBitmap+nTarget) == 0 ) +/*N*/ --nTarget; +/*N*/ +/*N*/ // shorten the block-array +/*N*/ if ( nTarget < aSet.nBlocks ) +/*N*/ { +/*N*/ ULONG* pNewMap = new ULONG[nTarget]; +/*N*/ memcpy( pNewMap, aSet.pBitmap, 4 * nTarget ); +/*N*/ delete [] aSet.pBitmap; +/*N*/ aSet.pBitmap = pNewMap; +/*N*/ aSet.nBlocks = nTarget; +/*N*/ } +/*N*/ +/*N*/ return aSet; +/*N*/ } + +//-------------------------------------------------------------------- + +// substracts nOffset from each bit-value in the set + + +//-------------------------------------------------------------------- + +// internal code for operator= and copy-ctor + +/*N*/ void BitSet::CopyFrom( const BitSet& rSet ) +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ nCount = rSet.nCount; +/*N*/ nBlocks = rSet.nBlocks; +/*N*/ if ( rSet.nBlocks ) +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ pBitmap = new ULONG[nBlocks]; +/*N*/ memcpy( pBitmap, rSet.pBitmap, 4 * nBlocks ); +/*N*/ } +/*N*/ else +/*N*/ pBitmap = 0; +/*N*/ } + +//-------------------------------------------------------------------- + +// creates an empty bitset + +/*N*/ BitSet::BitSet() +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ nCount = 0; +/*N*/ nBlocks = 0; +/*N*/ pBitmap = 0; +/*N*/ } + +//-------------------------------------------------------------------- + +// creates a copy of bitset rOrig + +/*N*/ BitSet::BitSet( const BitSet& rOrig ) +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ CopyFrom(rOrig); +/*N*/ } + +//-------------------------------------------------------------------- + +// creates a bitset from an array + + +//-------------------------------------------------------------------- + +// frees the storage + +/*N*/ BitSet::~BitSet() +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ delete [] pBitmap; +/*N*/ } + +//-------------------------------------------------------------------- + +// creates a bitmap with all bits in rRange set + + +//-------------------------------------------------------------------- + +// assignment from another bitset + + +//-------------------------------------------------------------------- + +// assignment from a single bit + + +//-------------------------------------------------------------------- + +// creates the asymetric difference with another bitset + +/*N*/ BitSet& BitSet::operator-=(USHORT nBit) +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ USHORT nBlock = nBit / 32; +/*N*/ ULONG nBitVal = 1L << (nBit % 32); +/*N*/ +/*N*/ if ( nBlock >= nBlocks ) +/*N*/ return *this; +/*N*/ +/*N*/ if ( (*(pBitmap+nBlock) & nBitVal) ) +/*N*/ { +/*N*/ *(pBitmap+nBlock) &= ~nBitVal; +/*N*/ --nCount; +/*N*/ } +/*N*/ +/*N*/ return *this; +/*N*/ } + +//-------------------------------------------------------------------- + +// unites with the bits of rSet + +/*N*/ BitSet& BitSet::operator|=( const BitSet& rSet ) +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ USHORT nMax = Min(nBlocks, rSet.nBlocks); +/*N*/ +/*N*/ // expand the bitmap +/*N*/ if ( nBlocks < rSet.nBlocks ) +/*N*/ { +/*N*/ ULONG *pNewMap = new ULONG[rSet.nBlocks]; +/*N*/ memset( pNewMap + nBlocks, 0, 4 * (rSet.nBlocks - nBlocks) ); +/*N*/ +/*N*/ if ( pBitmap ) +/*N*/ { +/*?*/ memcpy( pNewMap, pBitmap, 4 * nBlocks ); +/*?*/ delete [] pBitmap; +/*N*/ } +/*N*/ pBitmap = pNewMap; +/*N*/ nBlocks = rSet.nBlocks; +/*N*/ } +/*N*/ +/*N*/ // add the bits blocks by block +/*N*/ for ( USHORT nBlock = 0; nBlock < nMax; ++nBlock ) +/*N*/ { +/*N*/ // compute numberof additional bits +/*?*/ ULONG nDiff = ~*(pBitmap+nBlock) & *(rSet.pBitmap+nBlock); +/*?*/ nCount += CountBits(nDiff); +/*?*/ +/*?*/ *(pBitmap+nBlock) |= *(rSet.pBitmap+nBlock); +/*N*/ } +/*N*/ +/*N*/ return *this; +/*N*/ } + +//-------------------------------------------------------------------- + +// unites with a single bit + +/*N*/ BitSet& BitSet::operator|=( USHORT nBit ) +/*N*/ { +/*N*/ DBG_MEMTEST(); +/*N*/ USHORT nBlock = nBit / 32; +/*N*/ ULONG nBitVal = 1L << (nBit % 32); +/*N*/ +/*N*/ if ( nBlock >= nBlocks ) +/*N*/ { +/*N*/ ULONG *pNewMap = new ULONG[nBlock+1]; +/*N*/ memset( pNewMap + nBlocks, 0, 4 * (nBlock - nBlocks + 1) ); +/*N*/ +/*N*/ if ( pBitmap ) +/*N*/ { +/*N*/ memcpy( pNewMap, pBitmap, 4 * nBlocks ); +/*N*/ delete [] pBitmap; +/*N*/ } +/*N*/ pBitmap = pNewMap; +/*N*/ nBlocks = nBlock+1; +/*N*/ } +/*N*/ +/*N*/ if ( (*(pBitmap+nBlock) & nBitVal) == 0 ) +/*N*/ { +/*N*/ *(pBitmap+nBlock) |= nBitVal; +/*N*/ ++nCount; +/*N*/ } +/*N*/ +/*N*/ return *this; +/*N*/ } + +// counts the number of 1-bits in the parameter + +/*N*/ USHORT BitSet::CountBits( ULONG nBits ) +/*N*/ { +/*N*/ USHORT nCount = 0; +/*N*/ int nBit = 32; +/*N*/ while ( nBit-- && nBits ) +/*?*/ { if ( ( (long)nBits ) < 0 ) +/*?*/ ++nCount; +/*?*/ nBits = nBits << 1; +/*N*/ } +/*N*/ return nCount; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |