Skip to content

Commit f2bdb0c

Browse files
authored
Add long support to BitField (#1561)
* Add testLang1641() * Rename some test methods * Add long support to BitField * Remove unnecessary blank line in BitFieldTest * Fix missing newline at end of file Add missing newline at the end of BitFieldLongTest.java * Fix return value * Use final * Add more tests
1 parent d68bf97 commit f2bdb0c

File tree

3 files changed

+449
-95
lines changed

3 files changed

+449
-95
lines changed

src/main/java/org/apache/commons/lang3/BitField.java

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
*/
7373
public class BitField {
7474

75-
private final int mask;
75+
private final long mask;
7676

7777
private final int shiftCount;
7878

@@ -86,13 +86,35 @@ public BitField(final int mask) {
8686
this.shiftCount = mask == 0 ? 0 : Integer.numberOfTrailingZeros(mask);
8787
}
8888

89+
/**
90+
* Creates a BitField instance.
91+
*
92+
* @param mask the mask specifying which bits apply to this BitField. Bits that are set in this mask are the bits that this BitField operates on.
93+
* @since 3.21.0
94+
*/
95+
public BitField(final long mask) {
96+
this.mask = mask;
97+
this.shiftCount = mask == 0 ? 0 : Long.numberOfTrailingZeros(mask);
98+
}
99+
89100
/**
90101
* Clears the bits.
91102
*
92103
* @param holder the int data containing the bits we're interested in.
93104
* @return the value of holder with the specified bits cleared (set to {@code 0}).
94105
*/
95106
public int clear(final int holder) {
107+
return (int) (holder & ~mask);
108+
}
109+
110+
/**
111+
* Clears the bits.
112+
*
113+
* @param holder the long data containing the bits we're interested in.
114+
* @return the value of holder with the specified bits cleared (set to {@code 0}).
115+
* @since 3.21.0
116+
*/
117+
public long clear(final long holder) {
96118
return holder & ~mask;
97119
}
98120

@@ -123,6 +145,17 @@ public short clearShort(final short holder) {
123145
* @return the selected bits.
124146
*/
125147
public int getRawValue(final int holder) {
148+
return (int) (holder & mask);
149+
}
150+
151+
/**
152+
* Gets the value for the specified BitField, unshifted.
153+
*
154+
* @param holder the long data containing the bits we're interested in.
155+
* @return the selected bits.
156+
* @since 3.21.0
157+
*/
158+
public long getRawValue(final long holder) {
126159
return holder & mask;
127160
}
128161

@@ -166,6 +199,22 @@ public int getValue(final int holder) {
166199
return getRawValue(holder) >> shiftCount;
167200
}
168201

202+
/**
203+
* Gets the value for the specified BitField, appropriately shifted right.
204+
* <p>
205+
* Many users of a BitField will want to treat the specified bits as an long value, and will not want to be aware that the value is stored as a BitField (and
206+
* so shifted left so many bits).
207+
* </p>
208+
*
209+
* @param holder the long data containing the bits we're interested in.
210+
* @return the selected bits, shifted right appropriately.
211+
* @see #setValue(long,long)
212+
* @since 3.21.0
213+
*/
214+
public long getValue(final long holder) {
215+
return getRawValue(holder) >> shiftCount;
216+
}
217+
169218
/**
170219
* Tests whether all of the bits are set or not.
171220
* <p>
@@ -179,11 +228,25 @@ public boolean isAllSet(final int holder) {
179228
return (holder & mask) == mask;
180229
}
181230

231+
/**
232+
* Tests whether all of the bits are set or not.
233+
* <p>
234+
* This is a stricter test than {@link #isSet(long)}, in that all of the bits in a multi-bit set must be set for this method to return {@code true}.
235+
* </p>
236+
*
237+
* @param holder the long data containing the bits we're interested in.
238+
* @return {@code true} if all of the bits are set, else {@code false}.
239+
* @since 3.21.0
240+
*/
241+
public boolean isAllSet(final long holder) {
242+
return (holder & mask) == mask;
243+
}
244+
182245
/**
183246
* Tests whether the field is set or not.
184247
* <p>
185248
* 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
186-
* determine whether *any* of its bits are set.
249+
* determine whether <em>any</em> of its bits are set.
187250
* </p>
188251
*
189252
* @param holder the int data containing the bits we're interested in
@@ -193,13 +256,39 @@ public boolean isSet(final int holder) {
193256
return (holder & mask) != 0;
194257
}
195258

259+
/**
260+
* Tests whether the field is set or not.
261+
* <p>
262+
* 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
263+
* determine whether <em>any</em> of its bits are set.
264+
* </p>
265+
*
266+
* @param holder the long data containing the bits we're interested in
267+
* @return {@code true} if any of the bits are set, else {@code false}
268+
* @since 3.21.0
269+
*/
270+
public boolean isSet(final long holder) {
271+
return (holder & mask) != 0;
272+
}
273+
196274
/**
197275
* Sets the bits.
198276
*
199277
* @param holder the int data containing the bits we're interested in.
200278
* @return the value of holder with the specified bits set to {@code 1}.
201279
*/
202280
public int set(final int holder) {
281+
return (int) (holder | mask);
282+
}
283+
284+
/**
285+
* Sets the bits.
286+
*
287+
* @param holder the long data containing the bits we're interested in.
288+
* @return the value of holder with the specified bits set to {@code 1}.
289+
* @since 3.21.0
290+
*/
291+
public long set(final long holder) {
203292
return holder | mask;
204293
}
205294

@@ -214,6 +303,18 @@ public int setBoolean(final int holder, final boolean flag) {
214303
return flag ? set(holder) : clear(holder);
215304
}
216305

306+
/**
307+
* Sets a boolean BitField.
308+
*
309+
* @param holder the long data containing the bits we're interested in.
310+
* @param flag indicating whether to set or clear the bits.
311+
* @return the value of holder with the specified bits set or cleared.
312+
* @since 3.21.0
313+
*/
314+
public long setBoolean(final long holder, final boolean flag) {
315+
return flag ? set(holder) : clear(holder);
316+
}
317+
217318
/**
218319
* Sets the bits.
219320
*
@@ -277,6 +378,19 @@ public short setShortValue(final short holder, final short value) {
277378
* @see #getValue(int)
278379
*/
279380
public int setValue(final int holder, final int value) {
381+
return (int) (holder & ~mask | value << shiftCount & mask);
382+
}
383+
384+
/**
385+
* Sets the bits with new values.
386+
*
387+
* @param holder the long data containing the bits we're interested in.
388+
* @param value the new value for the specified bits.
389+
* @return the value of holder with the bits from the value parameter replacing the old bits.
390+
* @see #getValue(long)
391+
* @since 3.21.0
392+
*/
393+
public long setValue(final long holder, final long value) {
280394
return holder & ~mask | value << shiftCount & mask;
281395
}
282396
}

0 commit comments

Comments
 (0)