1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.language.util;
11
12 import java.io.Serializable;
13 import java.math.BigInteger;
14 import java.util.BitSet;
15
16 /***
17 * Utilities for the bitset class.
18 * <p>
19 * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
20 * University of Technology </a>, the Netherlands. <br>
21 * See for project information <a
22 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
23 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
24 * License (GPL) </a>, no warranty <br>
25 *
26 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
27 * Jacobs </a>
28 * @version 1.2 Apr 27, 2004
29 * @since 1.4
30 */
31 public final class BitUtil implements Serializable
32 {
33 /***
34 * constructs a new BitUtil
35 */
36 private BitUtil()
37 {
38 super();
39 }
40
41 /***
42 * @param bits the bitset to convert
43 * @return Returns a byte array of at least length 1. The most significant
44 * bit in the result is guaranteed not to be a 1 (since BitSet does
45 * not support sign extension). The byte-ordering of the result is
46 * big-endian which means the most significant bit is in element 0.
47 * The bit at index 0 of the bit set is assumed to be the least
48 * significant bit.
49 */
50 public static byte[] toByteArray(final BitSet bits)
51 {
52 synchronized (bits)
53 {
54 byte[] bytes = new byte[bits.length() / 8 + 1];
55 for (int i = 0; i < bits.length(); i++)
56 {
57 if (bits.get(i))
58 {
59 bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8);
60 }
61 }
62 return bytes;
63 }
64 }
65
66 /***
67 * @param bits the bitset to convert
68 * @param length the length of the set
69 * @return Returns an int. The most significant bit in the result is
70 * guaranteed not to be a 1 (since BitSet does not support sign
71 * extension). The int-ordering of the result is big-endian which
72 * means the most significant bit is in element 0. The bit at index
73 * 0 of the bit set is assumed to be the least significant bit.
74 */
75 public static int toInt(final BitSet bits, final int length)
76 {
77 byte[] bytes = BitUtil.toByteArray(bits);
78 int value = new BigInteger(bytes).intValue();
79 if (value > Math.pow(2, length - 1) && length != -1)
80 {
81 value = value - (int) Math.pow(2, length);
82 }
83 return value;
84 }
85
86 /***
87 * constructs a new BitSet from a string in the "110110" format.
88 *
89 * @param value the value
90 * @return the BitSet
91 */
92 public static BitSet fromString(String value)
93 {
94 if (!value.startsWith("{"))
95 {
96 BitSet set = new BitSet(value.length());
97 for (int i = 0; i < value.length(); i++)
98 {
99 if (value.charAt(i) == '1')
100 {
101 set.set(i, true);
102 } else if (value.charAt(i) == '0')
103 {
104 set.set(i, false);
105 } else
106 {
107 throw new IllegalArgumentException(
108 "value should only contain ones and zeros. Try 110011");
109 }
110 }
111 return set;
112 }
113 BitSet set = new BitSet();
114 value = value.substring(1, value.length() - 1);
115 if (value.equals(""))
116 {
117 return set;
118 }
119 String[] bits = value.split(",");
120 for (int i = 0; i < bits.length; i++)
121 {
122 bits[i] = bits[i].trim();
123 set.set(Integer.valueOf(bits[i]).intValue());
124 }
125 return set;
126 }
127
128 /***
129 * @param bytes the byteArray
130 * @return Returns a bitset containing the values in bytes.The byte-ordering
131 * of bytes must be big-endian which means the most significant bit
132 * is in element 0.
133 */
134 public static BitSet fromByteArray(final byte[] bytes)
135 {
136 BitSet bits = new BitSet();
137 for (int i = 0; i < bytes.length * 8; i++)
138 {
139 if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0)
140 {
141 bits.set(i);
142 }
143 }
144 return bits;
145 }
146
147 /***
148 * returns the bitset of an integer value
149 *
150 * @param value the value
151 * @param length the length of the bitSet to produce
152 * @return the BitSet
153 */
154 public static BitSet fromInt(final int value, final int length)
155 {
156 return BitUtil.fromInteger(new Integer(value), length);
157 }
158
159 /***
160 * returns the bitset of an integer value
161 *
162 * @param value the value
163 * @param length the length of
164 * @return the BitSet
165 */
166 public static BitSet fromInteger(Integer value, final int length)
167 {
168 if (value.intValue() < 0 && length != -1)
169 {
170 value = new Integer((int) Math.pow(2, length) + value.intValue());
171 }
172 return BitUtil.fromByteArray(new BigInteger(value.toString())
173 .toByteArray());
174 }
175
176 /***
177 * returns a one-size BitSet with value
178 *
179 * @param value the value of the bitSet
180 * @return the BitSet
181 */
182 public static BitSet fromBoolean(final boolean value)
183 {
184 BitSet result = new BitSet(1);
185 result.set(0, value);
186 return result;
187 }
188 }