/* HistoryListSingleton.java
Copyright 2003, Bil Lewis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.lambda.Debugger;
// HistoryList/HistoryList.java
/*
*/
import java.lang.reflect.Field;
public class HistoryListSingleton extends HistoryList {
private static int nCreated = 0;
private static int nUpgraded = 0;
private int time0; // TimeStamp
private Object value0; // Object
public void reset(int time) {
Object currentValue = valueOn(time, false);
time0 = 0;
value0 = currentValue;
}
public boolean compact(int eot) {
time0 = TimeStamp.forward(time0);
if (time0 >= 0) {
if (time0 > eot)
throw new DebuggerException("HLM.compact() failed on " + this +" ["+time0+">"+eot+"] = "+value0);
}
else
time0 = 0;
verify(eot);
return true;
}
public void verify(int eot) {
if (time0 == 0) return;
if (time0 > eot) throw new DebuggerException("HLS.verify() failed on <HLS" + this + " >" + time0);
}
public void setValue(Object obj, String varName, Object value) throws NoSuchFieldException, SecurityException, CompletionException {
if (obj instanceof int[]) {
if (value instanceof Integer) {
value = ShadowInt.createShadowInt(((Integer)value).intValue());
this.value0 = value; // CHANGE THIS CURRENT TIME
return;
}
throw new CompletionException("Wrong type. " + value + " is not an int");
}
if (obj instanceof Object[]) { // Check exact type somehow
this.value0 = value; // CHANGE THIS CURRENT TIME
return;
}
Field f = obj.getClass().getField(varName);
Class fieldClass = f.getType();
if (value instanceof Integer) {
if (fieldClass.equals(int.class)) {
value = new ShadowInt(((Integer)value).intValue());
this.value0 = value; // CHANGE THIS CURRENT TIME
return;
}
else
throw new CompletionException("Wrong type. " + value + " is not a " + fieldClass);
}
if (value instanceof Boolean) {
if (fieldClass.equals(boolean.class)) {
if (((Boolean)value).booleanValue())
value = ShadowBoolean.TRUE;
else
value = ShadowBoolean.FALSE;
this.value0 = value; // CHANGE THIS CURRENT TIME
return;
}
else
throw new CompletionException("Wrong type. " + value + " is not a " + fieldClass);
}
if ( (value != null) && (!Subtype.subtype(value.getClass(), fieldClass)) )
throw new CompletionException("Wrong type. " + value + " is not a " + fieldClass);
this.value0 = value; // CHANGE THIS CURRENT TIME
}
public static int getNCreated() {
return nCreated;
}
public static int getNUpgraded() {
return nUpgraded;
}
public HistoryList dup(int time) {
HistoryListSingleton hls = new HistoryListSingleton(0, valueOn(time, false));
return hls;
}
public TVPair[] getValues() {
TVPair[] values = new TVPair[1];
values[0] = new TVPair(time0, value0);
return(values);
}
public int size() {
if (time0 >= 0)
return 1;
else
return 0;
}
public TimeStamp getTS(int i) {
return(TimeStamp.lookup(time0));
}
public int getTime(int i) {
return(time0);
}
public Object getValue(int i) {
return(value0);
}
public HistoryList upgrade(int time, Object value) {
nUpgraded++;
HistoryList hl = new HistoryListTripleton(this.time0, this.value0, time, value);
return hl;
}
public static void printStatistics() {}
// Constructors
public HistoryListSingleton() {time0 = -1;}
public HistoryListSingleton(int time, Object initialValue) {
nEntries++;
nCreated++;
this.time0 = time;
value0 = initialValue;
}
public HistoryList add(int time, Object o) {
if (size() == 0) {
this.time0 = time;
this.value0 = o;
return null;
}
return upgrade(time, o);
}
public HistoryList add(int time, int i) {
return add(time, ShadowInt.createShadowInt(i));
}
public void print() {
System.out.println("\t" + time0 + " \t" + value0);
}
public String toString(int i) {
return("<HistoryListSingleton " + " " + 1 + ">");
}
public String toString() {
return( "XXY " + valueOn(TimeStamp.currentTime(), false));// Don't i need spaces here?
}
public TimeStamp getFirst() {
if (size() == 0) return null;
TimeStamp ts = TimeStamp.lookup(time0);
return(ts);
}
public TimeStamp getLast() {
if (size() == 0) return null;
TimeStamp ts = TimeStamp.lookup(time0);
return(ts);
}
public Object getLastValue() {
if (size() == 0) return(null); // Never happen?
return(value0);
}
public TimeStamp getPrevious() {
if (size() == 0) return null;
TimeStamp ts1 = TimeStamp.currentTime();
if (ts1 == TimeStamp.bot()) return(null);
TimeStamp timeStamp = TimeStamp.lookup(time0);
if (!timeStamp.laterThan(ts1)) {
TimeStamp prev = timeStamp.getPreviousThisThread();
if (prev == null) return(timeStamp);
return(prev);
}
return(null);
}
public TimeStamp getNext() {
if (size() == 0) return null;
TimeStamp timeStamp = TimeStamp.lookup(time0);
if (timeStamp.laterThan(TimeStamp.currentTime())) {
return(timeStamp);
}
return(null);
}
public Object valueOn(TimeStamp ts, boolean foreign) {
return valueOn(ts.time, foreign);
}
public Object valueOn(int tim, boolean foreign) {
if (size() == 0) return(null);
if (foreign) return(value0); // Let caller know we don't have valid entries for ts
if (TimeStamp.laterThan(time0, tim)) {
return(Dashes.DASHES);
}
return(value0);
}
public void removeLast() {
time0 = -1;
}
public static void main(String[] args) {
System.out.println("----------------------HistoryList----------------------\n");
System.out.println("----------------------HistoryList----------------------\n");
}
}