001: /*
002: * Copyright 2004 Brian S O'Neill
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.cojen.classfile;
018:
019: /**
020: * A specialized, faster BitSet used by InstructionList.
021: *
022: * @author Brian S O'Neill
023: */
024: final class BitList implements Cloneable {
025: // Bits are stored little endian.
026: private int[] mData;
027:
028: /**
029: * @param capacity initial amount of bits to store
030: */
031: public BitList(int capacity) {
032: mData = new int[(capacity + 31) >> 5];
033: }
034:
035: public boolean get(int index) {
036: return (mData[index >> 5] & (0x80000000 >>> index)) != 0;
037: }
038:
039: /**
040: * @return true if any change made
041: */
042: public boolean set(int index) {
043: int i = index >> 5;
044: int v = mData[i];
045: return v != (mData[i] = v | (0x80000000 >>> index));
046: }
047:
048: /**
049: * @return true if any changes made
050: */
051: public boolean or(BitList list) {
052: boolean changes = ensureCapacity(list.capacity());
053: for (int i = list.mData.length; --i >= 0;) {
054: int v = mData[i];
055: changes |= (v != (mData[i] = v | list.mData[i]));
056: }
057: return changes;
058: }
059:
060: public boolean isAllClear() {
061: for (int i = mData.length; --i >= 0;) {
062: if (mData[i] != 0) {
063: return false;
064: }
065: }
066: return true;
067: }
068:
069: public boolean isAllSet() {
070: for (int i = mData.length; --i >= 0;) {
071: if (mData[i] != 0xffffffff) {
072: return false;
073: }
074: }
075: return true;
076: }
077:
078: /**
079: * @return true if the bitwise or of the two lists is different than the
080: * bitwise xor.
081: */
082: public boolean intersects(BitList list) {
083: if (list != null) {
084: for (int i = Math.min(mData.length, list.mData.length); --i >= 0;) {
085: int v1 = mData[i];
086: int v2 = list.mData[i];
087: if ((v1 | v2) != (v1 ^ v2)) {
088: return true;
089: }
090: }
091: }
092: return false;
093: }
094:
095: public int hashCode() {
096: int hash = 0;
097: for (int i = mData.length; --i >= 0;) {
098: hash = hash * 31 + mData[i];
099: }
100: return hash;
101: }
102:
103: public int capacity() {
104: return mData.length << 5;
105: }
106:
107: public boolean equals(Object obj) {
108: if (obj instanceof BitList) {
109: return java.util.Arrays
110: .equals(mData, ((BitList) obj).mData);
111: }
112: return false;
113: }
114:
115: public BitList copy() {
116: return (BitList) clone();
117: }
118:
119: public Object clone() {
120: try {
121: return super .clone();
122: } catch (CloneNotSupportedException e) {
123: throw new InternalError();
124: }
125: }
126:
127: public String toString() {
128: StringBuffer buf = new StringBuffer(mData.length + 2);
129: buf.append('[');
130: for (int i = 0; i < mData.length; i++) {
131: String binary = Integer.toBinaryString(mData[i]);
132: for (int j = binary.length(); j < 32; j++) {
133: buf.append('0');
134: }
135: buf.append(binary);
136: }
137: buf.append(']');
138: return buf.toString();
139: }
140:
141: private boolean ensureCapacity(int capacity) {
142: int len = (capacity + 31) >> 5;
143: if (len > mData.length) {
144: int[] newData = new int[len];
145: System.arraycopy(mData, 0, newData, 0, mData.length);
146: mData = newData;
147: return true;
148: }
149: return false;
150: }
151: }
|