/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
/* ================================================================
* About NPOI
* Author: Tony Qu
* Author's email: tonyqus (at) gmail.com
* Author's Blog: tonyqus.wordpress.com.cn (wp.tonyqus.cn)
* HomePage: http://www.codeplex.com/npoi
* Contributors:
*
* ==============================================================*/
using System;
using System.Collections.Generic;
using System.Text;
namespace HH.WMS.Utils.NPOI.Util
{
///
/// Manage operations dealing with bit-mapped fields.
/// @author Marc Johnson (mjohnson at apache dot org)
/// @author Andrew C. Oliver (acoliver at apache dot org)
///
[Serializable]
public class BitField
{
private int _mask;
private int _shift_count;
///
/// Create a instance
///
///
/// the mask specifying which bits apply to this
/// BitField. Bits that are set in this mask are the
/// bits that this BitField operates on
///
public BitField(int mask)
{
this._mask = mask;
int num = 0;
int num2 = mask;
if (num2 != 0)
{
while ((num2 & 1) == 0)
{
num++;
num2 = num2 >> 1;
}
}
this._shift_count = num;
}
///
/// Create a instance
///
///
/// the mask specifying which bits apply to this
/// BitField. Bits that are set in this mask are the
/// bits that this BitField operates on
///
public BitField(uint mask):this((int)mask)
{
}
///
/// Clear the bits.
///
/// the int data containing the bits we're interested in
/// the value of holder with the specified bits cleared (set to 0)
public int Clear(int holder)
{
return (holder & ~this._mask);
}
///
/// Clear the bits.
///
/// the short data containing the bits we're interested in
/// the value of holder with the specified bits cleared (set to 0)
public short ClearShort(short holder)
{
return (short)this.Clear(holder);
}
///
/// Obtain the value for the specified BitField, appropriately
/// shifted right. Many users of a BitField will want to treat the
/// specified bits as an int value, and will not want to be aware
/// that the value is stored as a BitField (and so shifted left so
/// many bits)
///
/// the int data containing the bits we're interested in
/// the selected bits, shifted right appropriately
public int GetRawValue(int holder)
{
return (holder & this._mask);
}
///
/// Obtain the value for the specified BitField, unshifted
///
/// the short data containing the bits we're interested in
/// the selected bits
public short GetShortRawValue(short holder)
{
return (short)this.GetRawValue(holder);
}
///
/// Obtain the value for the specified BitField, appropriately
/// shifted right, as a short. Many users of a BitField will want
/// to treat the specified bits as an int value, and will not want
/// to be aware that the value is stored as a BitField (and so
/// shifted left so many bits)
///
/// the short data containing the bits we're interested in
/// the selected bits, shifted right appropriately
public short GetShortValue(short holder)
{
return (short)this.GetValue(holder);
}
///
/// Obtain the value for the specified BitField, appropriately
/// shifted right. Many users of a BitField will want to treat the
/// specified bits as an int value, and will not want to be aware
/// that the value is stored as a BitField (and so shifted left so
/// many bits)
///
/// the int data containing the bits we're interested in
/// the selected bits, shifted right appropriately
public int GetValue(int holder)
{
return Operator.UnsignedRightShift(this.GetRawValue(holder) , this._shift_count);
}
///
/// Are all of the bits set or not? This is a stricter test than
/// isSet, in that all of the bits in a multi-bit set must be set
/// for this method to return true
///
/// the int data containing the bits we're interested in
///
/// true if all of the bits are set otherwise, false.
///
public bool IsAllSet(int holder)
{
return ((holder & this._mask) == this._mask);
}
///
/// is the field set or not? This is most commonly used for a
/// single-bit field, which is often used to represent a boolean
/// value; the results of using it for a multi-bit field is to
/// determine whether *any* of its bits are set
///
/// the int data containing the bits we're interested in
///
/// true if any of the bits are set; otherwise, false.
///
public bool IsSet(int holder)
{
return ((holder & this._mask) != 0);
}
///
/// Set the bits.
///
/// the int data containing the bits we're interested in
/// the value of holder with the specified bits set to 1
public int Set(int holder)
{
return (holder | this._mask);
}
///
/// Set a boolean BitField
///
/// the int data containing the bits we're interested in
/// indicating whether to set or clear the bits
/// the value of holder with the specified bits set or cleared
public int SetBoolean(int holder, bool flag)
{
return (!flag ? this.Clear(holder) : this.Set(holder));
}
///
/// Set the bits.
///
/// the short data containing the bits we're interested in
/// the value of holder with the specified bits set to 1
public short SetShort(short holder)
{
return (short)this.Set(holder);
}
///
/// Set a boolean BitField
///
/// the short data containing the bits we're interested in
/// indicating whether to set or clear the bits
/// the value of holder with the specified bits set or cleared
public short SetShortBoolean(short holder, bool flag)
{
return (!flag ? this.ClearShort(holder) : this.SetShort(holder));
}
///
/// Obtain the value for the specified BitField, appropriately
/// shifted right, as a short. Many users of a BitField will want
/// to treat the specified bits as an int value, and will not want
/// to be aware that the value is stored as a BitField (and so
/// shifted left so many bits)
///
/// the short data containing the bits we're interested in
/// the new value for the specified bits
/// the selected bits, shifted right appropriately
public short SetShortValue(short holder, short value)
{
return (short)this.SetValue(holder, value);
}
///
/// Sets the value.
///
/// the byte data containing the bits we're interested in
/// The value.
///
public int SetValue(int holder, int value)
{
return ((holder & ~this._mask) | ((value << this._shift_count) & this._mask));
}
///
/// Set a boolean BitField
///
/// the byte data containing the bits we're interested in
/// indicating whether to set or clear the bits
/// the value of holder with the specified bits set or cleared
public byte SetByteBoolean(byte holder, bool flag)
{
return (!flag ? this.ClearByte(holder) : this.SetByte(holder));
}
///
/// Clears the bits.
///
/// the byte data containing the bits we're interested in
/// the value of holder with the specified bits cleared
public byte ClearByte(byte holder)
{
return (byte)this.Clear(holder);
}
///
/// Set the bits.
///
/// the byte data containing the bits we're interested in
/// the value of holder with the specified bits set to 1
public byte SetByte(byte holder)
{
return (byte)this.Set(holder);
}
}
}