View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import org.junit.jupiter.api.Test;
26  
27  /**
28   * Tests {@link BitField} constructed with long masks.
29   */
30  class BitFieldLongTest extends AbstractLangTest {
31  
32      private static final BitField BF_MULTI  = new BitField(0x3F80L);
33      private static final BitField BF_MULTI_L  = new BitField(0x3F80_0000_0000_0000L);
34      private static final BitField BF_SINGLE = new BitField(0x4000L);
35      private static final BitField BF_SINGLE_L = new BitField(0x4000_0000_0000_0000L);
36      private static final BitField BF_ZERO = new BitField(0L);
37      private static final BitField BF_ZERO_L = new BitField(0L);
38  
39      @Test
40      void testByteBoolean() {
41          assertEquals(0, new BitField(0L).setByteBoolean((byte) 0, true));
42          assertEquals(1, new BitField(1L).setByteBoolean((byte) 0, true));
43          assertEquals(2, new BitField(2L).setByteBoolean((byte) 0, true));
44          assertEquals(4, new BitField(4L).setByteBoolean((byte) 0, true));
45          assertEquals(8, new BitField(8L).setByteBoolean((byte) 0, true));
46          assertEquals(16, new BitField(16L).setByteBoolean((byte) 0, true));
47          assertEquals(32, new BitField(32L).setByteBoolean((byte) 0, true));
48          assertEquals(64, new BitField(64L).setByteBoolean((byte) 0, true));
49          assertEquals(-128, new BitField(128L).setByteBoolean((byte) 0, true));
50          assertEquals(1, new BitField(0L).setByteBoolean((byte) 1, false));
51          assertEquals(0, new BitField(1L).setByteBoolean((byte) 1, false));
52          assertEquals(0, new BitField(2L).setByteBoolean((byte) 2, false));
53          assertEquals(0, new BitField(4L).setByteBoolean((byte) 4, false));
54          assertEquals(0, new BitField(8L).setByteBoolean((byte) 8, false));
55          assertEquals(0, new BitField(16L).setByteBoolean((byte) 16, false));
56          assertEquals(0, new BitField(32L).setByteBoolean((byte) 32, false));
57          assertEquals(0, new BitField(64L).setByteBoolean((byte) 64, false));
58          assertEquals(0, new BitField(128L).setByteBoolean((byte) 128, false));
59          assertEquals(-2, new BitField(1L).setByteBoolean((byte) 255, false));
60          final byte clearedBit = new BitField(0x40L).setByteBoolean((byte) - 63, false);
61          assertFalse(new BitField(0x40).isSet(clearedBit));
62      }
63  
64      /**
65       * Tests the {@link BitField#clear()} method.
66       */
67      @Test
68      void testClearInt() {
69          assertEquals(BF_MULTI.clear(-1), 0xFFFF_C07F);
70          assertEquals(BF_SINGLE.clear(-1), 0xFFFF_BFFF);
71          assertEquals(BF_ZERO.clear(-1), 0xFFFF_FFFF);
72          // Above-bit-31 masks fail loudly on int holders instead of silently no-op'ing (see BitField#intMask()).
73          assertThrows(IllegalStateException.class, () -> BF_MULTI_L.clear(-1));
74          assertThrows(IllegalStateException.class, () -> BF_SINGLE_L.clear(-1));
75          assertEquals(BF_ZERO_L.clear(-1), 0xFFFF_FFFF);
76      }
77  
78      /**
79       * Tests the {@link BitField#clear()} method.
80       */
81      @Test
82      void testClearLong() {
83          assertEquals(BF_MULTI.clear(-1L), 0xFFFF_FFFF_FFFF_C07FL);
84          assertEquals(BF_SINGLE.clear(-1L), 0xFFFF_FFFF_FFFF_BFFFL);
85          assertEquals(BF_ZERO.clear(-1L), 0xFFFF_FFFF);
86          assertEquals(BF_MULTI_L.clear(-1L), 0xC07F_FFFF_FFFF_FFFFL);
87          assertEquals(BF_SINGLE_L.clear(-1L), 0xBFFF_FFFF_FFFF_FFFFL);
88          assertEquals(BF_ZERO_L.clear(-1L), 0xFFFF_FFFF_FFFF_FFFFL);
89      }
90  
91      /**
92       * Tests the {@link BitField#clearShort()} method.
93       */
94      @Test
95      void testClearShort() {
96          assertEquals(BF_MULTI.clearShort((short) - 1), (short) 0xC07F);
97          assertEquals(BF_SINGLE.clearShort((short) - 1), (short) 0xBFFF);
98          assertEquals(BF_ZERO.clearShort((short) -1), (short) 0xFFFF);
99          // Above-bit-31 masks fail loudly on short holders instead of silently no-op'ing (see BitField#intMask()).
100         assertThrows(IllegalStateException.class, () -> BF_MULTI_L.clearShort((short) -1));
101         assertThrows(IllegalStateException.class, () -> BF_SINGLE_L.clearShort((short) -1));
102         assertEquals(BF_ZERO_L.clearShort((short) -1), (short) 0xFFFF);
103     }
104 
105     @Test
106     void testEdgeCases() {
107         final BitField field = new BitField(0x1L); // bit 0
108         assertEquals(1L, field.set(0L));
109         assertEquals(0L, field.clear(1L));
110         final BitField highField = new BitField(0x8000_0000_0000_0000L); // highest bit
111         assertEquals(0x8000_0000_0000_0000L, highField.set(0L));
112         assertEquals(0L, highField.clear(0x8000_0000_0000_0000L));
113     }
114 
115     /**
116      * Tests the {@link BitField#getRawValue()} method.
117      */
118     @Test
119     void testGetRawValue() {
120         // mask < max int and int input
121         assertEquals(BF_MULTI.getRawValue(-1), 0x3F80);
122         assertEquals(BF_MULTI.getRawValue(0), 0);
123         assertEquals(BF_SINGLE.getRawValue(-1), 0x4000);
124         assertEquals(BF_SINGLE.getRawValue(0), 0);
125         assertEquals(BF_ZERO.getRawValue(-1), 0);
126         assertEquals(BF_ZERO.getRawValue(0), 0);
127         // mask > max int and int input: fails loudly (the old silent 0 was incoherent with the
128         // sign-extended answers the same mixture produced in isSet/isAllSet).
129         assertThrows(IllegalStateException.class, () -> BF_MULTI_L.getRawValue(-1));
130         assertThrows(IllegalStateException.class, () -> BF_MULTI_L.getRawValue(0));
131         assertThrows(IllegalStateException.class, () -> BF_SINGLE_L.getRawValue(-1));
132         assertThrows(IllegalStateException.class, () -> BF_SINGLE_L.getRawValue(0));
133         assertEquals(BF_ZERO_L.getRawValue(-1), 0);
134         assertEquals(BF_ZERO_L.getRawValue(0), 0);
135         // mask > max int and long input
136         assertEquals(BF_MULTI_L.getRawValue(-1L), 0x3F80_0000_0000_0000L);
137         assertEquals(BF_MULTI_L.getRawValue(0L), 0);
138         assertEquals(BF_SINGLE_L.getRawValue(-1L), 0x4000_0000_0000_0000L);
139         assertEquals(BF_SINGLE_L.getRawValue(0L), 0);
140         assertEquals(BF_ZERO_L.getRawValue(-1L), 0);
141         assertEquals(BF_ZERO_L.getRawValue(0L), 0);
142     }
143 
144     /**
145      * Tests the {@link BitField#getShortRawValue()} method.
146      */
147     @Test
148     void testGetShortRawValue() {
149         // mask < max int and short input
150         assertEquals(BF_MULTI.getShortRawValue((short) - 1), (short) 0x3F80);
151         assertEquals(BF_MULTI.getShortRawValue((short) 0), (short) 0);
152         assertEquals(BF_SINGLE.getShortRawValue((short) - 1), (short) 0x4000);
153         assertEquals(BF_SINGLE.getShortRawValue((short) 0), (short) 0);
154         assertEquals(BF_ZERO.getShortRawValue((short) -1), (short) 0);
155         assertEquals(BF_ZERO.getShortRawValue((short) 0), (short) 0);
156         // mask > max int and short input: fails loudly (see testGetRawValue).
157         assertThrows(IllegalStateException.class, () -> BF_MULTI_L.getShortRawValue((short) -1));
158         assertThrows(IllegalStateException.class, () -> BF_MULTI_L.getShortRawValue((short) 0));
159         assertThrows(IllegalStateException.class, () -> BF_SINGLE_L.getShortRawValue((short) -1));
160         assertThrows(IllegalStateException.class, () -> BF_SINGLE_L.getShortRawValue((short) 0));
161         assertEquals(BF_ZERO_L.getShortRawValue((short) -1), (short) 0);
162         assertEquals(BF_ZERO_L.getShortRawValue((short) 0), (short) 0);
163     }
164 
165     /**
166      * Tests the getRawValue() and getValue() methods
167      */
168     @Test
169     void testGetValueAndRawValueIntRange() {
170         final BitField field = new BitField(0xFF00L); // bits 8-15
171         final long holder = 0x1234L;
172         // raw value: bits & mask
173         assertEquals(0x1200L, field.getRawValue(holder));
174         // shifted value: shifted right to LSB
175         assertEquals(0x12L, field.getValue(holder));
176     }
177 
178     /**
179      * Tests the isSet() and isAllSet() methods
180      */
181     @Test
182     void testIsSetAndIsAllSet() {
183         final BitField field1 = new BitField(0x3000L); // bits 12-13
184         final long holder = 0x3000L;
185         assertTrue(field1.isSet(holder));
186         assertTrue(field1.isAllSet(holder));
187         final long holderPartial = 0x1000L;
188         assertTrue(field1.isSet(holderPartial));
189         assertFalse(field1.isAllSet(holderPartial));
190     }
191 
192     @Test
193     void testMultipleBits() {
194         final BitField field = new BitField(0xF0F0L); // multiple bits
195         final long holder = 0xAAAA;
196         final long newValue = 0x55;
197         final long result = field.setValue(holder, newValue);
198         assertEquals(holder & ~0xF0F0L | newValue << 4 & 0xF0F0L, result);
199     }
200 
201     /**
202      * Tests the set() method
203      */
204     @Test
205     void testSet() {
206         final BitField field = new BitField(0x1000L); // bit 12
207         final long holder = 0x0000L;
208         final long result = field.set(holder);
209         assertEquals(0x1000L, result);
210     }
211 
212     /**
213      * Tests the setBoolean() method
214      */
215     @Test
216     void testSetBoolean() {
217         final BitField field = new BitField(0x1000L); // bit 12
218         final long holder = 0x0000L;
219         final long setTrue = field.setBoolean(holder, true);
220         assertEquals(0x1000L, setTrue);
221         final long setFalse = field.setBoolean(setTrue, false);
222         assertEquals(0x0000L, setFalse);
223     }
224 
225     /**
226      * Tests the setValue() method
227      */
228     @Test
229     void testSetValue() {
230         final BitField field = new BitField(0xFF00L); // bits 8-15
231         final long holder = 0x1200L;
232         final long result = field.setValue(holder, 0x34L); // replace bits 8-15 with 0x34
233         assertEquals(0x3400L, result);
234     }
235 }