001: /*
002: * AbstractBitVector.java
003: *
004: * Copyright (C) 2004 Peter Graves
005: * $Id: AbstractBitVector.java,v 1.7 2004/05/16 14:01:57 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: public abstract class AbstractBitVector extends AbstractVector {
025: protected static final int LONG_MASK = 0x3f;
026:
027: protected int capacity;
028:
029: // For non-displaced bit-vectors.
030: protected long[] bits;
031:
032: public LispObject typep(LispObject type) throws ConditionThrowable {
033: if (type == Symbol.BIT_VECTOR)
034: return T;
035: if (type == BuiltInClass.BIT_VECTOR)
036: return T;
037: return super .typep(type);
038: }
039:
040: public LispClass classOf() {
041: return BuiltInClass.BIT_VECTOR;
042: }
043:
044: public final LispObject BIT_VECTOR_P() {
045: return T;
046: }
047:
048: public final int capacity() {
049: return capacity;
050: }
051:
052: public final LispObject getElementType() {
053: return Symbol.BIT;
054: }
055:
056: public boolean equal(LispObject obj) throws ConditionThrowable {
057: if (this == obj)
058: return true;
059: if (obj instanceof AbstractBitVector) {
060: AbstractBitVector v = (AbstractBitVector) obj;
061: if (length() != v.length())
062: return false;
063: for (int i = length(); i-- > 0;) {
064: if (getBit(i) != v.getBit(i))
065: return false;
066: }
067: return true;
068: }
069: return false;
070: }
071:
072: public boolean equalp(LispObject obj) throws ConditionThrowable {
073: if (this == obj)
074: return true;
075: if (obj instanceof AbstractBitVector) {
076: AbstractBitVector v = (AbstractBitVector) obj;
077: if (length() != v.length())
078: return false;
079: for (int i = length(); i-- > 0;) {
080: if (getBit(i) != v.getBit(i))
081: return false;
082: }
083: return true;
084: }
085: if (obj instanceof AbstractVector)
086: return ((AbstractVector) obj).equalp(this );
087: return false;
088: }
089:
090: public void fill(LispObject obj) throws ConditionThrowable {
091: try {
092: switch (((Fixnum) obj).value) {
093: case 0:
094: if (bits != null) {
095: for (int i = bits.length; i-- > 0;)
096: bits[i] = 0;
097: } else {
098: for (int i = capacity; i-- > 0;)
099: clearBit(i);
100: }
101: return;
102: case 1:
103: if (bits != null) {
104: for (int i = bits.length; i-- > 0;)
105: bits[i] = -1L;
106: } else {
107: for (int i = capacity; i-- > 0;)
108: setBit(i);
109: }
110: return;
111: }
112: } catch (ClassCastException e) {
113: // Fall through...
114: }
115: signal(new TypeError(obj, Symbol.BIT));
116: }
117:
118: public LispObject subseq(int start, int end)
119: throws ConditionThrowable {
120: SimpleBitVector v = new SimpleBitVector(end - start);
121: int i = start, j = 0;
122: try {
123: while (i < end) {
124: if (getBit(i++) == 0)
125: v.clearBit(j++);
126: else
127: v.setBit(j++);
128: }
129: return v;
130: } catch (ArrayIndexOutOfBoundsException e) {
131: return signal(new TypeError("Array index out of bounds: "
132: + i + "."));
133: }
134: }
135:
136: public int hashCode() {
137: int hashCode = 1;
138: try {
139: // Consider first 64 bits only.
140: final int limit = Math.min(length(), 64);
141: for (int i = 0; i < limit; i++)
142: hashCode = hashCode * 31 + getBit(i);
143: } catch (ConditionThrowable t) {
144: // Shouldn't happen.
145: Debug.trace(t);
146: }
147: return hashCode;
148: }
149:
150: public String writeToString() throws ConditionThrowable {
151: final int limit = length();
152: StringBuffer sb = new StringBuffer(limit + 2);
153: sb.append("#*");
154: for (int i = 0; i < limit; i++)
155: sb.append(getBit(i) == 1 ? '1' : '0');
156: return sb.toString();
157: }
158:
159: // Ignores fill pointer.
160: public LispObject AREF(LispObject index) throws ConditionThrowable {
161: try {
162: return getRowMajor(((Fixnum) index).value);
163: } catch (ClassCastException e) {
164: return signal(new TypeError(index, Symbol.FIXNUM));
165: }
166: }
167:
168: public LispObject reverse() throws ConditionThrowable {
169: int length = length();
170: SimpleBitVector result = new SimpleBitVector(length);
171: int i, j;
172: for (i = 0, j = length - 1; i < length; i++, j--) {
173: if (getBit(j) == 1)
174: result.setBit(i);
175: else
176: result.clearBit(i);
177: }
178: return result;
179: }
180:
181: protected abstract int getBit(int index) throws ConditionThrowable;
182:
183: protected abstract void setBit(int index) throws ConditionThrowable;
184:
185: protected abstract void clearBit(int index)
186: throws ConditionThrowable;
187: }
|