View Javadoc

1   /*
2    * @(#) BitUtil.java Apr 27, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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 }