    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.lang3;
    018
    019    /**
    020     * <p>Operations on bit-mapped fields.</p>
    021     *
    022     * @since 2.0
    023     * @version $Id: BitField.java 1088899 2011-04-05 05:31:27Z bayard $
    024     */
    025    public class BitField {
    026
    027        private final int _mask;
    028        private final int _shift_count;
    029
    030        /**
    031         * <p>Creates a BitField instance.</p>
    032         *
    033         * @param mask the mask specifying which bits apply to this
    034         *  BitField. Bits that are set in this mask are the bits
    035         *  that this BitField operates on
    036         */
    037        public BitField(int mask) {
    038            _mask = mask;
    039            int count = 0;
    040            int bit_pattern = mask;
    041
    042            if (bit_pattern != 0) {
    043                while ((bit_pattern & 1) == 0) {
    044                    count++;
    045                    bit_pattern >>= 1;
    046                }
    047            }
    048            _shift_count = count;
    049        }
    050
    051        /**
    052         * <p>Obtains the value for the specified BitField, appropriately
    053         * shifted right.</p>
    054         *
    055         * <p>Many users of a BitField will want to treat the specified
    056         * bits as an int value, and will not want to be aware that the
    057         * value is stored as a BitField (and so shifted left so many
    058         * bits).</p>
    059         *
    060         * @see #setValue(int,int)
    061         * @param holder the int data containing the bits we're interested
    062         *  in
    063         * @return the selected bits, shifted right appropriately
    064         */
    065        public int getValue(int holder) {
    066            return getRawValue(holder) >> _shift_count;
    067        }
    068
    069        /**
    070         * <p>Obtains the value for the specified BitField, appropriately
    071         * shifted right, as a short.</p>
    072         *
    073         * <p>Many users of a BitField will want to treat the specified
    074         * bits as an int value, and will not want to be aware that the
    075         * value is stored as a BitField (and so shifted left so many
    076         * bits).</p>
    077         *
    078         * @see #setShortValue(short,short)
    079         * @param holder the short data containing the bits we're
    080         *  interested in
    081         * @return the selected bits, shifted right appropriately
    082         */
    083        public short getShortValue(short holder) {
    084            return (short) getValue(holder);
    085        }
    086
    087        /**
    088         * <p>Obtains the value for the specified BitField, unshifted.</p>
    089         *
    090         * @param holder the int data containing the bits we're
    091         *  interested in
    092         * @return the selected bits
    093         */
    094        public int getRawValue(int holder) {
    095            return holder & _mask;
    096        }
    097
    098        /**
    099         * <p>Obtains the value for the specified BitField, unshifted.</p>
    100         *
    101         * @param holder the short data containing the bits we're
    102         *  interested in
    103         * @return the selected bits
    104         */
    105        public short getShortRawValue(short holder) {
    106            return (short) getRawValue(holder);
    107        }
    108
    109        /**
    110         * <p>Returns whether the field is set or not.</p>
    111         *
    112         * <p>This is most commonly used for a single-bit field, which is
    113         * often used to represent a boolean value; the results of using
    114         * it for a multi-bit field is to determine whether *any* of its
    115         * bits are set.</p>
    116         *
    117         * @param holder the int data containing the bits we're interested
    118         *  in
    119         * @return {@code true} if any of the bits are set,
    120         *  else {@code false}
    121         */
    122        public boolean isSet(int holder) {
    123            return (holder & _mask) != 0;
    124        }
    125
    126        /**
    127         * <p>Returns whether all of the bits are set or not.</p>
    128         *
    129         * <p>This is a stricter test than {@link #isSet(int)},
    130         * in that all of the bits in a multi-bit set must be set
    131         * for this method to return {@code true}.</p>
    132         *
    133         * @param holder the int data containing the bits we're
    134         *  interested in
    135         * @return {@code true} if all of the bits are set,
    136         *  else {@code false}
    137         */
    138        public boolean isAllSet(int holder) {
    139            return (holder & _mask) == _mask;
    140        }
    141
    142        /**
    143         * <p>Replaces the bits with new values.</p>
    144         *
    145         * @see #getValue(int)
    146         * @param holder the int data containing the bits we're
    147         *  interested in
    148         * @param value the new value for the specified bits
    149         * @return the value of holder with the bits from the value
    150         *  parameter replacing the old bits
    151         */
    152        public int setValue(int holder, int value) {
    153            return (holder & ~_mask) | ((value << _shift_count) & _mask);
    154        }
    155
    156        /**
    157         * <p>Replaces the bits with new values.</p>
    158         *
    159         * @see #getShortValue(short)
    160         * @param holder the short data containing the bits we're
    161         *  interested in
    162         * @param value the new value for the specified bits
    163         * @return the value of holder with the bits from the value
    164         *  parameter replacing the old bits
    165         */
    166        public short setShortValue(short holder, short value) {
    167            return (short) setValue(holder, value);
    168        }
    169
    170        /**
    171         * <p>Clears the bits.</p>
    172         *
    173         * @param holder the int data containing the bits we're
    174         *  interested in
    175         * @return the value of holder with the specified bits cleared
    176         *  (set to {@code 0})
    177         */
    178        public int clear(int holder) {
    179            return holder & ~_mask;
    180        }
    181
    182        /**
    183         * <p>Clears the bits.</p>
    184         *
    185         * @param holder the short data containing the bits we're
    186         *  interested in
    187         * @return the value of holder with the specified bits cleared
    188         *  (set to {@code 0})
    189         */
    190        public short clearShort(short holder) {
    191            return (short) clear(holder);
    192        }
    193
    194        /**
    195         * <p>Clears the bits.</p>
    196         *
    197         * @param holder the byte data containing the bits we're
    198         *  interested in
    199         *
    200         * @return the value of holder with the specified bits cleared
    201         *  (set to {@code 0})
    202         */
    203        public byte clearByte(byte holder) {
    204            return (byte) clear(holder);
    205        }
    206
    207        /**
    208         * <p>Sets the bits.</p>
    209         *
    210         * @param holder the int data containing the bits we're
    211         *  interested in
    212         * @return the value of holder with the specified bits set
    213         *  to {@code 1}
    214         */
    215        public int set(int holder) {
    216            return holder | _mask;
    217        }
    218
    219        /**
    220         * <p>Sets the bits.</p>
    221         *
    222         * @param holder the short data containing the bits we're
    223         *  interested in
    224         * @return the value of holder with the specified bits set
    225         *  to {@code 1}
    226         */
    227        public short setShort(short holder) {
    228            return (short) set(holder);
    229        }
    230
    231        /**
    232         * <p>Sets the bits.</p>
    233         *
    234         * @param holder the byte data containing the bits we're
    235         *  interested in
    236         *
    237         * @return the value of holder with the specified bits set
    238         *  to {@code 1}
    239         */
    240        public byte setByte(byte holder) {
    241            return (byte) set(holder);
    242        }
    243
    244        /**
    245         * <p>Sets a boolean BitField.</p>
    246         *
    247         * @param holder the int data containing the bits we're
    248         *  interested in
    249         * @param flag indicating whether to set or clear the bits
    250         * @return the value of holder with the specified bits set or
    251         *         cleared
    252         */
    253        public int setBoolean(int holder, boolean flag) {
    254            return flag ? set(holder) : clear(holder);
    255        }
    256
    257        /**
    258         * <p>Sets a boolean BitField.</p>
    259         *
    260         * @param holder the short data containing the bits we're
    261         *  interested in
    262         * @param flag indicating whether to set or clear the bits
    263         * @return the value of holder with the specified bits set or
    264         *  cleared
    265         */
    266        public short setShortBoolean(short holder, boolean flag) {
    267            return flag ? setShort(holder) : clearShort(holder);
    268        }
    269
    270        /**
    271         * <p>Sets a boolean BitField.</p>
    272         *
    273         * @param holder the byte data containing the bits we're
    274         *  interested in
    275         * @param flag indicating whether to set or clear the bits
    276         * @return the value of holder with the specified bits set or
    277         *  cleared
    278         */
    279        public byte setByteBoolean(byte holder, boolean flag) {
    280            return flag ? setByte(holder) : clearByte(holder);
    281        }
    282
    283    }