mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-09-13 21:56:19 +00:00
GP-2558 PropertyMap templatize and cleanup. ProgramMerge bug/cleanup
related to User Properties. Program Diff bug fix for multiple labels at same address.
This commit is contained in:
parent
45165ea167
commit
c5c651a053
|
@ -65,12 +65,12 @@ public class DefaultPcodeDebuggerPropertyAccess<T>
|
|||
}
|
||||
|
||||
// NB. This is stored in the program, not the user data, despite what the name implies
|
||||
PropertyMap map =
|
||||
PropertyMap<?> map =
|
||||
progLoc.getProgram().getUsrPropertyManager().getPropertyMap(name);
|
||||
if (map == null) {
|
||||
return super.whenNull(hostAddress);
|
||||
}
|
||||
Object object = map.getObject(progLoc.getByteAddress());
|
||||
Object object = map.get(progLoc.getByteAddress());
|
||||
if (!type.isInstance(object)) {
|
||||
// TODO: Warn?
|
||||
return super.whenNull(hostAddress);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.trace.database.listing;
|
||||
|
||||
import static ghidra.lifecycle.Unfinished.TODO;
|
||||
import static ghidra.lifecycle.Unfinished.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
@ -42,7 +42,6 @@ import ghidra.trace.model.thread.TraceThread;
|
|||
import ghidra.util.LockHold;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
|
||||
/**
|
||||
* A base interface for implementations of {@link TraceCodeUnit}
|
||||
|
@ -214,39 +213,6 @@ public interface DBTraceCodeUnitAdapter extends TraceCodeUnit, MemBufferAdapter
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default void visitProperty(PropertyVisitor visitor, String propertyName) {
|
||||
try (LockHold hold = LockHold.lock(getTrace().getReadWriteLock().readLock())) {
|
||||
TracePropertyMapOperations<?> map =
|
||||
getTrace().getInternalAddressPropertyManager().getPropertyMap(propertyName);
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
if (map.getValueClass() == Void.class) {
|
||||
if (map.getAddressSetView(Range.singleton(getStartSnap())).contains(getAddress())) {
|
||||
visitor.visit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
Object value = map.get(getStartSnap(), getAddress());
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (value instanceof String) {
|
||||
visitor.visit((String) value);
|
||||
}
|
||||
else if (value instanceof Saveable) {
|
||||
visitor.visit((Saveable) value);
|
||||
}
|
||||
else if (value instanceof Integer) {
|
||||
visitor.visit(((Integer) value).intValue());
|
||||
}
|
||||
else {
|
||||
visitor.visit(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default String getLabel() {
|
||||
try (LockHold hold = getTrace().lockRead()) {
|
||||
|
|
|
@ -26,13 +26,13 @@ import ghidra.trace.model.property.TracePropertyMap;
|
|||
import ghidra.util.LockHold;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager {
|
||||
protected final DBTraceProgramView program;
|
||||
|
||||
protected abstract class AbstractDBTraceProgramViewPropertyMap<T> implements PropertyMap {
|
||||
protected abstract class AbstractDBTraceProgramViewPropertyMap<T> implements PropertyMap<T> {
|
||||
protected final TracePropertyMap<T> map;
|
||||
protected final String name;
|
||||
|
||||
|
@ -76,7 +76,7 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
}
|
||||
|
||||
@Override
|
||||
public T getObject(Address addr) {
|
||||
public T get(Address addr) {
|
||||
return map.get(program.snap, addr);
|
||||
}
|
||||
|
||||
|
@ -172,15 +172,6 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
super(map, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
Integer value = getObject(addr);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
visitor.visit(value.intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr, int value) {
|
||||
map.set(DBTraceUtils.atLeastMaybeScratch(program.snap), addr, value);
|
||||
|
@ -188,7 +179,7 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
|
||||
@Override
|
||||
public int getInt(Address addr) throws NoValueException {
|
||||
Integer value = getObject(addr);
|
||||
Integer value = get(addr);
|
||||
if (value == null) {
|
||||
throw new NoValueException();
|
||||
}
|
||||
|
@ -203,16 +194,6 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
super(map, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
Long value = getObject(addr);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
// TODO: In program, this throws NotYetImplemented....
|
||||
visitor.visit(value.longValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr, long value) {
|
||||
map.set(DBTraceUtils.atLeastMaybeScratch(program.snap), addr, value);
|
||||
|
@ -220,7 +201,7 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
|
||||
@Override
|
||||
public long getLong(Address addr) throws NoValueException {
|
||||
Long value = getObject(addr);
|
||||
Long value = get(addr);
|
||||
if (value == null) {
|
||||
throw new NoValueException();
|
||||
}
|
||||
|
@ -235,12 +216,6 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
super(map, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
String value = getObject(addr);
|
||||
visitor.visit(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr, String value) {
|
||||
map.set(DBTraceUtils.atLeastMaybeScratch(program.snap), addr, value);
|
||||
|
@ -248,23 +223,19 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
|
||||
@Override
|
||||
public String getString(Address addr) {
|
||||
return getObject(addr);
|
||||
return get(addr);
|
||||
}
|
||||
}
|
||||
|
||||
protected class DBTraceProgramViewObjectPropertyMap<T extends Saveable>
|
||||
extends AbstractDBTraceProgramViewPropertyMap<T> implements ObjectPropertyMap {
|
||||
extends AbstractDBTraceProgramViewPropertyMap<T> implements ObjectPropertyMap<T> {
|
||||
|
||||
// TODO: Handle case where specific Saveable implementation class is missing
|
||||
|
||||
public DBTraceProgramViewObjectPropertyMap(TracePropertyMap<T> map, String name) {
|
||||
super(map, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
Saveable value = getObject(addr);
|
||||
visitor.visit(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr, Saveable value) {
|
||||
map.set(DBTraceUtils.atLeastMaybeScratch(program.snap), addr,
|
||||
|
@ -272,29 +243,21 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectClass() {
|
||||
public Class<T> getValueClass() {
|
||||
return map.getValueClass();
|
||||
}
|
||||
}
|
||||
|
||||
protected class DBTraceProgramViewVoidPropertyMap
|
||||
extends AbstractDBTraceProgramViewPropertyMap<Void> implements VoidPropertyMap {
|
||||
extends AbstractDBTraceProgramViewPropertyMap<Boolean> implements VoidPropertyMap {
|
||||
|
||||
public DBTraceProgramViewVoidPropertyMap(TracePropertyMap<Void> map, String name) {
|
||||
public DBTraceProgramViewVoidPropertyMap(TracePropertyMap<Boolean> map, String name) {
|
||||
super(map, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
if (!hasProperty(addr)) {
|
||||
return;
|
||||
}
|
||||
visitor.visit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr) {
|
||||
map.set(DBTraceUtils.atLeastMaybeScratch(program.snap), addr, null);
|
||||
map.set(DBTraceUtils.atLeastMaybeScratch(program.snap), addr, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,8 +289,8 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
}
|
||||
|
||||
@Override
|
||||
public ObjectPropertyMap createObjectPropertyMap(String propertyName,
|
||||
Class<? extends Saveable> objectClass) throws DuplicateNameException {
|
||||
public <T extends Saveable> ObjectPropertyMap<T> createObjectPropertyMap(String propertyName,
|
||||
Class<T> objectClass) throws DuplicateNameException {
|
||||
return new DBTraceProgramViewObjectPropertyMap<>(program.trace.getAddressPropertyManager()
|
||||
.createPropertyMap(propertyName, objectClass),
|
||||
propertyName);
|
||||
|
@ -337,13 +300,13 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
public VoidPropertyMap createVoidPropertyMap(String propertyName)
|
||||
throws DuplicateNameException {
|
||||
return new DBTraceProgramViewVoidPropertyMap(program.trace.getAddressPropertyManager()
|
||||
.createPropertyMap(propertyName, Void.class),
|
||||
.createPropertyMap(propertyName, Boolean.class),
|
||||
propertyName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public PropertyMap getPropertyMap(String propertyName) {
|
||||
public PropertyMap<?> getPropertyMap(String propertyName) {
|
||||
TracePropertyMap<?> map =
|
||||
program.trace.getAddressPropertyManager().getPropertyMap(propertyName);
|
||||
if (map == null) {
|
||||
|
@ -363,13 +326,14 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
propertyName);
|
||||
}
|
||||
if (cls == Void.class) {
|
||||
return new DBTraceProgramViewVoidPropertyMap((TracePropertyMap<Void>) map,
|
||||
return new DBTraceProgramViewVoidPropertyMap((TracePropertyMap<Boolean>) map,
|
||||
propertyName);
|
||||
}
|
||||
if (Saveable.class.isAssignableFrom(cls)) {
|
||||
return new DBTraceProgramViewObjectPropertyMap<>(
|
||||
(TracePropertyMap<? extends Saveable>) map, propertyName);
|
||||
}
|
||||
// TODO: Handle unsupported map (simiar to UnsupportedMapDB)
|
||||
throw new AssertionError("Where did this property map type come from? " + cls);
|
||||
}
|
||||
|
||||
|
@ -396,7 +360,7 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public ObjectPropertyMap getObjectPropertyMap(String propertyName) {
|
||||
public ObjectPropertyMap<? extends Saveable> getObjectPropertyMap(String propertyName) {
|
||||
TracePropertyMap<?> map =
|
||||
program.trace.getAddressPropertyManager().getPropertyMap(propertyName);
|
||||
if (map == null) {
|
||||
|
@ -411,8 +375,8 @@ public class DBTraceProgramViewPropertyMapManager implements PropertyMapManager
|
|||
|
||||
@Override
|
||||
public VoidPropertyMap getVoidPropertyMap(String propertyName) {
|
||||
TracePropertyMap<Void> map = program.trace.getAddressPropertyManager()
|
||||
.getPropertyMap(propertyName, Void.class);
|
||||
TracePropertyMap<Boolean> map = program.trace.getAddressPropertyManager()
|
||||
.getPropertyMap(propertyName, Boolean.class);
|
||||
return map == null ? null : new DBTraceProgramViewVoidPropertyMap(map, propertyName);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import db.DBHandle;
|
|||
import db.DBRecord;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.listing.ProgramUserData;
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.trace.database.DBTrace;
|
||||
import ghidra.trace.database.DBTraceManager;
|
||||
import ghidra.trace.database.map.AbstractDBTracePropertyMap;
|
||||
|
@ -37,6 +36,7 @@ import ghidra.util.database.*;
|
|||
import ghidra.util.database.annot.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,7 +22,6 @@ import com.google.common.collect.Range;
|
|||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
|
@ -31,6 +30,7 @@ import ghidra.trace.model.symbol.TraceReference;
|
|||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
/**
|
||||
* A code unit in a {@link Trace}
|
||||
|
|
|
@ -17,9 +17,9 @@ package ghidra.trace.model.property;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
/**
|
||||
* The manager for user properties of a trace
|
||||
|
|
|
@ -23,8 +23,6 @@ import java.math.BigInteger;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.junit.*;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
@ -42,7 +40,6 @@ import ghidra.program.model.listing.*;
|
|||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.listing.DBTraceCommentAdapter.DBTraceCommentEntry;
|
||||
|
@ -61,7 +58,7 @@ import ghidra.util.*;
|
|||
import ghidra.util.database.UndoableTransaction;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest
|
||||
implements Unfinished {
|
||||
|
@ -144,56 +141,6 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest
|
|||
}
|
||||
}
|
||||
|
||||
protected static class TestPropertyVisitor implements PropertyVisitor {
|
||||
Class<?> type = null;
|
||||
Object val = null;
|
||||
|
||||
Pair<Class<?>, Object> getAndReset() {
|
||||
Pair<Class<?>, Object> ret = new ImmutablePair<>(type, val);
|
||||
type = null;
|
||||
val = null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
boolean isSet() {
|
||||
return type != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit() {
|
||||
assertNull(type);
|
||||
type = Void.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String value) {
|
||||
assertNull(type);
|
||||
type = String.class;
|
||||
val = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Object value) {
|
||||
assertNull(type);
|
||||
type = Object.class;
|
||||
val = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Saveable value) {
|
||||
assertNull(type);
|
||||
type = Saveable.class;
|
||||
val = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int value) {
|
||||
assertNull(type);
|
||||
type = Integer.class;
|
||||
val = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T> Set<T> set(Iterator<T> it) {
|
||||
Set<T> result = new HashSet<>();
|
||||
while (it.hasNext()) {
|
||||
|
@ -409,24 +356,6 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest
|
|||
set(i4004.propertyNames()));
|
||||
assertEquals(Set.of(), set(i4006.propertyNames()));
|
||||
|
||||
TestPropertyVisitor visitor = new TestPropertyVisitor();
|
||||
|
||||
i4004.visitProperty(visitor, "noProperty");
|
||||
assertFalse(visitor.isSet());
|
||||
i4004.visitProperty(visitor, "myVoid");
|
||||
assertEquals(new ImmutablePair<>(Void.class, null), visitor.getAndReset());
|
||||
i4006.visitProperty(visitor, "myVoid");
|
||||
assertFalse(visitor.isSet());
|
||||
i4004.visitProperty(visitor, "myInt");
|
||||
assertEquals(new ImmutablePair<>(Integer.class, 0x1234), visitor.getAndReset());
|
||||
i4006.visitProperty(visitor, "myInt");
|
||||
assertFalse(visitor.isSet());
|
||||
i4004.visitProperty(visitor, "myString");
|
||||
assertEquals(new ImmutablePair<>(String.class, "Hello!"), visitor.getAndReset());
|
||||
i4004.visitProperty(visitor, "mySaveable");
|
||||
assertEquals(new ImmutablePair<>(Saveable.class, new TestSaveable(0x5678, "Good bye!")),
|
||||
visitor.getAndReset());
|
||||
|
||||
try (UndoableTransaction tid = b.startTransaction()) {
|
||||
i4004.removeProperty("myVoid");
|
||||
i4006.removeProperty("myVoid"); // NOP
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.junit.*;
|
|||
import com.google.common.collect.Range;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
|
@ -35,6 +34,7 @@ import ghidra.util.ObjectStorage;
|
|||
import ghidra.util.Saveable;
|
||||
import ghidra.util.database.UndoableTransaction;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
public class DBTraceAddressPropertyManagerTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
protected static class MySaveable implements Saveable {
|
||||
|
|
|
@ -283,20 +283,6 @@ abstract class AbstractListingMerger implements ListingMerger, ListingMergeConst
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the two indicated objects are equal. It allows
|
||||
* either or both of the specified objects to be null.
|
||||
* @param o1 the first object or null
|
||||
* @param o2 the second object or null
|
||||
* @return true if the objects are equal.
|
||||
*/
|
||||
static boolean same(Object o1, Object o2) {
|
||||
if (o1 == null) {
|
||||
return (o2 == null);
|
||||
}
|
||||
return o1.equals(o2);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#apply()
|
||||
*/
|
||||
|
|
|
@ -1070,7 +1070,7 @@ class SymbolMerger extends AbstractListingMerger {
|
|||
// Both changed primary so check for conflict.
|
||||
Symbol latestPrimary = latestSymTab.getPrimarySymbol(addr);
|
||||
Symbol latestSameAsMy = SimpleDiffUtility.getSymbol(myPrimary, latestPgm);
|
||||
if (!same(latestPrimary, latestSameAsMy)) {
|
||||
if (!Objects.equals(latestPrimary, latestSameAsMy)) {
|
||||
savePrimaryConflict(addr);
|
||||
}
|
||||
}
|
||||
|
@ -1540,7 +1540,7 @@ class SymbolMerger extends AbstractListingMerger {
|
|||
Symbol latestResultSymbol = getResultSymbolFromLatestSymbol(latestPrimary);
|
||||
Symbol myPrimary = mySymTab.getPrimarySymbol(addr);
|
||||
Symbol myResultSymbol = getResultSymbolFromMySymbol(myPrimary);
|
||||
if (myResultSymbol == null || same(myResultSymbol, latestResultSymbol)) {
|
||||
if (myResultSymbol == null || Objects.equals(myResultSymbol, latestResultSymbol)) {
|
||||
return;
|
||||
}
|
||||
currentAddress = addr;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,28 +15,27 @@
|
|||
*/
|
||||
package ghidra.app.merge.listing;
|
||||
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.merge.util.MergeUtilities;
|
||||
import ghidra.program.database.properties.UnsupportedMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.util.*;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.merge.util.MergeUtilities;
|
||||
import ghidra.program.database.properties.GenericSaveable;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.util.PropertyMap;
|
||||
import ghidra.program.model.util.PropertyMapManager;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Class for merging user defined property changes. This class can merge non-conflicting
|
||||
* user defined property changes that were made to the checked out version. It can determine
|
||||
|
@ -72,9 +70,6 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
super(listingMergeMgr);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.AbstractListingMerger#init()
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
@ -84,16 +79,12 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
conflictSet = new AddressSet();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#getConflictType()
|
||||
*/
|
||||
@Override
|
||||
public String getConflictType() {
|
||||
return "User Defined Property";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#autoMerge(ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void autoMerge(int progressMin, int progressMax, TaskMonitor monitor)
|
||||
throws ProgramConflictException, MemoryAccessException, CancelledException {
|
||||
|
||||
|
@ -111,10 +102,8 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
AddressSet tmpAutoSet = new AddressSet();
|
||||
AddressSet overlapSet = new AddressSet();
|
||||
MergeUtilities.adjustSets(latestDetailSet, myDetailSet, tmpAutoSet, overlapSet);
|
||||
// FUTURE : Change USER_DEFINED_DIFFS to be individual addresses rather than code unit ranges.
|
||||
AddressSet autoAllSet = limitToStartofCodeUnits(resultPgm, tmpAutoSet);
|
||||
// mergeProperties() won't try to merge Unsupported user defined properties.
|
||||
listingMergeMgr.mergeMy.mergeProperties(autoAllSet, monitor);
|
||||
listingMergeMgr.mergeMy.mergeProperties(tmpAutoSet, monitor);
|
||||
|
||||
propNames = getPropertyNames();
|
||||
int numProps = propNames.length;
|
||||
|
@ -129,11 +118,11 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
|
||||
for (int i = 0; i < propNames.length; i++) {
|
||||
propertyIndex = i;
|
||||
PropertyMap latestMap = latestPMM.getPropertyMap(propNames[i]);
|
||||
PropertyMap myMap = myPMM.getPropertyMap(propNames[i]);
|
||||
PropertyMap originalMap = originalPMM.getPropertyMap(propNames[i]);
|
||||
PropertyMap<?> latestMap = latestPMM.getPropertyMap(propNames[i]);
|
||||
PropertyMap<?> myMap = myPMM.getPropertyMap(propNames[i]);
|
||||
PropertyMap<?> originalMap = originalPMM.getPropertyMap(propNames[i]);
|
||||
// Handle case where the class for a Saveable property is missing.
|
||||
if ((latestMap instanceof UnsupportedMapDB) || (myMap instanceof UnsupportedMapDB)) {
|
||||
if (isUnsupportedMap(latestMap) || isUnsupportedMap(myMap)) {
|
||||
String msg =
|
||||
"Encountered unsupported property: " + propNames[i] +
|
||||
"\nYour Ghidra may be missing the java class for this property." +
|
||||
|
@ -144,31 +133,48 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
continue; // ignore property that isn't supported.
|
||||
}
|
||||
if (!samePropertyTypes(latestMap, myMap)) {
|
||||
|
||||
// TODO: improve handling of incompatibl map types - address level conflicts
|
||||
// resolution may be inappropriate since you can't pick-and-choose - only one map
|
||||
// can be retained. (see GP-2585)
|
||||
|
||||
String msg =
|
||||
LATEST_TITLE + " and " + MY_TITLE + " program versions not same type for " +
|
||||
propNames[i] + " property.";
|
||||
LATEST_TITLE + " and " + MY_TITLE +
|
||||
" program versions do not have the same type for '" +
|
||||
propNames[i] + "' property.";
|
||||
Msg.showError(this, this.listingMergePanel, "User Defined Property Merge Error",
|
||||
msg);
|
||||
}
|
||||
else if (isUnsupportedMap(latestMap) || isUnsupportedMap(myMap)) {
|
||||
String msg =
|
||||
LATEST_TITLE + " and/or " + MY_TITLE + " program versions have unsupported " +
|
||||
"property map '" + propNames[i] + "' which will be ignored.";
|
||||
Msg.showError(this, this.listingMergePanel, "User Defined Property Merge Error",
|
||||
msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
AddressIterator latestIter =
|
||||
(latestMap != null) ? latestMap.getPropertyIterator(overlapSet) : null;
|
||||
AddressIterator myIter = (myMap != null) ? myMap.getPropertyIterator(overlapSet) : null;
|
||||
AddressIterator originalIter =
|
||||
(originalMap != null) ? originalMap.getPropertyIterator(overlapSet) : null;
|
||||
|
||||
MultiAddressIterator addrIter =
|
||||
new MultiAddressIterator(new AddressIterator[] { latestIter, myIter, originalIter });
|
||||
while (addrIter.hasNext()) {
|
||||
Address addr = addrIter.next();
|
||||
Object latestObj = getProperty(latestMap, addr);
|
||||
Object myObj = getProperty(myMap, addr);
|
||||
Object originalObj = getProperty(originalMap, addr);
|
||||
boolean sameLatestMy = same(latestObj, myObj);
|
||||
Object latestObj = latestMap != null ? latestMap.get(addr) : null;
|
||||
Object myObj = myMap != null ? myMap.get(addr) : null;
|
||||
Object originalObj = originalMap != null ? originalMap.get(addr) : null;
|
||||
|
||||
boolean sameLatestMy = Objects.equals(latestObj, myObj);
|
||||
if (sameLatestMy) {
|
||||
// My is already like latest, so do nothing.
|
||||
continue;
|
||||
}
|
||||
boolean sameOriginalLatest = same(originalObj, latestObj);
|
||||
boolean sameOriginalMy = same(originalObj, myObj);
|
||||
boolean sameOriginalLatest = Objects.equals(originalObj, latestObj);
|
||||
boolean sameOriginalMy = Objects.equals(originalObj, myObj);
|
||||
if (sameOriginalLatest) {
|
||||
// Only My changed so autoMerge.
|
||||
merge(propNames[i], addr, KEEP_MY);
|
||||
|
@ -186,40 +192,12 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
updateProgress(100, "Done auto-merging User Defined Properties and determining conflicts.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the property, if there is one, from the specified property map for
|
||||
* the indicated address.
|
||||
* @param map the property map
|
||||
* @param address the address
|
||||
* @return the property at the address or null if there isn't one.
|
||||
*/
|
||||
private Object getProperty(PropertyMap map, Address address) {
|
||||
if (map instanceof VoidPropertyMap) {
|
||||
return ((VoidPropertyMap) map).getNextPropertyAddress(address);
|
||||
private boolean isUnsupportedMap(PropertyMap<?> map) {
|
||||
if (map == null) {
|
||||
return false;
|
||||
}
|
||||
else if (map instanceof ObjectPropertyMap) {
|
||||
return ((ObjectPropertyMap) map).getObject(address);
|
||||
}
|
||||
else if (map instanceof LongPropertyMap) {
|
||||
try {
|
||||
return new Long(((LongPropertyMap) map).getLong(address));
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (map instanceof IntPropertyMap) {
|
||||
try {
|
||||
return new Integer(((IntPropertyMap) map).getInt(address));
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (map instanceof StringPropertyMap) {
|
||||
return ((StringPropertyMap) map).getString(address);
|
||||
}
|
||||
return null;
|
||||
Class<?> valueClass = map.getValueClass();
|
||||
return valueClass == null || GenericSaveable.class.equals(valueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,11 +207,13 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
* @return true if the property type held by the two maps is the same.
|
||||
* Otherwise, return false.
|
||||
*/
|
||||
private boolean samePropertyTypes(PropertyMap latestMap, PropertyMap myMap) {
|
||||
if (latestMap != null && myMap != null) {
|
||||
return latestMap.getClass().equals(myMap.getClass());
|
||||
private boolean samePropertyTypes(PropertyMap<?> latestMap, PropertyMap<?> myMap) {
|
||||
if (latestMap == null || myMap == null) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
Class<?> latestValueClass = latestMap.getValueClass();
|
||||
Class<?> myValueClass = myMap.getValueClass();
|
||||
return Objects.equals(myValueClass, latestValueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,16 +240,12 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#hasConflict(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasConflict(Address addr) {
|
||||
return conflictSet.contains(addr);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#getConflictCount(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public int getConflictCount(Address addr) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < conflictSets.length; i++) {
|
||||
|
@ -292,22 +268,14 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
*/
|
||||
private void setupConflictsPanel(ListingMergePanel listingPanel, String propertyName,
|
||||
Address addr, ChangeListener changeListener) {
|
||||
|
||||
// Initialize the conflict panel.
|
||||
PropertyMap latestPMap = latestPMM.getPropertyMap(propertyName);
|
||||
PropertyMap myPMap = myPMM.getPropertyMap(propertyName);
|
||||
PropertyMap originalPMap = originalPMM.getPropertyMap(propertyName);
|
||||
Object latestObj = null;
|
||||
Object myObj = null;
|
||||
Object originalObj = null;
|
||||
if (latestPMap != null) {
|
||||
latestObj = getProperty(latestPMap, addr);
|
||||
}
|
||||
if (myPMap != null) {
|
||||
myObj = getProperty(myPMap, addr);
|
||||
}
|
||||
if (originalPMap != null) {
|
||||
originalObj = getProperty(originalPMap, addr);
|
||||
}
|
||||
PropertyMap<?> latestMap = latestPMM.getPropertyMap(propertyName);
|
||||
PropertyMap<?> myMap = myPMM.getPropertyMap(propertyName);
|
||||
PropertyMap<?> originalMap = originalPMM.getPropertyMap(propertyName);
|
||||
Object latestObj = latestMap != null ? latestMap.get(addr) : null;
|
||||
Object myObj = myMap != null ? myMap.get(addr) : null;
|
||||
Object originalObj = originalMap != null ? originalMap.get(addr) : null;
|
||||
|
||||
// Get an empty conflict panel.
|
||||
if (conflictPanel != null) {
|
||||
|
@ -380,10 +348,7 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
// }
|
||||
// }
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#mergeConflicts(ghidra.app.merge.tool.ListingMergePanel,
|
||||
* ghidra.program.model.address.Address, int, ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void mergeConflicts(ListingMergePanel listingPanel, Address addr,
|
||||
int mergeConflictOption, TaskMonitor monitor) throws CancelledException,
|
||||
MemoryAccessException {
|
||||
|
@ -499,16 +464,11 @@ class UserDefinedPropertyMerger extends AbstractListingMerger {
|
|||
return "Delete as in '" + version + "' version";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#getConflicts()
|
||||
*/
|
||||
@Override
|
||||
public AddressSetView getConflicts() {
|
||||
return conflictSet;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#apply()
|
||||
*/
|
||||
@Override
|
||||
public boolean apply() {
|
||||
numConflictsResolved = 0;
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.util;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import ghidra.program.database.function.FunctionDB;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.listing.FunctionTag;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
* Compares the function tags in two programs.
|
||||
*
|
||||
* Two sets of tags are considered equal if they contain the name and comment
|
||||
* attributes.
|
||||
*
|
||||
*/
|
||||
class FunctionTagComparator extends ProgramDiff.ProgramDiffComparatorImpl {
|
||||
|
||||
/**
|
||||
* Generic constructor for comparing program differences.
|
||||
*
|
||||
* @param program1 the first program
|
||||
* @param program2 the second program
|
||||
*/
|
||||
FunctionTagComparator(Program program1, Program program2) {
|
||||
super(program1, program2);
|
||||
}
|
||||
|
||||
/** Compares two function tag lists to determine whether the first
|
||||
* tag address is effectively less than (comes before it in memory),
|
||||
* equal to (at the same spot in memory), or greater than (comes after
|
||||
* it in memory) the second comment's address.
|
||||
*
|
||||
* @param obj1 the address for the first program's tag.
|
||||
* @param obj2 the address for the second program's tag.
|
||||
* @return -1 if the first comes before the second in memory.
|
||||
* 0 if the objects are at the same spot in memory.
|
||||
* 1 if the first comes after the second in memory.
|
||||
*/
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
FunctionDB f1 = (FunctionDB) o1;
|
||||
FunctionDB f2 = (FunctionDB) o2;
|
||||
|
||||
Address a1 = f1.getEntryPoint();
|
||||
Address a2 = f2.getEntryPoint();
|
||||
|
||||
Address address2CompatibleWith1 =
|
||||
SimpleDiffUtility.getCompatibleAddress(program2, a2, program1);
|
||||
return a1.compareTo(address2CompatibleWith1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the tag lists for the given functions contain
|
||||
* the same items; order is unimportant.
|
||||
*
|
||||
* @param obj1 the first {@link FunctionDB} object
|
||||
* @param obj2 the second {@link FunctionDB} object
|
||||
* @return true if the tags lists contain the same elements.
|
||||
*/
|
||||
@Override
|
||||
public boolean isSame(Object obj1, Object obj2) {
|
||||
FunctionDB f1 = (FunctionDB) obj1;
|
||||
FunctionDB f2 = (FunctionDB) obj2;
|
||||
|
||||
if (f1 == null && f2 == null) {
|
||||
// Both null - neither is a function so just return true
|
||||
return true;
|
||||
}
|
||||
if (f1 == null || f2 == null) {
|
||||
// Someone is not a function, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the tag lists and check if they're the same.
|
||||
Collection<FunctionTag> f1Tags = f1.getTags();
|
||||
Collection<FunctionTag> f2Tags = f2.getTags();
|
||||
return f1Tags.equals(f2Tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address set that contains the address for the tags.
|
||||
*
|
||||
* @param obj the object being examined by this comparator.
|
||||
* @param program the program the object is associated with.
|
||||
* @return address set containing the tag location.
|
||||
*/
|
||||
@Override
|
||||
public AddressSet getAddressSet(Object obj, Program program) {
|
||||
AddressSet addrs = new AddressSet();
|
||||
if (obj == null) {
|
||||
return addrs;
|
||||
}
|
||||
|
||||
FunctionDB function = (FunctionDB) obj;
|
||||
addrs.add(function.getEntryPoint());
|
||||
return addrs;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -29,9 +29,9 @@ import ghidra.program.model.listing.*;
|
|||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
/**
|
||||
* ProgramDiffDetails is used to determine the detailed differences between
|
||||
|
|
|
@ -32,7 +32,6 @@ import ghidra.program.model.util.*;
|
|||
import ghidra.util.*;
|
||||
import ghidra.util.datastruct.LongLongHashtable;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
|
@ -46,7 +45,7 @@ import ghidra.util.task.TaskMonitorAdapter;
|
|||
* and a one up number.
|
||||
*/
|
||||
|
||||
public class ProgramMerge implements PropertyVisitor {
|
||||
public class ProgramMerge {
|
||||
|
||||
/** Suffix that is attached to a symbol name and then followed by a number to create a new unique symbol name. */
|
||||
public static String SYMBOL_CONFLICT_SUFFIX = "_conflict";
|
||||
|
@ -66,10 +65,6 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
private Listing resultListing;
|
||||
/** The listing for the program being merged from. */
|
||||
private Listing originListing;
|
||||
/** The current code unit that is being modified when a user defined property is merged. */
|
||||
private CodeUnit resultCu;
|
||||
/** The current property name being merged, when merging user defined properties. */
|
||||
private String propertyName;
|
||||
|
||||
private SymbolMerge symbolMerge;
|
||||
private FunctionMerge functionMerge;
|
||||
|
@ -729,7 +724,7 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
// If instruction has modified fall through, then change it
|
||||
Address oldFallThrough = originInstruction.getFallThrough();
|
||||
Address newFallThrough = originToResultTranslator.getAddress(oldFallThrough);
|
||||
if (!SystemUtilities.isEqual(targetInstruction.getFallThrough(), newFallThrough)) {
|
||||
if (!Objects.equals(targetInstruction.getFallThrough(), newFallThrough)) {
|
||||
if (originInstruction.isFallThroughOverridden()) {
|
||||
targetInstruction.setFallThrough(newFallThrough);
|
||||
}
|
||||
|
@ -889,7 +884,7 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
Address resultAddress = originToResultTranslator.getAddress(originAddress);
|
||||
Equate resultEquate = resultEquateTable.getEquate(resultAddress, opIndex, value);
|
||||
Equate originEquate = originEquateTable.getEquate(originAddress, opIndex, value);
|
||||
if (SystemUtilities.isEqual(resultEquate, originEquate)) {
|
||||
if (Objects.equals(resultEquate, originEquate)) {
|
||||
return;
|
||||
}
|
||||
if (resultEquate != null) {
|
||||
|
@ -1246,7 +1241,7 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
|
||||
private void replaceReferences(CodeUnit originCu, int opIndex) {
|
||||
Address resultAddress = originToResultTranslator.getAddress(originCu.getMinAddress());
|
||||
resultCu = resultListing.getCodeUnitAt(resultAddress);
|
||||
CodeUnit resultCu = resultListing.getCodeUnitAt(resultAddress);
|
||||
if (opIndex > resultCu.getNumOperands()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1502,7 +1497,7 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
Address originFallThrough = originInstruction.getFallThrough();
|
||||
Address originFTCompatibleWithResult =
|
||||
originToResultTranslator.getAddress(originFallThrough);
|
||||
if (SystemUtilities.isEqual(resultFallThrough, originFTCompatibleWithResult)) {
|
||||
if (Objects.equals(resultFallThrough, originFTCompatibleWithResult)) {
|
||||
return;
|
||||
}
|
||||
if (!originOverridden) {
|
||||
|
@ -2378,7 +2373,7 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
if (function != null) {
|
||||
Address entry = function.getEntryPoint();
|
||||
String origName = function.getName();
|
||||
if (!SystemUtilities.isEqual(origName, name)) {
|
||||
if (!Objects.equals(origName, name)) {
|
||||
for (int i = 0; i < Integer.MAX_VALUE; i++) {
|
||||
String newName =
|
||||
(i == 0) ? name : name + ProgramMerge.SYMBOL_CONFLICT_SUFFIX + i;
|
||||
|
@ -3828,174 +3823,133 @@ public class ProgramMerge implements PropertyVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
/** Replaces the user defined properties from the origin program into the result
|
||||
/**
|
||||
* Replaces the user defined properties from the origin program into the result
|
||||
* program at the address that is equivalent to the origin address.
|
||||
* Note: To merge properties, there must be a code unit AT the equivalent address
|
||||
* in the result program.
|
||||
* @param originAddress the address of the code unit to get the properties from in the origin program.
|
||||
*/
|
||||
private void mergePropertiesAtAddress(Address originAddress) {
|
||||
Address resultAddress = originToResultTranslator.getAddress(originAddress);
|
||||
resultCu = resultListing.getCodeUnitAt(resultAddress);
|
||||
if (resultCu != null) {
|
||||
// Remove the existing properties from the merge program's code unit.
|
||||
Iterator<String> propNames = resultCu.propertyNames();
|
||||
while (propNames.hasNext()) {
|
||||
resultCu.removeProperty(propNames.next());
|
||||
}
|
||||
|
||||
// Add the originating program's user defined properties on the code unit.
|
||||
CodeUnit origCu = originListing.getCodeUnitAt(originAddress);
|
||||
if (origCu != null) {
|
||||
propNames = origCu.propertyNames();
|
||||
while (propNames.hasNext()) {
|
||||
propertyName = propNames.next();
|
||||
if (propertyName.equals("Bookmarks")) {
|
||||
continue; // ignore bookmarks as properties, since the bookmark merge gets these.
|
||||
Address resultAddress;
|
||||
try {
|
||||
resultAddress = originToResultTranslator.getAddress(originAddress);
|
||||
}
|
||||
catch (AddressTranslationException e1) {
|
||||
return;
|
||||
}
|
||||
if (!resultProgram.getMemory().contains(resultAddress)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyMapManager origPropertyMgr = originProgram.getUsrPropertyManager();
|
||||
PropertyMapManager resultPropertyMgr = resultProgram.getUsrPropertyManager();
|
||||
|
||||
Iterator<String> propNames = resultPropertyMgr.propertyManagers();
|
||||
while (propNames.hasNext()) {
|
||||
String propertyName = propNames.next();
|
||||
PropertyMap<?> resultPropertyMap = resultPropertyMgr.getPropertyMap(propertyName);
|
||||
resultPropertyMap.remove(resultAddress);
|
||||
}
|
||||
|
||||
propNames = origPropertyMgr.propertyManagers();
|
||||
while (propNames.hasNext()) {
|
||||
String propertyName = propNames.next();
|
||||
if (propertyName.equals("Bookmarks")) {
|
||||
continue; // ignore bookmarks as properties, since the bookmark merge gets these.
|
||||
}
|
||||
PropertyMap<?> origPropertyMap = origPropertyMgr.getPropertyMap(propertyName);
|
||||
if (origPropertyMap instanceof UnsupportedMapDB) {
|
||||
continue; // ignore property that isn't supported.
|
||||
}
|
||||
PropertyMap<?> resultPropertyMap = resultPropertyMgr.getPropertyMap(propertyName);
|
||||
Object value = origPropertyMap.get(originAddress);
|
||||
if (value != null) {
|
||||
try {
|
||||
if (resultPropertyMap == null) {
|
||||
resultPropertyMap =
|
||||
createPropertyMap(propertyName, resultProgram, origPropertyMap);
|
||||
}
|
||||
// Handle case where the class for a Saveable property is missing.
|
||||
if (originListing.getPropertyMap(propertyName) instanceof UnsupportedMapDB) {
|
||||
continue; // ignore property that isn't supported.
|
||||
}
|
||||
origCu.visitProperty(this, propertyName);
|
||||
resultPropertyMap.add(resultAddress, value);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
throw new AssertException(e);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String msg = "Property merge failed at " + resultAddress + " '" + propertyName +
|
||||
"': " + e.getMessage();
|
||||
Msg.error(this, msg);
|
||||
errorMsg.append(msg + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Replaces the user defined properties from the specified origin address in the origin program
|
||||
private PropertyMap<?> createPropertyMap(String propertyName, Program p,
|
||||
PropertyMap<?> originalMap) throws DuplicateNameException {
|
||||
|
||||
PropertyMapManager usrPropertyManager = p.getUsrPropertyManager();
|
||||
if (originalMap instanceof IntPropertyMap) {
|
||||
return usrPropertyManager.createIntPropertyMap(propertyName);
|
||||
}
|
||||
else if (originalMap instanceof LongPropertyMap) {
|
||||
return usrPropertyManager.createLongPropertyMap(propertyName);
|
||||
}
|
||||
else if (originalMap instanceof StringPropertyMap) {
|
||||
return usrPropertyManager.createStringPropertyMap(propertyName);
|
||||
}
|
||||
else if (originalMap instanceof VoidPropertyMap) {
|
||||
return usrPropertyManager.createVoidPropertyMap(propertyName);
|
||||
}
|
||||
else if (originalMap instanceof ObjectPropertyMap) {
|
||||
Class<? extends Saveable> objectClass =
|
||||
((ObjectPropertyMap<?>) originalMap).getValueClass();
|
||||
return usrPropertyManager.createObjectPropertyMap(propertyName, objectClass);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the user defined properties from the specified origin address in the origin program
|
||||
* to the equivalent result address in the result program.
|
||||
* Note: To merge properties, there must be a code unit AT the equivalent address
|
||||
* in the result program.
|
||||
* @param userPropertyName original property name
|
||||
* @param originAddress the address of the code unit to get the properties from in the origin program.
|
||||
*/
|
||||
public void mergeUserProperty(String userPropertyName, Address originAddress) {
|
||||
Address resultAddress = originToResultTranslator.getAddress(originAddress);
|
||||
PropertyMapManager resultPmm = resultProgram.getUsrPropertyManager();
|
||||
PropertyMapManager originPmm = originProgram.getUsrPropertyManager();
|
||||
PropertyMap resultOpm = resultPmm.getPropertyMap(userPropertyName);
|
||||
PropertyMap originOpm = originPmm.getPropertyMap(userPropertyName);
|
||||
Object resultObject = null;
|
||||
Object originObject = null;
|
||||
if (resultOpm != null) {
|
||||
resultObject = getProperty(resultOpm, resultAddress);
|
||||
}
|
||||
if (originOpm != null) {
|
||||
originObject = getProperty(originOpm, originAddress);
|
||||
}
|
||||
if (!SystemUtilities.isEqual(resultObject, originObject)) {
|
||||
PropertyMap<?> resultOpm = resultPmm.getPropertyMap(userPropertyName);
|
||||
PropertyMap<?> originOpm = originPmm.getPropertyMap(userPropertyName);
|
||||
Object resultObject = resultOpm != null ? resultOpm.get(resultAddress) : null;
|
||||
Object originObject = originOpm != null ? originOpm.get(originAddress) : null;
|
||||
|
||||
if (!Objects.equals(resultObject, originObject)) {
|
||||
if (resultObject != null && resultOpm != null) {
|
||||
resultOpm.remove(resultAddress);
|
||||
}
|
||||
if (originObject != null) {
|
||||
if (resultOpm == null) {
|
||||
try {
|
||||
try {
|
||||
if (resultOpm == null) {
|
||||
resultOpm =
|
||||
resultPmm.createObjectPropertyMap(userPropertyName, Saveable.class);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
throw new RuntimeException(e);
|
||||
createPropertyMap(userPropertyName, resultProgram, originOpm);
|
||||
}
|
||||
resultOpm.add(resultAddress, originObject);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
throw new AssertException(e);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
String msg = "Property merge failed at " + resultAddress + " '" +
|
||||
userPropertyName + "': " + e.getMessage();
|
||||
Msg.error(this, msg);
|
||||
errorMsg.append(msg + "\n");
|
||||
}
|
||||
setProperty(resultOpm, resultAddress, originObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object getProperty(PropertyMap map, Address address) {
|
||||
if (map instanceof VoidPropertyMap) {
|
||||
return ((VoidPropertyMap) map).getNextPropertyAddress(address);
|
||||
}
|
||||
else if (map instanceof ObjectPropertyMap) {
|
||||
return ((ObjectPropertyMap) map).getObject(address);
|
||||
}
|
||||
else if (map instanceof LongPropertyMap) {
|
||||
try {
|
||||
return new Long(((LongPropertyMap) map).getLong(address));
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (map instanceof IntPropertyMap) {
|
||||
try {
|
||||
return new Integer(((IntPropertyMap) map).getInt(address));
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (map instanceof StringPropertyMap) {
|
||||
return ((StringPropertyMap) map).getString(address);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setProperty(PropertyMap map, Address address, Object property) {
|
||||
if (map instanceof VoidPropertyMap) {
|
||||
((VoidPropertyMap) map).add(address);
|
||||
}
|
||||
else if (map instanceof ObjectPropertyMap) {
|
||||
((ObjectPropertyMap) map).add(address, (Saveable) property);
|
||||
}
|
||||
else if (map instanceof LongPropertyMap) {
|
||||
((LongPropertyMap) map).add(address, ((Long) property).longValue());
|
||||
}
|
||||
else if (map instanceof IntPropertyMap) {
|
||||
((IntPropertyMap) map).add(address, ((Integer) property).intValue());
|
||||
}
|
||||
else if (map instanceof StringPropertyMap) {
|
||||
((StringPropertyMap) map).add(address, (String) property);
|
||||
}
|
||||
}
|
||||
|
||||
// *******************************************************************
|
||||
// The following are the methods for the PropertyVisitor interface.
|
||||
// *******************************************************************
|
||||
/** Set the property on the merge program's code unit if the named property
|
||||
* is a void property type.
|
||||
*/
|
||||
@Override
|
||||
public void visit() {
|
||||
resultCu.setProperty(propertyName);
|
||||
}
|
||||
|
||||
/** Set the property on the merge program's code unit if the named property
|
||||
* is a String property type.
|
||||
* @param value the value for the named property.
|
||||
*/
|
||||
@Override
|
||||
public void visit(String value) {
|
||||
resultCu.setProperty(propertyName, value);
|
||||
}
|
||||
|
||||
/** Set the property on the merge program's code unit if the named property
|
||||
* is an Object property type.
|
||||
* @param value the value for the named property.
|
||||
*/
|
||||
@Override
|
||||
public void visit(Object value) {
|
||||
String message = "Could Not Merge Property.\n" + "Can't merge property, \"" + propertyName +
|
||||
"\", with value of " + value;
|
||||
errorMsg.append(message);
|
||||
}
|
||||
|
||||
/** Set the property on the merge program's code unit if the named property
|
||||
* is an Object property type.
|
||||
* @param value the value for the named property.
|
||||
*/
|
||||
@Override
|
||||
public void visit(Saveable value) {
|
||||
resultCu.setProperty(propertyName, value);
|
||||
}
|
||||
|
||||
/** Set the property on the merge program's code unit if the named property
|
||||
* is an int property type.
|
||||
* @param value the value for the named property.
|
||||
*/
|
||||
@Override
|
||||
public void visit(int value) {
|
||||
resultCu.setProperty(propertyName, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ import java.awt.Color;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.database.ProgramModifierListener;
|
||||
import docking.AbstractErrDialog;
|
||||
import ghidra.program.database.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.util.*;
|
||||
import ghidra.util.SaveableColor;
|
||||
|
@ -31,7 +31,7 @@ import ghidra.util.exception.DuplicateNameException;
|
|||
/**
|
||||
* Test the merge of the versioned program's listing.
|
||||
*/
|
||||
public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest {
|
||||
public class UserDefinedPropertyMergeManagerTest extends AbstractListingMergeManagerTest {
|
||||
|
||||
// ********************
|
||||
// *** DiffTestPgm1 ***
|
||||
|
@ -60,11 +60,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
// 0x10039f8: testColor=BLACK.
|
||||
// 0x10039fe: testColor=GREEN.
|
||||
|
||||
/**
|
||||
*
|
||||
* @param arg0
|
||||
*/
|
||||
public UserDefinedMergeManagerTest() {
|
||||
public UserDefinedPropertyMergeManagerTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -72,9 +68,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
public void testAddVoidProperty() throws Exception {
|
||||
mtf.initialize("DiffTestPgm1", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -96,9 +89,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -153,9 +143,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
// 0x10039fe: testColor=GREEN.
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -174,9 +161,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -250,16 +234,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
// 0x10039fe: testColor=RED.
|
||||
mtf.initialize("DiffTestPgm1", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
assertNotNull(opm);
|
||||
opm.add(addr(program, "0x1002400"), new SaveableColor(Color.GRAY));
|
||||
opm.add(addr(program, "0x1002466"), new SaveableColor(Color.CYAN));
|
||||
|
@ -274,16 +255,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
assertNotNull(opm);
|
||||
opm.add(addr(program, "0x1002466"), new SaveableColor(Color.MAGENTA));
|
||||
opm.add(addr(program, "0x1002481"), new SaveableColor(Color.RED));
|
||||
|
@ -306,62 +284,59 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm;
|
||||
ObjectPropertyMap opm;
|
||||
ObjectPropertyMap<?> opm;
|
||||
pmm = resultProgram.getUsrPropertyManager();
|
||||
opm = pmm.getObjectPropertyMap("testColor");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002400"), address);
|
||||
assertEquals(new SaveableColor(Color.GRAY), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.GRAY), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002472"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002481"), address);
|
||||
assertEquals(new SaveableColor(Color.RED), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.RED), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002488"), address);
|
||||
assertEquals(new SaveableColor(Color.PINK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.PINK), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x100248a"), address);
|
||||
assertEquals(new SaveableColor(Color.GREEN), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.GREEN), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x100248c"), address);
|
||||
assertEquals(new SaveableColor(Color.YELLOW), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.YELLOW), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002490"), address);
|
||||
assertEquals(new SaveableColor(Color.ORANGE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.ORANGE), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039dd"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.RED), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.RED), opm.get(address));
|
||||
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testAddStringProperty() throws Exception {
|
||||
mtf.initialize("DiffTestPgm1", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -387,9 +362,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -458,7 +430,259 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testAddStringProperty2() throws Exception {
|
||||
mtf.initialize("DiffTestPgm1", new OriginalProgramModifierListener() {
|
||||
|
||||
@Override
|
||||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
try {
|
||||
StringPropertyMap spm = pmm.createStringPropertyMap("testString1");
|
||||
spm.add(addr(program, "0x1002100"), "A");
|
||||
spm.add(addr(program, "0x1002166"), "B");
|
||||
|
||||
spm = pmm.createStringPropertyMap("testString2");
|
||||
spm.add(addr(program, "0x1002200"), "C");
|
||||
spm.add(addr(program, "0x1002266"), "D");
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, commit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
try {
|
||||
StringPropertyMap spm = pmm.createStringPropertyMap("testString3");
|
||||
spm.add(addr(program, "0x1002381"), "E");
|
||||
spm.add(addr(program, "0x1002366"), "F");
|
||||
|
||||
// Add to existing map removed in latest (conflict)
|
||||
// NOTE: In the absence of property conflict handling this
|
||||
// will cause testString1 properties removed in latest to be
|
||||
// re-introduced into result
|
||||
|
||||
// TODO: improve property conflict handling
|
||||
|
||||
spm = pmm.getStringPropertyMap("testString1");
|
||||
spm.add(addr(program, "0x1002500"), "G");
|
||||
spm.add(addr(program, "0x1002566"), "H");
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, commit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
try {
|
||||
StringPropertyMap spm = pmm.createStringPropertyMap("testString4");
|
||||
spm.add(addr(program, "0x1002500"), "I");
|
||||
spm.add(addr(program, "0x1002566"), "J");
|
||||
|
||||
pmm.removePropertyMap("testString1");
|
||||
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, commit);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
executeMerge(ASK_USER);
|
||||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm = resultProgram.getUsrPropertyManager();
|
||||
|
||||
StringPropertyMap spm = pmm.getStringPropertyMap("testString1");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002500"), address);
|
||||
assertEquals("G", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002566"), address);
|
||||
assertEquals("H", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
spm = pmm.getStringPropertyMap("testString2");
|
||||
address = resultProgram.getMinAddress();
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002200"), address);
|
||||
assertEquals("C", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002266"), address);
|
||||
assertEquals("D", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
spm = pmm.getStringPropertyMap("testString3");
|
||||
address = resultProgram.getMinAddress();
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002366"), address);
|
||||
assertEquals("F", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002381"), address);
|
||||
assertEquals("E", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
spm = pmm.getStringPropertyMap("testString4");
|
||||
address = resultProgram.getMinAddress();
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002500"), address);
|
||||
assertEquals("I", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002566"), address);
|
||||
assertEquals("J", spm.getString(address));
|
||||
|
||||
address = spm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddStringProperty3() throws Exception {
|
||||
mtf.initialize("DiffTestPgm1", new OriginalProgramModifierListener() {
|
||||
|
||||
@Override
|
||||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
try {
|
||||
StringPropertyMap pm = pmm.createStringPropertyMap("testMap");
|
||||
pm.add(addr(program, "0x1002100"), "A");
|
||||
pm.add(addr(program, "0x1002166"), "B");
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, commit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
try {
|
||||
pmm.removePropertyMap("testMap");
|
||||
|
||||
IntPropertyMap pm = pmm.createIntPropertyMap("testMap");
|
||||
pm.add(addr(program, "0x1002100"), 1);
|
||||
pm.add(addr(program, "0x1002166"), 2);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, commit);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
try {
|
||||
pmm.removePropertyMap("testMap");
|
||||
|
||||
LongPropertyMap pm = pmm.createLongPropertyMap("testMap");
|
||||
pm.add(addr(program, "0x1002100"), 1);
|
||||
pm.add(addr(program, "0x1002166"), 2);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
commit = true;
|
||||
}
|
||||
finally {
|
||||
program.endTransaction(txId, commit);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
executeMerge(ASK_USER);
|
||||
|
||||
AbstractErrDialog errDlg = waitForErrorDialog();
|
||||
String message = errDlg.getMessage();
|
||||
assertEquals("Latest and Checked Out program versions do not have the same type for " +
|
||||
"'testMap' property.", message);
|
||||
pressButtonByText(errDlg, "OK");
|
||||
|
||||
chooseUserDefined(addr("0x1002100"), "testMap", KEEP_ORIGINAL);
|
||||
chooseUserDefined(addr("0x1002166"), "testMap", KEEP_LATEST);
|
||||
|
||||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm = resultProgram.getUsrPropertyManager();
|
||||
|
||||
PropertyMap<?> pm = pmm.getPropertyMap("testMap");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x1002166"), address);
|
||||
assertEquals(2L, pm.get(address));
|
||||
|
||||
// TODO: Incompatible maps result in silently discarded property values selected during
|
||||
// merge. This should be handled at map-level and not as a address-level conflict.
|
||||
// (See GP-2585)
|
||||
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveSpaceProperty() throws Exception {
|
||||
// ** DiffTestPgm2 **
|
||||
// 10018ba = 1
|
||||
|
@ -472,9 +696,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -491,9 +712,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -541,16 +759,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.remove(addr(program, "0x100248c"));
|
||||
pm.remove(addr(program, "0x10039f8"));
|
||||
commit = true;
|
||||
|
@ -560,16 +775,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.remove(addr(program, "0x10039f1"));
|
||||
pm.remove(addr(program, "0x10039f8"));
|
||||
commit = true;
|
||||
|
@ -584,11 +796,11 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm = resultProgram.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.GREEN), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.GREEN), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -607,9 +819,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -629,9 +838,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -690,16 +896,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.remove(addr(program, "0x100248c"));
|
||||
pm.remove(addr(program, "0x10039f1"));
|
||||
pm.add(addr(program, "0x10039f8"), new SaveableColor(Color.BLUE));
|
||||
|
@ -711,16 +914,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.add(addr(program, "0x100248c"), new SaveableColor(Color.RED));
|
||||
pm.add(addr(program, "0x10039f1"), new SaveableColor(Color.ORANGE));
|
||||
pm.remove(addr(program, "0x10039f8"));
|
||||
|
@ -741,14 +941,14 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm = resultProgram.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.ORANGE), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.ORANGE), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLUE), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLUE), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -767,9 +967,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -788,9 +985,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -851,16 +1045,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.add(addr(program, "0x100248c"), new SaveableColor(Color.BLUE));
|
||||
pm.add(addr(program, "0x10039f8"), new SaveableColor(Color.ORANGE));
|
||||
pm.add(addr(program, "0x10039fe"), new SaveableColor(Color.PINK));
|
||||
|
@ -871,16 +1062,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.add(addr(program, "0x10039f1"), new SaveableColor(Color.RED));
|
||||
pm.add(addr(program, "0x10039f8"), new SaveableColor(Color.ORANGE));
|
||||
pm.add(addr(program, "0x10039fe"), new SaveableColor(Color.YELLOW));
|
||||
|
@ -897,20 +1085,20 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm = resultProgram.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x100248c"), address);
|
||||
assertEquals(new SaveableColor(Color.BLUE), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLUE), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.RED), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.RED), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.ORANGE), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.ORANGE), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.YELLOW), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.YELLOW), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -929,9 +1117,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -950,9 +1135,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -1004,16 +1186,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.remove(addr(program, "0x100248c"));
|
||||
pm.remove(addr(program, "0x10039f1"));
|
||||
pm.add(addr(program, "0x10039f8"), new SaveableColor(Color.BLUE));
|
||||
|
@ -1025,16 +1204,13 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
boolean commit = false;
|
||||
try {
|
||||
PropertyMapManager pmm = program.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
pm.add(addr(program, "0x100248c"), new SaveableColor(Color.RED));
|
||||
pm.add(addr(program, "0x10039f1"), new SaveableColor(Color.ORANGE));
|
||||
pm.remove(addr(program, "0x10039f8"));
|
||||
|
@ -1052,14 +1228,14 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
waitForMergeCompletion();
|
||||
|
||||
PropertyMapManager pmm = resultProgram.getUsrPropertyManager();
|
||||
ObjectPropertyMap pm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> pm = pmm.getObjectPropertyMap("testColor");
|
||||
Address address = resultProgram.getMinAddress();
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x100248c"), address);
|
||||
assertEquals(new SaveableColor(Color.RED), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.RED), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.ORANGE), pm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.ORANGE), pm.get(address));
|
||||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -1078,9 +1254,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -1094,7 +1267,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x1002428"), 4);
|
||||
ipm.add(addr(program, "0x100248c"), 5);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.remove(addr(program, "0x100248c"));
|
||||
opm.remove(addr(program, "0x10039f1"));
|
||||
opm.add(addr(program, "0x10039f8"), new SaveableColor(Color.BLUE));
|
||||
|
@ -1107,9 +1280,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -1123,7 +1293,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x1002428"), 3);
|
||||
ipm.add(addr(program, "0x100248c"), 6);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.add(addr(program, "0x100248c"), new SaveableColor(Color.RED));
|
||||
opm.add(addr(program, "0x10039f1"), new SaveableColor(Color.ORANGE));
|
||||
opm.remove(addr(program, "0x10039f8"));
|
||||
|
@ -1168,14 +1338,14 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
address = ipm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
address = resultProgram.getMinAddress();
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.ORANGE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.ORANGE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLUE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLUE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -1194,9 +1364,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -1210,7 +1377,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x1002428"), 4);
|
||||
ipm.add(addr(program, "0x100248c"), 5);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.remove(addr(program, "0x100248c"));
|
||||
opm.remove(addr(program, "0x10039f1"));
|
||||
opm.add(addr(program, "0x10039f8"), new SaveableColor(Color.BLUE));
|
||||
|
@ -1223,9 +1390,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -1239,7 +1403,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.remove(addr(program, "0x1002428"));
|
||||
ipm.remove(addr(program, "0x100248c"));
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.add(addr(program, "0x100248c"), new SaveableColor(Color.RED));
|
||||
opm.add(addr(program, "0x10039f1"), new SaveableColor(Color.ORANGE));
|
||||
opm.remove(addr(program, "0x10039f8"));
|
||||
|
@ -1277,14 +1441,14 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
address = resultProgram.getMinAddress();
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.ORANGE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.ORANGE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLUE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLUE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -1303,9 +1467,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -1321,7 +1482,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x10061e0"), 2);
|
||||
ipm.add(addr(program, "0x10018ea"), 1);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.remove(addr(program, "0x100248c"));
|
||||
opm.remove(addr(program, "0x10039f1"));
|
||||
opm.add(addr(program, "0x10039f8"), new SaveableColor(Color.BLUE));
|
||||
|
@ -1334,9 +1495,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -1352,7 +1510,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x10061e0"), 3);
|
||||
ipm.add(addr(program, "0x10018ea"), 4);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.add(addr(program, "0x100248c"), new SaveableColor(Color.RED));
|
||||
opm.add(addr(program, "0x10039f1"), new SaveableColor(Color.ORANGE));
|
||||
opm.remove(addr(program, "0x10039f8"));
|
||||
|
@ -1393,14 +1551,14 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
address = resultProgram.getMinAddress();
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLUE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLUE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.PINK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.PINK), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
||||
|
@ -1419,9 +1577,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
|
||||
mtf.initialize("DiffTestPgm2", new ProgramModifierListener() {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyLatest(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify Latest Program");
|
||||
|
@ -1437,7 +1592,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x10061e0"), 2);
|
||||
ipm.add(addr(program, "0x10018ea"), 1);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.remove(addr(program, "0x100248c"));
|
||||
opm.remove(addr(program, "0x10039f1"));
|
||||
opm.add(addr(program, "0x10039f8"), new SaveableColor(Color.BLUE));
|
||||
|
@ -1450,9 +1605,6 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.data.ProgramModifierListener#modifyPrivate(ghidra.program.database.ProgramDB)
|
||||
*/
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
int txId = program.startTransaction("Modify My Program");
|
||||
|
@ -1468,7 +1620,7 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
ipm.add(addr(program, "0x10061e0"), 3);
|
||||
ipm.add(addr(program, "0x10018ea"), 4);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
opm.add(addr(program, "0x100248c"), new SaveableColor(Color.RED));
|
||||
opm.add(addr(program, "0x10039f1"), new SaveableColor(Color.ORANGE));
|
||||
opm.remove(addr(program, "0x10039f8"));
|
||||
|
@ -1509,20 +1661,20 @@ public class UserDefinedMergeManagerTest extends AbstractListingMergeManagerTest
|
|||
address = pm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
|
||||
ObjectPropertyMap opm = pmm.getObjectPropertyMap("testColor");
|
||||
ObjectPropertyMap<?> opm = pmm.getObjectPropertyMap("testColor");
|
||||
address = resultProgram.getMinAddress();
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x100248c"), address);
|
||||
assertEquals(new SaveableColor(Color.WHITE), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.WHITE), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f1"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039f8"), address);
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.BLACK), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertEquals(addr("0x10039fe"), address);
|
||||
assertEquals(new SaveableColor(Color.GREEN), opm.getObject(address));
|
||||
assertEquals(new SaveableColor(Color.GREEN), opm.get(address));
|
||||
address = opm.getNextPropertyAddress(address);
|
||||
assertNull(address);
|
||||
}
|
|
@ -25,26 +25,23 @@ import org.junit.*;
|
|||
|
||||
import db.*;
|
||||
import db.util.ErrorHandler;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.program.database.ProgramBuilder;
|
||||
import ghidra.program.database.ProgramDB;
|
||||
import ghidra.program.database.map.AddressMap;
|
||||
import ghidra.program.database.mem.MemoryMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.util.*;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.program.util.ChangeManagerAdapter;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.util.Lock;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTest
|
||||
implements ChangeManager, ErrorHandler {
|
||||
implements ErrorHandler {
|
||||
|
||||
private static final File testDir = new File(AbstractGenericTest.getTestDirectoryPath());
|
||||
private static final File testDir = new File(getTestDirectoryPath());
|
||||
private static File dbFile = new File(testDir, "test.dbf");
|
||||
|
||||
private DBHandle dbh;
|
||||
|
@ -55,24 +52,22 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
private DBPropertyMapManager mgr;
|
||||
private int transactionID;
|
||||
|
||||
private final ChangeManager changeMgr = new ChangeManagerAdapter();
|
||||
|
||||
/**
|
||||
* Constructor for DBPropertyMapManagerTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public DBPropertyMapManagerTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
|
||||
dbh = program.getDBHandle();
|
||||
addrSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
memMap = (MemoryMapDB) program.getMemory();
|
||||
memMap = program.getMemory();
|
||||
addrMap = (AddressMap) getInstanceField("addrMap", memMap);
|
||||
mgr = (DBPropertyMapManager) program.getUsrPropertyManager();
|
||||
|
||||
|
@ -83,9 +78,6 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
dbFile.delete();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#tearDown()
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (program != null) {
|
||||
|
@ -135,7 +127,8 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
|
||||
@Test
|
||||
public void testCreateObjectPropertyMap() throws Exception {
|
||||
ObjectPropertyMap map = mgr.createObjectPropertyMap("TEST", TestSaveable.class);
|
||||
ObjectPropertyMap<TestSaveable> map =
|
||||
mgr.createObjectPropertyMap("TEST", TestSaveable.class);
|
||||
map.add(addr(100), new TestSaveable());
|
||||
program.endTransaction(transactionID, true);
|
||||
assertEquals(map.getSize(), 1);
|
||||
|
@ -160,9 +153,10 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
PropertyMap pmap = mgr.getPropertyMap("TEST");
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
PropertyMap<?> pmap = mgr.getPropertyMap("TEST");
|
||||
assertEquals(1, pmap.getSize());
|
||||
}
|
||||
|
||||
|
@ -177,9 +171,10 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
PropertyMap pmap = mgr.getPropertyMap("TEST");
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
PropertyMap<?> pmap = mgr.getPropertyMap("TEST");
|
||||
assertEquals(1, pmap.getSize());
|
||||
}
|
||||
|
||||
|
@ -194,9 +189,10 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
PropertyMap pmap = mgr.getPropertyMap("TEST");
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
PropertyMap<?> pmap = mgr.getPropertyMap("TEST");
|
||||
assertEquals(1, pmap.getSize());
|
||||
}
|
||||
|
||||
|
@ -211,15 +207,17 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
PropertyMap pmap = mgr.getPropertyMap("TEST");
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
PropertyMap<?> pmap = mgr.getPropertyMap("TEST");
|
||||
assertEquals(1, pmap.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetObjectPropertyMap() throws Exception {
|
||||
ObjectPropertyMap map = mgr.createObjectPropertyMap("TEST", TestSaveable.class);
|
||||
ObjectPropertyMap<TestSaveable> map =
|
||||
mgr.createObjectPropertyMap("TEST", TestSaveable.class);
|
||||
map.add(addr(100), new TestSaveable());
|
||||
program.endTransaction(transactionID, true);
|
||||
|
||||
|
@ -228,9 +226,10 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
PropertyMap pmap = mgr.getPropertyMap("TEST");
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
PropertyMap<?> pmap = mgr.getPropertyMap("TEST");
|
||||
assertEquals(1, pmap.getSize());
|
||||
}
|
||||
|
||||
|
@ -245,9 +244,10 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
PropertyMap pmap = mgr.getPropertyMap("TEST");
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
PropertyMap<?> pmap = mgr.getPropertyMap("TEST");
|
||||
assertEquals(1, pmap.getSize());
|
||||
}
|
||||
|
||||
|
@ -263,8 +263,9 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
|
||||
dbh = new DBHandle(dbFile);
|
||||
dbh.startTransaction();
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
mgr.removePropertyMap("TEST");
|
||||
|
||||
assertNull(mgr.getIntPropertyMap("TEST"));
|
||||
|
@ -281,8 +282,9 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
program = null;
|
||||
|
||||
dbh = new DBHandle(dbFile);
|
||||
mgr = new DBPropertyMapManager(dbh, this, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
mgr =
|
||||
new DBPropertyMapManager(dbh, changeMgr, addrMap, DBConstants.UPDATE, new Lock("TEST"),
|
||||
TaskMonitor.DUMMY);
|
||||
|
||||
int cnt = 0;
|
||||
Iterator<String> iter = mgr.propertyManagers();
|
||||
|
@ -294,112 +296,9 @@ public class DBPropertyMapManagerTest extends AbstractGhidraHeadedIntegrationTes
|
|||
assertEquals(cnt, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for void removeAll(Address)
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveAll() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for void removeAll(Address, Address)
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveAllRange() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setChanged(int, ghidra.program.model.address.Address, ghidra.program.model.address.Address, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setChanged(int type, Address start, Address end, Object oldValue, Object newValue) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setChanged(int, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setChanged(int type, Object oldValue, Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setObjChanged(int, ghidra.program.model.address.Address, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setObjChanged(int type, Address addr, Object affectedObj, Object oldValue,
|
||||
Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setObjChanged(int, int, ghidra.program.model.address.Address, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setObjChanged(int type, int subType, Address addr, Object affectedObj,
|
||||
Object oldValue, Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setObjChanged(int, ghidra.program.model.address.AddressSetView, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setObjChanged(int type, AddressSetView addrSet, Object affectedObj, Object oldValue,
|
||||
Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setObjChanged(int, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setObjChanged(int type, Object affectedObj, Object oldValue, Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setObjChanged(int, int, java.lang.Object, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setObjChanged(int type, int subType, Object affectedObj, Object oldValue,
|
||||
Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setPropertyChanged(java.lang.String, ghidra.program.model.address.Address, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void setPropertyChanged(String propertyName, Address codeUnitAddr, Object oldValue,
|
||||
Object newValue) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setPropertyRangeRemoved(java.lang.String, ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void setPropertyRangeRemoved(String propertyName, Address start, Address end) {
|
||||
}
|
||||
|
||||
/*
|
||||
* @see ghidra.util.ErrorHandler#dbError(java.io.IOException)
|
||||
*/
|
||||
@Override
|
||||
public void dbError(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setDataTypeChanged(int, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public void setDataTypeChanged(int type, Object obj1, Object obj2) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.util.ChangeManager#setRegisterValuesChanged(ghidra.program.model.lang.Register, ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void setRegisterValuesChanged(Register register, Address start, Address end) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,10 +30,8 @@ import ghidra.program.database.map.AddressMap;
|
|||
import ghidra.program.database.mem.MemoryMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -51,22 +49,18 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
|
||||
/**
|
||||
* Constructor for IntPropertyMapDBTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public IntPropertyMapDBTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
|
||||
db = program.getDBHandle();
|
||||
addrSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
memMap = (MemoryMapDB) program.getMemory();
|
||||
memMap = program.getMemory();
|
||||
addrMap = (AddressMap) getInstanceField("addrMap", memMap);
|
||||
transactionID = program.startTransaction("Test");
|
||||
|
||||
|
@ -75,9 +69,6 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
random = new Random(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#tearDown()
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
program.endTransaction(transactionID, true);
|
||||
|
@ -91,7 +82,7 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
|
||||
private void createPropertyMap(String name) throws Exception {
|
||||
propertyMap = new IntPropertyMapDB(db, DBConstants.CREATE, this, null, addrMap, name,
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
TaskMonitor.DUMMY);
|
||||
propertyMap.setCacheSize(2);
|
||||
}
|
||||
|
||||
|
@ -139,6 +130,7 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +148,6 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
|
||||
@Test
|
||||
public void testApplyValue() throws Exception {
|
||||
MyIntVisitor visitor = new MyIntVisitor();
|
||||
createPropertyMap("TEST");
|
||||
|
||||
int[] values = new int[20];
|
||||
|
@ -165,10 +156,8 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
propertyMap.add(addr(i * 100), values[i]);
|
||||
}
|
||||
for (int i = 0; i < 20; i++) {
|
||||
propertyMap.applyValue(visitor, addr(i * 100));
|
||||
assertEquals(values[i], visitor.value);
|
||||
assertEquals(values[i], propertyMap.getInt(addr(i * 100)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -226,6 +215,7 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
propertyMap.removeRange(addr(1900), addr(2050));
|
||||
assertEquals(17, propertyMap.getSize());
|
||||
|
@ -234,6 +224,7 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,6 +247,7 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
propertyMap.remove(addr(1900));
|
||||
assertEquals(18, propertyMap.getSize());
|
||||
|
@ -264,6 +256,7 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,47 +455,9 @@ public class IntPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest im
|
|||
assertNull(iter.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.db.util.ErrorHandler#dbError(java.io.IOException)
|
||||
*/
|
||||
@Override
|
||||
public void dbError(IOException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MyIntVisitor implements PropertyVisitor {
|
||||
|
||||
int value;
|
||||
|
||||
/** Handle the case of a void property type. */
|
||||
@Override
|
||||
public void visit() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a String property type. */
|
||||
@Override
|
||||
public void visit(String value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of an Object property type. */
|
||||
@Override
|
||||
public void visit(Object value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a Saveable property type*/
|
||||
@Override
|
||||
public void visit(Saveable value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of an int property type. */
|
||||
@Override
|
||||
public void visit(int value1) {
|
||||
this.value = value1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import ghidra.program.database.mem.MemoryMapDB;
|
|||
import ghidra.program.model.address.*;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -49,22 +49,18 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
|
||||
/**
|
||||
* Constructor for LongPropertyMapDBTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public LongPropertyMapDBTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
|
||||
db = program.getDBHandle();
|
||||
addrSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
memMap = (MemoryMapDB) program.getMemory();
|
||||
memMap = program.getMemory();
|
||||
addrMap = (AddressMap) getInstanceField("addrMap", memMap);
|
||||
transactionID = program.startTransaction("Test");
|
||||
|
||||
|
@ -73,9 +69,6 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
random = new Random(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#tearDown()
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
program.endTransaction(transactionID, true);
|
||||
|
@ -89,7 +82,7 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
|
||||
private void createPropertyMap(String name) throws Exception {
|
||||
propertyMap = new LongPropertyMapDB(db, DBConstants.CREATE, this, null, addrMap, name,
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
TaskMonitor.DUMMY);
|
||||
propertyMap.setCacheSize(2);
|
||||
}
|
||||
|
||||
|
@ -137,6 +130,7 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,21 +146,19 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
assertEquals(propertyMap.getSize(), 20);
|
||||
}
|
||||
|
||||
// public void testApplyValue() throws Exception {
|
||||
// MyLongVisitor visitor = new MyLongVisitor();
|
||||
// createPropertyMap("TEST");
|
||||
//
|
||||
// long[] values = new long[20];
|
||||
// for (int i = 0; i < 20; i++) {
|
||||
// values[i] = random.nextInt();
|
||||
// propertyMap.add(addr(i * 100), values[i]);
|
||||
// }
|
||||
// for (int i = 0; i < 20; i++) {
|
||||
// propertyMap.applyValue(visitor, addr(i * 100));
|
||||
// assertEquals(visitor.value, values[i]);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
@Test
|
||||
public void testApplyValue() throws Exception {
|
||||
createPropertyMap("TEST");
|
||||
|
||||
long[] values = new long[20];
|
||||
for (int i = 0; i < 20; i++) {
|
||||
values[i] = random.nextInt();
|
||||
propertyMap.add(addr(i * 100), values[i]);
|
||||
}
|
||||
for (int i = 0; i < 20; i++) {
|
||||
assertEquals(values[i], propertyMap.getLong(addr(i * 100)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception {
|
||||
|
@ -223,6 +215,7 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
propertyMap.removeRange(addr(1900), addr(2050));
|
||||
assertEquals(propertyMap.getSize(), 17);
|
||||
|
@ -231,6 +224,7 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,6 +247,7 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
propertyMap.remove(addr(1900));
|
||||
assertEquals(propertyMap.getSize(), 18);
|
||||
|
@ -261,6 +256,7 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
Assert.fail();
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,9 +455,6 @@ public class LongPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
assertNull(iter.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.db.util.ErrorHandler#dbError(java.io.IOException)
|
||||
*/
|
||||
@Override
|
||||
public void dbError(IOException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
|
|
|
@ -30,9 +30,7 @@ import ghidra.program.database.map.AddressMap;
|
|||
import ghidra.program.database.mem.MemoryMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -44,13 +42,12 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
private AddressSpace addrSpace;
|
||||
private MemoryMapDB memMap;
|
||||
private AddressMap addrMap;
|
||||
private ObjectPropertyMapDB propertyMap;
|
||||
private ObjectPropertyMapDB<TestSaveable> propertyMap;
|
||||
private Random random;
|
||||
private int transactionID;
|
||||
|
||||
/**
|
||||
* Constructor for ObjectPropertyMapDBTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public ObjectPropertyMapDBTest() {
|
||||
super();
|
||||
|
@ -65,7 +62,7 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
|
||||
db = program.getDBHandle();
|
||||
addrSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
memMap = (MemoryMapDB) program.getMemory();
|
||||
memMap = program.getMemory();
|
||||
addrMap = (AddressMap) getInstanceField("addrMap", memMap);
|
||||
transactionID = program.startTransaction("Test");
|
||||
|
||||
|
@ -89,8 +86,8 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
}
|
||||
|
||||
private void createPropertyMap(String name) throws Exception {
|
||||
propertyMap = new ObjectPropertyMapDB(db, DBConstants.CREATE, this, null, addrMap, name,
|
||||
TestSaveable.class, TaskMonitorAdapter.DUMMY_MONITOR, true);
|
||||
propertyMap = new ObjectPropertyMapDB<>(db, DBConstants.CREATE, this, null, addrMap, name,
|
||||
TestSaveable.class, TaskMonitor.DUMMY, true);
|
||||
propertyMap.setCacheSize(2);
|
||||
}
|
||||
|
||||
|
@ -134,11 +131,11 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
propertyMap.add(addr(i * 100), objs[i]);
|
||||
}
|
||||
for (int i = 0; i < 20; i++) {
|
||||
TestSaveable obj = (TestSaveable) propertyMap.getObject(addr(i * 100));
|
||||
TestSaveable obj = propertyMap.get(addr(i * 100));
|
||||
assertEquals(obj, objs[i]);
|
||||
}
|
||||
|
||||
assertNull(propertyMap.getObject(addr(150)));
|
||||
assertNull(propertyMap.get(addr(150)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -155,7 +152,7 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
|
||||
@Test
|
||||
public void testApplyValue() throws Exception {
|
||||
MyObjectVisitor visitor = new MyObjectVisitor();
|
||||
|
||||
createPropertyMap("TEST");
|
||||
|
||||
TestSaveable[] objs = new TestSaveable[20];
|
||||
|
@ -164,10 +161,8 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
propertyMap.add(addr(i * 100), objs[i]);
|
||||
}
|
||||
for (int i = 0; i < 20; i++) {
|
||||
propertyMap.applyValue(visitor, addr(i * 100));
|
||||
assertEquals(visitor.value, objs[i]);
|
||||
assertEquals(objs[i], propertyMap.get(addr(i * 100)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -220,10 +215,10 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
assertEquals(propertyMap.getSize(), 20);
|
||||
propertyMap.removeRange(addr(50), addr(250));
|
||||
assertEquals(propertyMap.getSize(), 18);
|
||||
assertNull(propertyMap.getObject(addr(200)));
|
||||
assertNull(propertyMap.get(addr(200)));
|
||||
propertyMap.removeRange(addr(1900), addr(2050));
|
||||
assertEquals(propertyMap.getSize(), 17);
|
||||
assertNull(propertyMap.getObject(addr(1900)));
|
||||
assertNull(propertyMap.get(addr(1900)));
|
||||
|
||||
}
|
||||
|
||||
|
@ -241,10 +236,10 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
assertEquals(propertyMap.getSize(), 20);
|
||||
propertyMap.remove(addr(200));
|
||||
assertEquals(propertyMap.getSize(), 19);
|
||||
assertNull(propertyMap.getObject(addr(200)));
|
||||
assertNull(propertyMap.get(addr(200)));
|
||||
propertyMap.remove(addr(1900));
|
||||
assertEquals(propertyMap.getSize(), 18);
|
||||
assertNull(propertyMap.getObject(addr(1900)));
|
||||
assertNull(propertyMap.get(addr(1900)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -442,9 +437,6 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
assertNull(iter.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.db.util.ErrorHandler#dbError(java.io.IOException)
|
||||
*/
|
||||
@Override
|
||||
public void dbError(IOException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
|
@ -521,38 +513,3 @@ public class ObjectPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
class MyObjectVisitor implements PropertyVisitor {
|
||||
|
||||
Saveable value;
|
||||
|
||||
/** Handle the case of a void property type. */
|
||||
@Override
|
||||
public void visit() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a String property type. */
|
||||
@Override
|
||||
public void visit(String value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of an Object property type. */
|
||||
@Override
|
||||
public void visit(Object value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a Saveable property type*/
|
||||
@Override
|
||||
public void visit(Saveable value1) {
|
||||
this.value = value1;
|
||||
}
|
||||
|
||||
/** Handle the case of an int property type. */
|
||||
@Override
|
||||
public void visit(int value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,7 @@ import ghidra.program.database.map.AddressMap;
|
|||
import ghidra.program.database.mem.MemoryMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class StringPropertyMapDBTest extends AbstractGhidraHeadlessIntegrationTest implements ErrorHandler {
|
||||
|
||||
|
@ -54,7 +52,7 @@ public class StringPropertyMapDBTest extends AbstractGhidraHeadlessIntegrationTe
|
|||
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
|
||||
db = program.getDBHandle();
|
||||
addrSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
memMap = (MemoryMapDB) program.getMemory();
|
||||
memMap = program.getMemory();
|
||||
addrMap = (AddressMap) getInstanceField("addrMap", memMap);
|
||||
transactionID = program.startTransaction("Test");
|
||||
|
||||
|
@ -79,7 +77,7 @@ public class StringPropertyMapDBTest extends AbstractGhidraHeadlessIntegrationTe
|
|||
|
||||
private void createPropertyMap(String name) throws Exception {
|
||||
propertyMap = new StringPropertyMapDB(db, DBConstants.CREATE, this, null, addrMap, name,
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
TaskMonitor.DUMMY);
|
||||
propertyMap.setCacheSize(2);
|
||||
}
|
||||
|
||||
|
@ -144,7 +142,6 @@ public class StringPropertyMapDBTest extends AbstractGhidraHeadlessIntegrationTe
|
|||
|
||||
@Test
|
||||
public void testApplyValue() throws Exception {
|
||||
MyStringVisitor visitor = new MyStringVisitor();
|
||||
createPropertyMap("TEST");
|
||||
|
||||
String[] values = new String[20];
|
||||
|
@ -153,10 +150,8 @@ public class StringPropertyMapDBTest extends AbstractGhidraHeadlessIntegrationTe
|
|||
propertyMap.add(addr(i * 100), values[i]);
|
||||
}
|
||||
for (int i = 0; i < 20; i++) {
|
||||
propertyMap.applyValue(visitor, addr(i * 100));
|
||||
assertEquals(visitor.value, values[i]);
|
||||
assertEquals(values[i], propertyMap.getString(addr(i * 100)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -430,47 +425,9 @@ public class StringPropertyMapDBTest extends AbstractGhidraHeadlessIntegrationTe
|
|||
assertNull(iter.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.db.util.ErrorHandler#dbError(java.io.IOException)
|
||||
*/
|
||||
@Override
|
||||
public void dbError(IOException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MyStringVisitor implements PropertyVisitor {
|
||||
|
||||
String value;
|
||||
|
||||
/** Handle the case of a void property type. */
|
||||
@Override
|
||||
public void visit() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a String property type. */
|
||||
@Override
|
||||
public void visit(String value1) {
|
||||
this.value = value1;
|
||||
}
|
||||
|
||||
/** Handle the case of an Object property type. */
|
||||
@Override
|
||||
public void visit(Object value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a Saveable property type*/
|
||||
@Override
|
||||
public void visit(Saveable value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of an int property type. */
|
||||
@Override
|
||||
public void visit(int value1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,7 @@ import ghidra.program.database.map.AddressMap;
|
|||
import ghidra.program.database.mem.MemoryMapDB;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -48,7 +46,6 @@ public class VoidPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
|
||||
/**
|
||||
* Constructor for VoidPropertyMapDBTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public VoidPropertyMapDBTest() {
|
||||
super();
|
||||
|
@ -63,7 +60,7 @@ public class VoidPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
|
||||
db = program.getDBHandle();
|
||||
addrSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
memMap = (MemoryMapDB) program.getMemory();
|
||||
memMap = program.getMemory();
|
||||
addrMap = (AddressMap) getInstanceField("addrMap", memMap);
|
||||
transactionID = program.startTransaction("Test");
|
||||
|
||||
|
@ -87,7 +84,7 @@ public class VoidPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
|
||||
private void createPropertyMap(String name) throws Exception {
|
||||
propertyMap = new VoidPropertyMapDB(db, DBConstants.CREATE, this, null, addrMap, name,
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
TaskMonitor.DUMMY);
|
||||
propertyMap.setCacheSize(2);
|
||||
}
|
||||
|
||||
|
@ -129,18 +126,14 @@ public class VoidPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
|
||||
@Test
|
||||
public void testApplyValue() throws Exception {
|
||||
MyVoidVisitor visitor = new MyVoidVisitor();
|
||||
createPropertyMap("TEST");
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
propertyMap.add(addr(i * 100));
|
||||
propertyMap.add(addr(i * 100), (i % 2) == 0);
|
||||
}
|
||||
for (int i = 0; i < 20; i++) {
|
||||
visitor.state = false;
|
||||
propertyMap.applyValue(visitor, addr(i * 100));
|
||||
assertTrue(visitor.state);
|
||||
assertEquals((i % 2) == 0, propertyMap.hasProperty(addr(i * 100)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -386,47 +379,9 @@ public class VoidPropertyMapDBTest extends AbstractGhidraHeadedIntegrationTest i
|
|||
assertNull(iter.next());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.db.util.ErrorHandler#dbError(java.io.IOException)
|
||||
*/
|
||||
@Override
|
||||
public void dbError(IOException e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MyVoidVisitor implements PropertyVisitor {
|
||||
|
||||
boolean state;
|
||||
|
||||
/** Handle the case of a void property type. */
|
||||
@Override
|
||||
public void visit() {
|
||||
state = true;
|
||||
}
|
||||
|
||||
/** Handle the case of a String property type. */
|
||||
@Override
|
||||
public void visit(String value) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of an Object property type. */
|
||||
@Override
|
||||
public void visit(Object value) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of a Saveable property type*/
|
||||
@Override
|
||||
public void visit(Saveable value) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/** Handle the case of an int property type. */
|
||||
@Override
|
||||
public void visit(int value) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.junit.*;
|
|||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
import ghidra.util.prop.ObjectPropertySet;
|
||||
import ghidra.util.map.ObjectValueMap;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -290,7 +290,7 @@ public class AddressObjectMapTest extends AbstractGenericTest {
|
|||
testMap.addObject("one", setB);
|
||||
|
||||
AddressMapImpl addrMap = (AddressMapImpl) getInstanceField("addrMap", testMap);
|
||||
ObjectPropertySet objMarkers = (ObjectPropertySet) getInstanceField("objMarkers", testMap);
|
||||
ObjectValueMap objMarkers = (ObjectValueMap) getInstanceField("objMarkers", testMap);
|
||||
|
||||
long start = Math.min(addrMap.getKey(startA), addrMap.getKey(startB));
|
||||
long end = Math.max(addrMap.getKey(endA), addrMap.getKey(endB));
|
||||
|
@ -319,7 +319,7 @@ public class AddressObjectMapTest extends AbstractGenericTest {
|
|||
testMap.removeObject("two", setB);
|
||||
|
||||
AddressMapImpl addrMap = (AddressMapImpl) getInstanceField("addrMap", testMap);
|
||||
ObjectPropertySet objMarkers = (ObjectPropertySet) getInstanceField("objMarkers", testMap);
|
||||
ObjectValueMap objMarkers = (ObjectValueMap) getInstanceField("objMarkers", testMap);
|
||||
|
||||
try {
|
||||
long firstMark = objMarkers.getFirstPropertyIndex();
|
||||
|
|
|
@ -64,21 +64,21 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
|
||||
public Map<FGVertex, Point> getVertexLocations(FunctionGraph functionGraph) {
|
||||
ObjectPropertyMap vertexLocationropertyMap =
|
||||
ObjectPropertyMap<SaveablePoint> vertexLocationPropertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
LOCATION_PROPERTY_NAME, SaveablePoint.class, false);
|
||||
|
||||
ObjectPropertyMap groupVertexLocationropertyMap =
|
||||
ObjectPropertyMap<SaveablePoint> groupVertexLocationPropertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
GROUP_LOCATION_PROPERTY_NAME, SaveablePoint.class, false);
|
||||
|
||||
return getVertexLocationsFromPropertyMaps(functionGraph, vertexLocationropertyMap,
|
||||
groupVertexLocationropertyMap);
|
||||
return getVertexLocationsFromPropertyMaps(functionGraph, vertexLocationPropertyMap,
|
||||
groupVertexLocationPropertyMap);
|
||||
}
|
||||
|
||||
private Map<FGVertex, Point> getVertexLocationsFromPropertyMaps(FunctionGraph functionGraph,
|
||||
ObjectPropertyMap vertexLocationPropertyMap,
|
||||
ObjectPropertyMap groupVertexLocationPropertyMap) {
|
||||
ObjectPropertyMap<SaveablePoint> vertexLocationPropertyMap,
|
||||
ObjectPropertyMap<SaveablePoint> groupVertexLocationPropertyMap) {
|
||||
|
||||
Map<FGVertex, Point> map = new HashMap<>();
|
||||
Graph<FGVertex, FGEdge> graph = functionGraph;
|
||||
|
@ -95,8 +95,8 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
|
||||
private SaveablePoint getPointFromPropertyMap(FGVertex vertex,
|
||||
ObjectPropertyMap vertexLocationPropertyMap,
|
||||
ObjectPropertyMap groupVertexLocationPropertyMap) {
|
||||
ObjectPropertyMap<SaveablePoint> vertexLocationPropertyMap,
|
||||
ObjectPropertyMap<SaveablePoint> groupVertexLocationPropertyMap) {
|
||||
|
||||
Address address = vertex.getVertexAddress();
|
||||
if (vertex instanceof GroupedFunctionGraphVertex) {
|
||||
|
@ -104,17 +104,17 @@ public class FunctionGraphVertexAttributes {
|
|||
return null;
|
||||
}
|
||||
|
||||
return (SaveablePoint) groupVertexLocationPropertyMap.getObject(address);
|
||||
return groupVertexLocationPropertyMap.get(address);
|
||||
}
|
||||
|
||||
if (vertexLocationPropertyMap == null) {
|
||||
return null;
|
||||
}
|
||||
return (SaveablePoint) vertexLocationPropertyMap.getObject(address);
|
||||
return vertexLocationPropertyMap.get(address);
|
||||
}
|
||||
|
||||
public Element getGroupedVertexSettings(FunctionGraph functionGraph) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableXML> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
GROUP_SETTINGS_PROPERTY_NAME, SaveableXML.class, false);
|
||||
if (propertyMap == null) {
|
||||
|
@ -123,7 +123,7 @@ public class FunctionGraphVertexAttributes {
|
|||
|
||||
FGVertex rootVertex = functionGraph.getRootVertex();
|
||||
Address entryPoint = rootVertex.getVertexAddress();
|
||||
SaveableXML saveableXML = (SaveableXML) propertyMap.getObject(entryPoint);
|
||||
SaveableXML saveableXML = propertyMap.get(entryPoint);
|
||||
if (saveableXML != null) {
|
||||
return saveableXML.getElement();
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
|
||||
public Element getRegroupVertexSettings(FunctionGraph functionGraph) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableXML> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
REGROUP_SETTINGS_PROPERTY_NAME, SaveableXML.class, false);
|
||||
if (propertyMap == null) {
|
||||
|
@ -141,7 +141,7 @@ public class FunctionGraphVertexAttributes {
|
|||
|
||||
FGVertex rootVertex = functionGraph.getRootVertex();
|
||||
Address entryPoint = rootVertex.getVertexAddress();
|
||||
SaveableXML saveableXML = (SaveableXML) propertyMap.getObject(entryPoint);
|
||||
SaveableXML saveableXML = propertyMap.get(entryPoint);
|
||||
if (saveableXML != null) {
|
||||
return saveableXML.getElement();
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
|
||||
public Map<FGVertex, Color> getVertexColors(FunctionGraph functionGraph) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableColor> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
COLOR_PROPERTY_NAME, SaveableColor.class, false);
|
||||
if (propertyMap == null) {
|
||||
|
@ -163,7 +163,7 @@ public class FunctionGraphVertexAttributes {
|
|||
for (FGVertex vertex : vertices) {
|
||||
AddressSetView codeBlock = vertex.getAddresses();
|
||||
Address minAddress = codeBlock.getMinAddress();
|
||||
SaveableColor saveableColor = (SaveableColor) propertyMap.getObject(minAddress);
|
||||
SaveableColor saveableColor = propertyMap.get(minAddress);
|
||||
if (saveableColor != null) {
|
||||
Color color = saveableColor.getColor();
|
||||
map.put(vertex, color);
|
||||
|
@ -174,6 +174,7 @@ public class FunctionGraphVertexAttributes {
|
|||
|
||||
/**
|
||||
* Clears all vertex locations (including group vertex locations).
|
||||
* @param functionGraph function graph
|
||||
*/
|
||||
public void clearVertexLocations(FunctionGraph functionGraph) {
|
||||
locationUpdateMap.clear(); // clear any unsaved changes
|
||||
|
@ -181,12 +182,12 @@ public class FunctionGraphVertexAttributes {
|
|||
|
||||
int transactionID = programUserData.startTransaction();
|
||||
try {
|
||||
ObjectPropertyMap vertexLocationPropertyMap =
|
||||
ObjectPropertyMap<SaveablePoint> vertexLocationPropertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
LOCATION_PROPERTY_NAME, SaveablePoint.class, false);
|
||||
clearMap(vertexLocationPropertyMap, functionGraph);
|
||||
|
||||
ObjectPropertyMap groupVertexLocationPropertyMap =
|
||||
ObjectPropertyMap<SaveablePoint> groupVertexLocationPropertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
GROUP_LOCATION_PROPERTY_NAME, SaveablePoint.class, false);
|
||||
clearMap(groupVertexLocationPropertyMap, functionGraph);
|
||||
|
@ -196,7 +197,8 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
}
|
||||
|
||||
private void clearMap(ObjectPropertyMap propertyMap, FunctionGraph functionGraph) {
|
||||
private void clearMap(ObjectPropertyMap<SaveablePoint> propertyMap,
|
||||
FunctionGraph functionGraph) {
|
||||
if (propertyMap == null) {
|
||||
return; // nothing to do
|
||||
}
|
||||
|
@ -212,13 +214,14 @@ public class FunctionGraphVertexAttributes {
|
|||
|
||||
/**
|
||||
* Note: this method does not clear group vertex locations.
|
||||
* @param functionGraph function graph
|
||||
*/
|
||||
public void clearGroupSettings(FunctionGraph functionGraph) {
|
||||
groupedSettingsUpdateMap.clear(); // clear any unsaved changes
|
||||
|
||||
int transactionID = programUserData.startTransaction();
|
||||
try {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableXML> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
GROUP_SETTINGS_PROPERTY_NAME, SaveableXML.class, false);
|
||||
|
||||
|
@ -239,7 +242,7 @@ public class FunctionGraphVertexAttributes {
|
|||
|
||||
int transactionID = programUserData.startTransaction();
|
||||
try {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableXML> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
REGROUP_SETTINGS_PROPERTY_NAME, SaveableXML.class, false);
|
||||
|
||||
|
@ -258,9 +261,9 @@ public class FunctionGraphVertexAttributes {
|
|||
public void clearAllPropertiesForAddresses(AddressSetView addresses) {
|
||||
int transactionID = programUserData.startTransaction();
|
||||
try {
|
||||
List<PropertyMap> properties =
|
||||
List<PropertyMap<?>> properties =
|
||||
programUserData.getProperties(FunctionGraphPlugin.class.getSimpleName());
|
||||
for (PropertyMap propertyMap : properties) {
|
||||
for (PropertyMap<?> propertyMap : properties) {
|
||||
clearAllPropertiesForAddressRange(propertyMap, addresses);
|
||||
}
|
||||
}
|
||||
|
@ -272,9 +275,9 @@ public class FunctionGraphVertexAttributes {
|
|||
public void clearPropertyForAddresses(String propertyName, AddressSetView addresses) {
|
||||
int transactionID = programUserData.startTransaction();
|
||||
try {
|
||||
List<PropertyMap> properties =
|
||||
List<PropertyMap<?>> properties =
|
||||
programUserData.getProperties(FunctionGraphPlugin.class.getSimpleName());
|
||||
for (PropertyMap propertyMap : properties) {
|
||||
for (PropertyMap<?> propertyMap : properties) {
|
||||
if (propertyMap.getName().equals(propertyName)) {
|
||||
clearAllPropertiesForAddressRange(propertyMap, addresses);
|
||||
return;
|
||||
|
@ -286,7 +289,7 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
}
|
||||
|
||||
private void clearAllPropertiesForAddressRange(PropertyMap propertyMap,
|
||||
private void clearAllPropertiesForAddressRange(PropertyMap<?> propertyMap,
|
||||
AddressSetView addresses) {
|
||||
AddressIterator iterator = addresses.getAddresses(true);
|
||||
for (; iterator.hasNext();) {
|
||||
|
@ -300,35 +303,35 @@ public class FunctionGraphVertexAttributes {
|
|||
try {
|
||||
|
||||
if (!colorUpdateMap.isEmpty()) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableColor> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
COLOR_PROPERTY_NAME, SaveableColor.class, true);
|
||||
saveMap(colorUpdateMap, propertyMap);
|
||||
}
|
||||
|
||||
if (!locationUpdateMap.isEmpty()) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveablePoint> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
LOCATION_PROPERTY_NAME, SaveablePoint.class, true);
|
||||
saveMap(locationUpdateMap, propertyMap);
|
||||
}
|
||||
|
||||
if (!groupLocationUpdateMap.isEmpty()) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveablePoint> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
GROUP_LOCATION_PROPERTY_NAME, SaveablePoint.class, true);
|
||||
saveMap(groupLocationUpdateMap, propertyMap);
|
||||
}
|
||||
|
||||
if (!groupedSettingsUpdateMap.isEmpty()) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableXML> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
GROUP_SETTINGS_PROPERTY_NAME, SaveableXML.class, true);
|
||||
saveMap(groupedSettingsUpdateMap, propertyMap);
|
||||
}
|
||||
|
||||
if (!regroupSettingsUpdateMap.isEmpty()) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableXML> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
REGROUP_SETTINGS_PROPERTY_NAME, SaveableXML.class, true);
|
||||
saveMap(regroupSettingsUpdateMap, propertyMap);
|
||||
|
@ -339,7 +342,8 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
}
|
||||
|
||||
private void saveMap(Map<Address, Saveable> map, ObjectPropertyMap propertyMap) {
|
||||
private void saveMap(Map<Address, Saveable> map,
|
||||
ObjectPropertyMap<? extends Saveable> propertyMap) {
|
||||
Set<Entry<Address, Saveable>> entrySet = map.entrySet();
|
||||
for (Entry<Address, Saveable> entry : entrySet) {
|
||||
Address key = entry.getKey();
|
||||
|
@ -362,14 +366,14 @@ public class FunctionGraphVertexAttributes {
|
|||
}
|
||||
|
||||
public Color getVertexColor(Address address) {
|
||||
ObjectPropertyMap propertyMap =
|
||||
ObjectPropertyMap<SaveableColor> propertyMap =
|
||||
programUserData.getObjectProperty(FunctionGraphPlugin.class.getSimpleName(),
|
||||
COLOR_PROPERTY_NAME, SaveableColor.class, false);
|
||||
if (propertyMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SaveableColor saveable = (SaveableColor) propertyMap.getObject(address);
|
||||
SaveableColor saveable = propertyMap.get(address);
|
||||
if (saveable == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ src/main/java/ghidra/util/datastruct/package.html||GHIDRA||||END|
|
|||
src/main/java/ghidra/util/graph/attributes/package.html||GHIDRA||||END|
|
||||
src/main/java/ghidra/util/graph/package.html||GHIDRA||||END|
|
||||
src/main/java/ghidra/util/layout/package.html||GHIDRA||||END|
|
||||
src/main/java/ghidra/util/prop/package.html||GHIDRA||||END|
|
||||
src/main/java/ghidra/util/map/package.html||GHIDRA||||END|
|
||||
src/main/java/ghidra/util/xml/package.html||GHIDRA||||END|
|
||||
src/main/resources/generic.log4j.xml||GHIDRA||||END|
|
||||
src/main/resources/generic.log4jdev.xml||GHIDRA||||END|
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -43,81 +42,63 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
this.in = in;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putInt(int)
|
||||
*/
|
||||
@Override
|
||||
public void putInt(int value) {
|
||||
try {
|
||||
out.writeInt(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putByte(byte)
|
||||
*/
|
||||
@Override
|
||||
public void putByte(byte value) {
|
||||
try {
|
||||
out.writeByte(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putShort(short)
|
||||
*/
|
||||
@Override
|
||||
public void putShort(short value) {
|
||||
try {
|
||||
out.writeShort(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putLong(long)
|
||||
*/
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
try {
|
||||
out.writeLong(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putString(String)
|
||||
*/
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
try {
|
||||
out.writeObject(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putBoolean(boolean)
|
||||
*/
|
||||
@Override
|
||||
public void putBoolean(boolean value) {
|
||||
try {
|
||||
out.writeBoolean(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putFloat(float)
|
||||
*/
|
||||
@Override
|
||||
public void putFloat(float value) {
|
||||
try {
|
||||
out.writeFloat(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putDouble(double)
|
||||
*/
|
||||
@Override
|
||||
public void putDouble(double value) {
|
||||
try {
|
||||
out.writeDouble(value);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getInt()
|
||||
*/
|
||||
@Override
|
||||
public int getInt() {
|
||||
try {
|
||||
return in.readInt();
|
||||
|
@ -126,9 +107,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getByte()
|
||||
*/
|
||||
@Override
|
||||
public byte getByte() {
|
||||
try {
|
||||
return in.readByte();
|
||||
|
@ -137,9 +116,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getShort()
|
||||
*/
|
||||
@Override
|
||||
public short getShort() {
|
||||
try {
|
||||
return in.readShort();
|
||||
|
@ -148,9 +125,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getLong()
|
||||
*/
|
||||
@Override
|
||||
public long getLong() {
|
||||
try {
|
||||
return in.readLong();
|
||||
|
@ -159,9 +134,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getBoolean()
|
||||
*/
|
||||
@Override
|
||||
public boolean getBoolean() {
|
||||
try {
|
||||
return in.readBoolean();
|
||||
|
@ -170,9 +143,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getString()
|
||||
*/
|
||||
@Override
|
||||
public String getString() {
|
||||
try {
|
||||
return (String)in.readObject();
|
||||
|
@ -181,9 +152,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getFloat()
|
||||
*/
|
||||
@Override
|
||||
public float getFloat() {
|
||||
try {
|
||||
return in.readFloat();
|
||||
|
@ -192,9 +161,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getDouble()
|
||||
*/
|
||||
@Override
|
||||
public double getDouble() {
|
||||
try {
|
||||
return in.readDouble();
|
||||
|
@ -203,9 +170,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putInts(int[])
|
||||
*/
|
||||
@Override
|
||||
public void putInts(int[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -219,9 +184,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putBytes(byte[])
|
||||
*/
|
||||
@Override
|
||||
public void putBytes(byte[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -235,9 +198,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putShorts(short[])
|
||||
*/
|
||||
@Override
|
||||
public void putShorts(short[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -252,9 +213,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putLongs(long[])
|
||||
*/
|
||||
@Override
|
||||
public void putLongs(long[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -269,9 +228,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putFloats(float[])
|
||||
*/
|
||||
@Override
|
||||
public void putFloats(float[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -286,9 +243,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putDoubles(double[])
|
||||
*/
|
||||
@Override
|
||||
public void putDoubles(double[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -302,9 +257,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#putStrings(String[])
|
||||
*/
|
||||
@Override
|
||||
public void putStrings(String[] value) {
|
||||
try {
|
||||
if (value == null) {
|
||||
|
@ -318,9 +271,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getInts()
|
||||
*/
|
||||
@Override
|
||||
public int[] getInts() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
@ -337,9 +288,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getBytes()
|
||||
*/
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
@ -356,9 +305,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getShorts()
|
||||
*/
|
||||
@Override
|
||||
public short[] getShorts() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
@ -375,9 +322,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getLongs()
|
||||
*/
|
||||
@Override
|
||||
public long[] getLongs() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
@ -394,9 +339,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getFloats()
|
||||
*/
|
||||
@Override
|
||||
public float[] getFloats() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
@ -413,9 +356,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getDoubles()
|
||||
*/
|
||||
@Override
|
||||
public double[] getDoubles() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
@ -432,9 +373,7 @@ public class ObjectStorageStreamAdapter implements ObjectStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.ObjectStorage#getStrings()
|
||||
*/
|
||||
@Override
|
||||
public String[] getStrings() {
|
||||
try {
|
||||
int n = in.readInt();
|
||||
|
|
|
@ -66,8 +66,7 @@ public interface Saveable {
|
|||
* Restore from the given ObjectStorage.
|
||||
* @param objStorage Object that can handle Java primitives, Strings, and
|
||||
* arrays of primitives and Strings
|
||||
* @throws db.IllegalFieldAccessException
|
||||
* if objStorage is improperly accessed.
|
||||
* TODO: document how errors should be handled (i.e, exception, null return)
|
||||
*/
|
||||
void restore(ObjectStorage objStorage);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,7 +16,7 @@
|
|||
package ghidra.util.datastruct;
|
||||
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.prop.PropertySet;
|
||||
import ghidra.util.map.ValueMap;
|
||||
|
||||
/**
|
||||
* Iterator over Property Set Index ranges that have the same value
|
||||
|
@ -28,7 +27,7 @@ public class PropertySetIndexRangeIterator implements IndexRangeIterator {
|
|||
/**
|
||||
* Constructor for PropertySetIndexRangeIterator.
|
||||
*/
|
||||
public PropertySetIndexRangeIterator(PropertySet set, long start) {
|
||||
public PropertySetIndexRangeIterator(ValueMap set, long start) {
|
||||
longIt = set.getPropertyIterator(start+1);
|
||||
|
||||
if (longIt.hasNext()) {
|
||||
|
|
|
@ -17,7 +17,7 @@ package ghidra.util.datastruct;
|
|||
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.IntPropertySet;
|
||||
import ghidra.util.map.IntValueMap;
|
||||
|
||||
/**
|
||||
* Stores ranges of int values throughout "long" space. Every "long" index has
|
||||
|
@ -33,7 +33,7 @@ import ghidra.util.prop.IntPropertySet;
|
|||
*/
|
||||
public class RangeMap {
|
||||
|
||||
IntPropertySet map;
|
||||
IntValueMap map;
|
||||
int defaultValue;
|
||||
|
||||
/**
|
||||
|
@ -48,7 +48,7 @@ public class RangeMap {
|
|||
* @param defaultValue the default value
|
||||
*/
|
||||
public RangeMap(int defaultValue) {
|
||||
map = new IntPropertySet("RangeMap");
|
||||
map = new IntValueMap("RangeMap");
|
||||
this.defaultValue = defaultValue;
|
||||
map.putInt(0, defaultValue);
|
||||
}
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.datastruct;
|
||||
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.ShortPropertySet;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Stores ranges of short values throughout "long" space.
|
||||
* Every "long" index has an associated short value (initially 0).
|
||||
* Users can paint (set) ranges of indexes to a given short integer value,
|
||||
* overwriting any value that currently exists in that range.
|
||||
*
|
||||
* This class is implemented using an ShortPropertySet. The first index
|
||||
* (0) will always contain a value. The value at any other given
|
||||
* index will either be the value stored at that index, or if no
|
||||
* value stored there, then the value stored at the nearest previous index
|
||||
* that contains a value.
|
||||
*/
|
||||
public class ShortRangeMap implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
/** The maximum end of range index allowed. */
|
||||
public static final long LARGEST = 0xffffffffffffffffl;
|
||||
|
||||
ShortPropertySet map;
|
||||
|
||||
/**
|
||||
* Constructor for RangeMap.
|
||||
*/
|
||||
public ShortRangeMap() {
|
||||
map = new ShortPropertySet("RangeMap");
|
||||
map.putShort(0, (short)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the given value with every index from start to end (inclusive)
|
||||
* Any previous associates are overwritten.
|
||||
* @param start the start index of the range to fill.
|
||||
* @param end the end index of the range to fill
|
||||
* @param value the value to put at every index in the range.
|
||||
*/
|
||||
public void paintRange(long start, long end, short value) {
|
||||
|
||||
// first fix up the end of the range, unless the end goes to the END
|
||||
if (end != LARGEST) {
|
||||
short origEndValue = getValue(end+1);
|
||||
if (origEndValue != value) {
|
||||
map.putShort(end+1, origEndValue);
|
||||
}
|
||||
else {
|
||||
map.remove(end+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now remove any values stored from start to end
|
||||
LongIterator it = map.getPropertyIterator(start);
|
||||
while(it.hasNext()) {
|
||||
long next = it.next();
|
||||
if (next <= end) {
|
||||
map.remove(next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (start == 0) {
|
||||
map.putShort(0,value);
|
||||
}
|
||||
else {
|
||||
short startValue = getValue(start);
|
||||
if (startValue != value) {
|
||||
map.putShort(start, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the short value associated with the given index.
|
||||
* @param index the index at which to get the value.
|
||||
*/
|
||||
public short getValue(long index) {
|
||||
try {
|
||||
return map.getShort(index);
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
try {
|
||||
index = map.getPreviousPropertyIndex(index);
|
||||
return map.getShort(index);
|
||||
}
|
||||
catch(NoSuchIndexException ex) {
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Returns an iterator over all occupied ranges in the map.
|
||||
* @param index the index to start the iterator
|
||||
* @return an iterator over all occupied ranges in the map.
|
||||
*/
|
||||
public IndexRangeIterator getIndexRangeIterator(long index) {
|
||||
return new PropertySetIndexRangeIterator(map, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over all indexes where the value changes.
|
||||
* @param start the starting index to search.
|
||||
* @param end the ending index to search.
|
||||
* @return an iterator over all indexes where the value changes.
|
||||
*/
|
||||
public LongIterator getChangePointIterator(long start, long end) {
|
||||
return map.getPropertyIterator(start, end);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,30 +13,29 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of int values indexed by long keys.
|
||||
*
|
||||
* Handles general storage and retrieval of int values indexed by long keys.
|
||||
*/
|
||||
public class IntPropertySet extends PropertySet {
|
||||
public class IntValueMap extends ValueMap<Integer> {
|
||||
private final static long serialVersionUID = 1;
|
||||
|
||||
/**
|
||||
* Constructor for IntPropertySet.
|
||||
* Constructor for IntValueMap.
|
||||
* @param name the name associated with this property set
|
||||
*/
|
||||
public IntPropertySet(String name) {
|
||||
public IntValueMap(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
* @see ValueMap#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
|
@ -51,7 +49,7 @@ public class IntPropertySet extends PropertySet {
|
|||
* @param value the int value to store.
|
||||
*/
|
||||
public void putInt(long index, int value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
ValueStoragePage<Integer> page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addInt(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
|
@ -64,28 +62,25 @@ public class IntPropertySet extends PropertySet {
|
|||
* @throws NoValueException if there is no int value stored at the index.
|
||||
*/
|
||||
public int getInt(long index) throws NoValueException {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
ValueStoragePage<Integer> page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getInt(getPageOffset(index));
|
||||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
try {
|
||||
int value = getInt(from);
|
||||
remove(from);
|
||||
putInt(to, value);
|
||||
}catch(NoValueException e) {}
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
try {
|
||||
|
@ -95,25 +90,10 @@ public class IntPropertySet extends PropertySet {
|
|||
throw new AssertException(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index) throws IOException{
|
||||
putInt(index, ois.readInt());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
try {
|
||||
visitor.visit(getInt(addr));
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,18 +13,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Class to iterate over indexes of a PropertyMap.
|
||||
*/
|
||||
class LongIteratorImpl implements LongIterator {
|
||||
|
||||
private PropertySet pm;
|
||||
private ValueMap<?> pm;
|
||||
private long start;
|
||||
private long end;
|
||||
private long current;
|
||||
|
@ -33,7 +32,7 @@ class LongIteratorImpl implements LongIterator {
|
|||
private boolean doesHaveNext;
|
||||
private boolean doesHavePrevious;
|
||||
|
||||
LongIteratorImpl(PropertySet pm) {
|
||||
LongIteratorImpl(ValueMap<?> pm) {
|
||||
this(pm, 0, true);
|
||||
}
|
||||
/**
|
||||
|
@ -45,7 +44,7 @@ class LongIteratorImpl implements LongIterator {
|
|||
* from a call to next(); If before is false, start will be the first index returned
|
||||
* from a call to previous().
|
||||
*/
|
||||
LongIteratorImpl(PropertySet pm, long start, boolean before) {
|
||||
LongIteratorImpl(ValueMap<?> pm, long start, boolean before) {
|
||||
this.pm = pm;
|
||||
this.start = before ? start : (start+1);
|
||||
current = start;
|
||||
|
@ -59,7 +58,7 @@ class LongIteratorImpl implements LongIterator {
|
|||
* @param start the initial property map index position of the iterator
|
||||
* @param end the last property map index position of the iterator
|
||||
*/
|
||||
LongIteratorImpl(PropertySet pm, long start, long end) {
|
||||
LongIteratorImpl(ValueMap<?> pm, long start, long end) {
|
||||
this(pm, start, end, true);
|
||||
}
|
||||
/**
|
||||
|
@ -72,7 +71,7 @@ class LongIteratorImpl implements LongIterator {
|
|||
* @param atStart If true, the iterator goes from start to end.
|
||||
* Otherwise, from end to start.
|
||||
*/
|
||||
LongIteratorImpl(PropertySet pm, long start, long end, boolean atStart) {
|
||||
LongIteratorImpl(ValueMap<?> pm, long start, long end, boolean atStart) {
|
||||
this.pm = pm;
|
||||
this.start =start;
|
||||
this.end = end;
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
|
||||
import ghidra.util.ObjectStorage;
|
||||
import ghidra.util.datastruct.DataTable;
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,26 +13,26 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of object values indexed by long keys.
|
||||
*
|
||||
* @param <T> object property value type
|
||||
*/
|
||||
public class ObjectPropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
public class ObjectValueMap<T extends Object> extends ValueMap<T> {
|
||||
|
||||
/**
|
||||
* Constructor for ObjectPropertySet.
|
||||
* @param name the name associated with this property set.
|
||||
*/
|
||||
public ObjectPropertySet(String name) {
|
||||
public ObjectValueMap(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
* @see ValueMap#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
|
@ -46,8 +45,8 @@ public class ObjectPropertySet extends PropertySet {
|
|||
* @param index the index at which to store the object.
|
||||
* @param value the object to store.
|
||||
*/
|
||||
public void putObject(long index, Object value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
public void putObject(long index, T value) {
|
||||
ValueStoragePage<T> page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addObject(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
|
@ -59,49 +58,32 @@ public class ObjectPropertySet extends PropertySet {
|
|||
* @return the object stored at the given index or null if no object is
|
||||
* stored at the index.
|
||||
*/
|
||||
public Object getObject(long index) {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
public T getObject(long index) {
|
||||
ValueStoragePage<T> page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getObject(getPageOffset(index));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
Object value = getObject(from);
|
||||
T value = getObject(from);
|
||||
remove(from);
|
||||
putObject(to, value);
|
||||
}
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
oos.writeObject(getObject(index));
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
putObject(index, ois.readObject());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
Object obj = getObject(addr);
|
||||
if (obj != null) {
|
||||
visitor.visit(obj);
|
||||
}
|
||||
putObject(index, (T) ois.readObject());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
package ghidra.util.map;
|
||||
|
||||
/**
|
||||
* Exception thrown when a PropertyPage does not support a
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
|
@ -25,10 +25,11 @@ import ghidra.util.exception.AssertException;
|
|||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
/**
|
||||
* Base class for managing properties that are accessed by an index. Property
|
||||
* values are determined by the derived class.
|
||||
* Base class for managing data values that are accessed by an ordered long index key. Specific
|
||||
* data value types are determined by the derived class.
|
||||
* @param <T> data value type
|
||||
*/
|
||||
public abstract class PropertySet implements Serializable {
|
||||
public abstract class ValueMap<T> implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
protected static final NoValueException noValueException = new NoValueException();
|
||||
private final static int DEFAULT_NUMBER_PAGE_BITS = 12;
|
||||
|
@ -37,16 +38,16 @@ public abstract class PropertySet implements Serializable {
|
|||
// size of a short
|
||||
|
||||
private String name;
|
||||
protected PropertyPageIndex propertyPageIndex; // table of pageIDs
|
||||
protected ValueStoragePageIndex propertyPageIndex; // table of pageIDs
|
||||
private int numPageBits; // number of bits from long used as page offset
|
||||
private long pageMask; // a mask for the offset bits, i.e. has a 1 if and only if
|
||||
// the bit is part of the offset
|
||||
protected short pageSize; // max elements in each page
|
||||
protected int numProperties;
|
||||
private Map<Long, PropertyPage> ht;
|
||||
private Class<?> objectClass;
|
||||
private Map<Long, ValueStoragePage<T>> ht;
|
||||
private Class<T> objectClass;
|
||||
|
||||
protected PropertySet(String name, Class<?> objectClass) {
|
||||
protected ValueMap(String name, Class<T> objectClass) {
|
||||
this(name, DEFAULT_NUMBER_PAGE_BITS, objectClass);
|
||||
}
|
||||
|
||||
|
@ -56,8 +57,9 @@ public abstract class PropertySet implements Serializable {
|
|||
* @param numPageBits number of bits to use for the
|
||||
* page size. Will be set to be at least 8 and no
|
||||
* more than 15.
|
||||
* @param objectClass saveable property value class
|
||||
*/
|
||||
protected PropertySet(String name, int numPageBits, Class<?> objectClass) {
|
||||
protected ValueMap(String name, int numPageBits, Class<T> objectClass) {
|
||||
this.objectClass = objectClass;
|
||||
ht = new HashMap<>();
|
||||
|
||||
|
@ -74,7 +76,7 @@ public abstract class PropertySet implements Serializable {
|
|||
pageMask = pageMask >>> (64 - numPageBits); // 64 = size of long
|
||||
|
||||
pageSize = (short) (pageMask + 1);
|
||||
propertyPageIndex = new PropertyPageIndex();
|
||||
propertyPageIndex = new ValueStoragePageIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,18 +97,18 @@ public abstract class PropertySet implements Serializable {
|
|||
/**
|
||||
* Returns property object class associated with this set.
|
||||
*/
|
||||
public Class<?> getObjectClass() {
|
||||
public Class<T> getObjectClass() {
|
||||
return objectClass;
|
||||
}
|
||||
|
||||
protected PropertyPage getPage(long pageId) {
|
||||
protected ValueStoragePage<T> getPage(long pageId) {
|
||||
return ht.get(pageId);
|
||||
}
|
||||
|
||||
protected PropertyPage getOrCreatePage(long pageID) {
|
||||
PropertyPage page = getPage(pageID);
|
||||
protected ValueStoragePage<T> getOrCreatePage(long pageID) {
|
||||
ValueStoragePage<T> page = getPage(pageID);
|
||||
if (page == null) {
|
||||
page = new PropertyPage(pageSize, pageID, getDataSize(), objectClass);
|
||||
page = new ValueStoragePage<T>(pageSize, pageID, getDataSize(), objectClass);
|
||||
ht.put(pageID, page);
|
||||
propertyPageIndex.add(pageID);
|
||||
}
|
||||
|
@ -163,7 +165,7 @@ public abstract class PropertySet implements Serializable {
|
|||
long pageID = getPageID(start);
|
||||
short offset = getPageOffset(start);
|
||||
|
||||
PropertyPage page = getPage(pageID);
|
||||
ValueStoragePage<T> page = getPage(pageID);
|
||||
|
||||
if (page == null) {
|
||||
long nextPageId = propertyPageIndex.getNext(pageID);
|
||||
|
@ -209,7 +211,7 @@ public abstract class PropertySet implements Serializable {
|
|||
long pageID = getPageID(index);
|
||||
short offset = getPageOffset(index);
|
||||
|
||||
PropertyPage page = getPage(pageID);
|
||||
ValueStoragePage<T> page = getPage(pageID);
|
||||
|
||||
return removeFromPage(page, pageID, offset);
|
||||
}
|
||||
|
@ -217,7 +219,7 @@ public abstract class PropertySet implements Serializable {
|
|||
/**
|
||||
* Remove the property on page at offset. If Page is now empty, remove it.
|
||||
*/
|
||||
private boolean removeFromPage(PropertyPage page, long pageID, short offset) {
|
||||
private boolean removeFromPage(ValueStoragePage<T> page, long pageID, short offset) {
|
||||
if (page != null) {
|
||||
|
||||
boolean removed = page.remove(offset);
|
||||
|
@ -239,7 +241,7 @@ public abstract class PropertySet implements Serializable {
|
|||
* @param index the long representation of an address.
|
||||
*/
|
||||
public synchronized boolean hasProperty(long index) {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
ValueStoragePage<T> page = getPage(getPageID(index));
|
||||
if (page == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -255,7 +257,7 @@ public abstract class PropertySet implements Serializable {
|
|||
public synchronized long getNextPropertyIndex(long index) throws NoSuchIndexException {
|
||||
long pageID = getPageID(index);
|
||||
short offset = getPageOffset(index);
|
||||
PropertyPage page = getPage(pageID);
|
||||
ValueStoragePage<T> page = getPage(pageID);
|
||||
|
||||
if (page != null) {
|
||||
short nextOffset = page.getNext(offset);
|
||||
|
@ -294,7 +296,7 @@ public abstract class PropertySet implements Serializable {
|
|||
long pageID = getPageID(index);
|
||||
short offset = getPageOffset(index);
|
||||
|
||||
PropertyPage page = getPage(pageID);
|
||||
ValueStoragePage<T> page = getPage(pageID);
|
||||
|
||||
if (page != null) {
|
||||
short prevOffset = page.getPrevious(offset);
|
||||
|
@ -533,12 +535,4 @@ public abstract class PropertySet implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Based upon the type of property manager that this is, the appropriate
|
||||
* visit() method will be called within the PropertyVisitor.
|
||||
* @param visitor object implementing the PropertyVisitor interface.
|
||||
* @param addr the address of where to visit (get) the property.
|
||||
*/
|
||||
public abstract void applyValue(PropertyVisitor visitor, long addr);
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,22 +19,23 @@
|
|||
* Created on February 20, 2002, 9:30 AM
|
||||
*/
|
||||
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.datastruct.*;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Manages property values of type int, String, Object, and
|
||||
* "void" for a page of possible addresses. Void serves as a marker
|
||||
* for whether an address has a property. The derived class for each type holds
|
||||
* the actual value of the property, and overrides the
|
||||
* appropriate add() and get() methods.
|
||||
* @param <T> property value type
|
||||
*/
|
||||
class PropertyPage implements Serializable {
|
||||
class ValueStoragePage<T> implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
private ShortKeyIndexer indexer;
|
||||
private ShortKeySet keySet; // set of offsets on page having property
|
||||
|
@ -47,12 +47,15 @@ class PropertyPage implements Serializable {
|
|||
private final int threshold; // after number of entries reaches this many,
|
||||
// the data structure for key set switches from
|
||||
// RedBlackKeySet to a BitTree
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param pageSize max number of properties on this page
|
||||
* @param pageID page identifier
|
||||
* @param valueSize
|
||||
* @param objectClass property value type class
|
||||
*/
|
||||
PropertyPage(short pageSize, long pageID, int valueSize, Class<?> objectClass) {
|
||||
ValueStoragePage(short pageSize, long pageID, int valueSize, Class<T> objectClass) {
|
||||
keySet = new RedBlackKeySet((short)(pageSize-1));
|
||||
this.pageSize = pageSize;
|
||||
this.objectClass = objectClass;
|
||||
|
@ -184,30 +187,38 @@ class PropertyPage implements Serializable {
|
|||
}
|
||||
return offset;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the object property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @return saveable object value or null if no value or not a {@link Saveable} property type
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* does not support object values for properties
|
||||
*/
|
||||
Saveable getSaveableObject(short offset) {
|
||||
Saveable getSaveableObject(short offset) throws TypeMismatchException {
|
||||
if (!Saveable.class.isAssignableFrom(objectClass)) {
|
||||
throw new TypeMismatchException();
|
||||
}
|
||||
if (keySet.containsKey(offset)) {
|
||||
int row = getRow(offset,false);
|
||||
|
||||
Saveable so = null;
|
||||
try {
|
||||
Saveable so = (Saveable)objectClass.newInstance();
|
||||
so.restore(new ObjectStorageAdapter(table, row));
|
||||
return so;
|
||||
}catch(IllegalAccessException e) {
|
||||
}catch(InstantiationException e) {
|
||||
so = (Saveable) objectClass.getDeclaredConstructor().newInstance();
|
||||
so.restore(new ObjectStorageAdapter(table, row));
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return so;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the object property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @param value object value to be stored
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* does not support object values for properties
|
||||
*/
|
||||
|
@ -216,36 +227,41 @@ class PropertyPage implements Serializable {
|
|||
int row = getRow(offset,true);
|
||||
value.save(new ObjectStorageAdapter(table, row));
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the object property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @return object value
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* does not support object values for properties
|
||||
*/
|
||||
Object getObject(short offset) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T getObject(short offset) {
|
||||
if (keySet.containsKey(offset)) {
|
||||
int row = getRow(offset,false);
|
||||
return table.getObject(row, 0);
|
||||
return (T) table.getObject(row, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the object property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @param value object value to be stored
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* does not support object values for properties
|
||||
*/
|
||||
void addObject(short offset,Object value) {
|
||||
void addObject(short offset, T value) {
|
||||
addKey(offset);
|
||||
int row = getRow(offset,true);
|
||||
table.putObject(row, 0, value);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the String property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @return string value for specified offset or null
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support String values for properties
|
||||
*/
|
||||
String getString(short offset) {
|
||||
|
@ -259,7 +275,8 @@ class PropertyPage implements Serializable {
|
|||
/**
|
||||
* Add the String property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @param value string value to be stored
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support String values for properties
|
||||
*/
|
||||
void addString(short offset, String value) {
|
||||
|
@ -268,12 +285,13 @@ class PropertyPage implements Serializable {
|
|||
table.putString(row,0,value);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Get the int property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @return integer value for specified offset
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support int values for properties
|
||||
* @throws NoValueException if no value stored for offset
|
||||
*/
|
||||
int getInt(short offset) throws NoValueException {
|
||||
if (keySet.containsKey(offset)) {
|
||||
|
@ -282,10 +300,12 @@ class PropertyPage implements Serializable {
|
|||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the int property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @param value integer value to be stored
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support int values for properties
|
||||
*/
|
||||
void addInt(short offset, int value) {
|
||||
|
@ -294,12 +314,14 @@ class PropertyPage implements Serializable {
|
|||
table.putInt(row,0,value);
|
||||
|
||||
}
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the long property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @return long value for specified offset
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support long values for properties
|
||||
* @throws NoValueException if no value stored for offset
|
||||
*/
|
||||
long getLong(short offset) throws NoValueException {
|
||||
if (keySet.containsKey(offset)) {
|
||||
|
@ -308,10 +330,12 @@ class PropertyPage implements Serializable {
|
|||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the long property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @param value long value to be stored
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support int values for properties
|
||||
*/
|
||||
void addLong(short offset, long value) {
|
||||
|
@ -320,13 +344,14 @@ class PropertyPage implements Serializable {
|
|||
table.putLong(row,0,value);
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the short property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @return short value for specified offset
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support long values for properties
|
||||
* @throws NoValueException if no value stored for offset
|
||||
*/
|
||||
short getShort(short offset) throws NoValueException {
|
||||
if (keySet.containsKey(offset)) {
|
||||
|
@ -335,10 +360,12 @@ class PropertyPage implements Serializable {
|
|||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the short property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @param value short value to be stored
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support int values for properties
|
||||
*/
|
||||
void addShort(short offset, short value) {
|
||||
|
@ -347,13 +374,14 @@ class PropertyPage implements Serializable {
|
|||
table.putShort(row,0,value);
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the long property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @return byte value for specified offset
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support long values for properties
|
||||
* @throws NoValueException if no value stored for offset
|
||||
*/
|
||||
byte getByte(short offset) throws NoValueException {
|
||||
if (keySet.containsKey(offset)) {
|
||||
|
@ -362,10 +390,12 @@ class PropertyPage implements Serializable {
|
|||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the byte property at the given offset.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @param value byte value to be stored
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support int values for properties
|
||||
*/
|
||||
void addByte(short offset, byte value) {
|
||||
|
@ -375,12 +405,10 @@ class PropertyPage implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Mark the given offset as having a property.
|
||||
* @param offset offset into the page
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* @exception ClassCastException thrown if the page
|
||||
* does not support "void" properties
|
||||
*/
|
||||
void add(short offset) {
|
||||
|
@ -391,13 +419,11 @@ class PropertyPage implements Serializable {
|
|||
* Mark the given offset ranges as having a property.
|
||||
* @param startOffset first offset.
|
||||
* @param endOffset last offset.
|
||||
* @exception TypeMismatchException thrown if the page
|
||||
* does not support "void" properties
|
||||
*/
|
||||
void addRange(short startOffset, short endOffset) {
|
||||
addKeys(startOffset, endOffset);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the number of properties on this page.
|
||||
*/
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
package ghidra.util.map;
|
||||
|
||||
import ghidra.util.datastruct.RedBlackLongKeySet;
|
||||
|
||||
|
@ -25,10 +24,10 @@ import java.io.Serializable;
|
|||
* PropertyPageIndex is used to find the property pages before and
|
||||
* after a given property page.
|
||||
*/
|
||||
class PropertyPageIndex implements Serializable {
|
||||
class ValueStoragePageIndex implements Serializable {
|
||||
private RedBlackLongKeySet rbtree;
|
||||
|
||||
public PropertyPageIndex() {
|
||||
public ValueStoragePageIndex() {
|
||||
rbtree = new RedBlackLongKeySet();
|
||||
}
|
||||
|
|
@ -4,6 +4,6 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
</head>
|
||||
<body>
|
||||
Classes for providing general property capabilities
|
||||
Classes for providing general value storage map capabilities
|
||||
</body>
|
||||
</html>
|
|
@ -1,118 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of byte values indexed by long keys.
|
||||
*
|
||||
*/
|
||||
public class BytePropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
/**
|
||||
* Constructor for BytePropertySet.
|
||||
* @param name the name associated with this property set.
|
||||
*/
|
||||
public BytePropertySet(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a byte value at the given index. Any value currently at that
|
||||
* index will be replaced by the new value.
|
||||
* @param index the index at which to store the byte value.
|
||||
* @param value the byte value to store.
|
||||
*/
|
||||
public void putByte(long index, byte value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addByte(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the byte value stored at the given index.
|
||||
* @param index the index at which to retrieve the byte value.
|
||||
* @return byte the value stored at the given index.
|
||||
* @throws NoValueException if there is no byte value stored at the index.
|
||||
*/
|
||||
public byte getByte(long index) throws NoValueException {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getByte(getPageOffset(index));
|
||||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
try {
|
||||
byte value = getByte(from);
|
||||
remove(from);
|
||||
putByte(to, value);
|
||||
}catch(NoValueException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
try {
|
||||
oos.writeByte(getByte(index));
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
throw new AssertException(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index) throws IOException{
|
||||
putByte(index, ois.readByte());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
throw new NotYetImplementedException();
|
||||
// try {
|
||||
// visitor.visit(getLong(addr));
|
||||
// }
|
||||
// catch(NoValueException e) {
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of long values indexed by long keys.
|
||||
*
|
||||
*/
|
||||
public class LongPropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
/**
|
||||
* Constructor for longPropertySet.
|
||||
* @param name the name associated with this property set
|
||||
*/
|
||||
public LongPropertySet(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an long value at the given index. Any value currently at that
|
||||
* index will be replaced by the new value.
|
||||
* @param index the index at which to store the long value.
|
||||
* @param value the long value to store.
|
||||
*/
|
||||
public void putLong(long index, long value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addLong(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the long value stored at the given index.
|
||||
* @param index the index at which to retrieve the long value.
|
||||
* @return long the value stored at the given index.
|
||||
* @throws NoValueException if there is no long value stored at the index.
|
||||
*/
|
||||
public long getLong(long index) throws NoValueException {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getLong(getPageOffset(index));
|
||||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
try {
|
||||
long value = getLong(from);
|
||||
remove(from);
|
||||
putLong(to, value);
|
||||
}catch(NoValueException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
try {
|
||||
oos.writeLong(getLong(index));
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
throw new AssertException(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index) throws IOException{
|
||||
putLong(index, ois.readLong());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(ghidra.util.prop.PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
throw new NotYetImplementedException();
|
||||
// try {
|
||||
// visitor.visit(getLong(addr));
|
||||
// }
|
||||
// catch(NoValueException e) {
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.Saveable;
|
||||
|
||||
/**
|
||||
* PropertyVisitor is an interface for use with user defined
|
||||
* properties when you know the name of the property but not its
|
||||
* type.
|
||||
*/
|
||||
|
||||
public interface PropertyVisitor {
|
||||
/** Handle the case of a void property type. */
|
||||
void visit();
|
||||
/** Handle the case of a String property type. */
|
||||
void visit(String value);
|
||||
/** Handle the case of an Object property type. */
|
||||
void visit(Object value);
|
||||
/** Handle the case of a Saveable property type*/
|
||||
void visit(Saveable value);
|
||||
/** Handle the case of an int property type. */
|
||||
void visit(int value);
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of saveable objects indexed by long
|
||||
* keys.
|
||||
*
|
||||
*/
|
||||
public class SaveableObjectPropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
/**
|
||||
* Constructor for SaveableObjectPropertySet.
|
||||
* @param name the name associated with this property set.
|
||||
*/
|
||||
public SaveableObjectPropertySet(String name, Class<?> objectClass) {
|
||||
super(name, objectClass);
|
||||
if (!Saveable.class.isAssignableFrom(objectClass)) {
|
||||
throw new IllegalArgumentException("Class "+objectClass+
|
||||
"does not implement the Saveable interface");
|
||||
}
|
||||
try {
|
||||
objectClass.newInstance();
|
||||
} catch(Exception e) {
|
||||
throw new IllegalArgumentException("Class "+objectClass+
|
||||
"must be public and have a public, no args, constructor");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a saveable object at the given index. Any object currently at
|
||||
* that index will be replaced by the new object.
|
||||
* @param index the index at which to store the saveable object.
|
||||
* @param value the saveable object to store.
|
||||
*/
|
||||
public void putObject(long index, Saveable value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addSaveableObject(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the saveable object stored at the given index.
|
||||
* @param index the index at which to retrieve the saveable object.
|
||||
* @return the saveable object stored at the given index or null if no
|
||||
* object is stored at the index.
|
||||
*/
|
||||
public Saveable getObject(long index) {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getSaveableObject(getPageOffset(index));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
Saveable value = getObject(from);
|
||||
remove(from);
|
||||
putObject(to, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
Saveable obj = getObject(index);
|
||||
oos.writeObject(obj.getClass().getName());
|
||||
obj.save(new ObjectStorageStreamAdapter(oos));
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index)
|
||||
throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
String className = (String)ois.readObject();
|
||||
Class<?> c = Class.forName(className);
|
||||
Saveable obj = (Saveable)c.newInstance();
|
||||
obj.restore(new ObjectStorageStreamAdapter(ois));
|
||||
putObject(index, obj);
|
||||
} catch (Exception e) {
|
||||
Msg.showError(this, null, null, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
Saveable obj = getObject(addr);
|
||||
if (obj != null) {
|
||||
visitor.visit(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of short values indexed by long keys.
|
||||
*
|
||||
*/
|
||||
public class ShortPropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
/**
|
||||
* Constructor for ShortPropertySet.
|
||||
* @param name the name associated with this property set.
|
||||
*/
|
||||
public ShortPropertySet(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a short value at the given index. Any value currently at that
|
||||
* index will be replaced by the new value.
|
||||
* @param index the index at which to store the short value.
|
||||
* @param value the short value to store.
|
||||
*/
|
||||
public void putShort(long index, short value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addShort(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the short value stored at the given index.
|
||||
* @param index the index at which to retrieve the short value.
|
||||
* @return the value stored at the given index.
|
||||
* @throws NoValueException if there is no short value stored at the index.
|
||||
*/
|
||||
public short getShort(long index) throws NoValueException {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getShort(getPageOffset(index));
|
||||
}
|
||||
throw noValueException;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
try {
|
||||
short value = getShort(from);
|
||||
remove(from);
|
||||
putShort(to, value);
|
||||
}catch(NoValueException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
try {
|
||||
oos.writeShort(getShort(index));
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
throw new AssertException(e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index) throws IOException{
|
||||
putShort(index, ois.readShort());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
throw new NotYetImplementedException();
|
||||
// try {
|
||||
// visitor.visit(getLong(addr));
|
||||
// }
|
||||
// catch(NoValueException e) {
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of Strings indexed by long keys.
|
||||
*
|
||||
*/
|
||||
public class StringPropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
/**
|
||||
* Constructor for StringPropertySet.
|
||||
* @param name the name associated with this property set.
|
||||
*/
|
||||
public StringPropertySet(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a String at the given index. Any String currently at that index
|
||||
* will be replaced by the new String.
|
||||
* @param index the index at which to store the String.
|
||||
* @param value the String to store.
|
||||
*/
|
||||
public void putString(long index, String value) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.addString(getPageOffset(index), value);
|
||||
numProperties += page.getSize() - n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the String stored at the given index.
|
||||
* @param index the index at which to retrieve the String.
|
||||
* @return the String stored at the given index or null if no String is
|
||||
* stored at that index.
|
||||
*/
|
||||
public String getString(long index) {
|
||||
PropertyPage page = getPage(getPageID(index));
|
||||
if (page != null) {
|
||||
return page.getString(getPageOffset(index));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
String value = getString(from);
|
||||
remove(from);
|
||||
putString(to, value);
|
||||
}
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
oos.writeObject(getString(index));
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
putString(index, (String)ois.readObject());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
String str = getString(addr);
|
||||
if (str != null) {
|
||||
visitor.visit(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Handles general storage and retrieval of a void property indexed by long
|
||||
* keys. Void propertys have no value - they either exist or they don't exist.
|
||||
*
|
||||
*/
|
||||
public class VoidPropertySet extends PropertySet {
|
||||
private final static long serialVersionUID = 1;
|
||||
/**
|
||||
* Constructor for VoidPropertySet.
|
||||
* @param name the name associated with this property set.
|
||||
*/
|
||||
public VoidPropertySet(String name) {
|
||||
super(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PropertySet#getDataSize()
|
||||
*/
|
||||
@Override
|
||||
public int getDataSize() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the existence of a property at the given index.
|
||||
* @param index the index at which to establish the existence of the
|
||||
* property.
|
||||
*/
|
||||
public void put(long index) {
|
||||
PropertyPage page = getOrCreatePage(getPageID(index));
|
||||
int n = page.getSize();
|
||||
page.add(getPageOffset(index));
|
||||
numProperties += page.getSize() - n;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.prop.PropertySet#moveIndex(long, long)
|
||||
*/
|
||||
@Override
|
||||
protected void moveIndex(long from, long to) {
|
||||
boolean value = hasProperty(from);
|
||||
remove(from);
|
||||
if (value) {
|
||||
put(to);
|
||||
}
|
||||
else {
|
||||
remove(to);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* saves the property at the given index to the given output stream.
|
||||
*/
|
||||
@Override
|
||||
protected void saveProperty(ObjectOutputStream oos, long index) throws IOException {
|
||||
}
|
||||
/**
|
||||
* restores the property from the input stream to the given index.
|
||||
*/
|
||||
@Override
|
||||
protected void restoreProperty(ObjectInputStream ois, long index) throws IOException,
|
||||
ClassNotFoundException {
|
||||
this.put(index);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @see ghidra.util.prop.PropertySet#applyValue(PropertyVisitor, long)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, long addr) {
|
||||
if (hasProperty(addr)) {
|
||||
visitor.visit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
@ -25,17 +25,18 @@ import generic.test.AbstractGenericTest;
|
|||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.map.IntValueMap;
|
||||
|
||||
public class IntPropertySetTest extends AbstractGenericTest {
|
||||
IntPropertySet ps;
|
||||
public class IntValueMapTest extends AbstractGenericTest {
|
||||
IntValueMap ps;
|
||||
|
||||
public IntPropertySetTest() {
|
||||
public IntValueMapTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ps = new IntPropertySet("Test");
|
||||
ps = new IntValueMap("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -168,6 +169,60 @@ public class IntPropertySetTest extends AbstractGenericTest {
|
|||
assertEquals(i, 10000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangeIterator() {
|
||||
|
||||
IntValueMap pm = new IntValueMap("Test");
|
||||
for (int i = 0; i < 20; i++) {
|
||||
pm.putInt(i + 10, i + 100);
|
||||
}
|
||||
LongIterator it = pm.getPropertyIterator(10, 30);
|
||||
|
||||
int i = 10;
|
||||
while (it.hasNext()) {
|
||||
long index = it.next();
|
||||
assertEquals(i, index);
|
||||
if (it.hasPrevious()) {
|
||||
index = it.previous();
|
||||
assertEquals(i, index);
|
||||
index = it.next();// so we don't go into an infinite loop
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
it = pm.getPropertyIterator(12);
|
||||
i = 11;
|
||||
while (it.hasPrevious()) {
|
||||
long index = it.previous();
|
||||
assertEquals(i, index);
|
||||
if (it.hasNext()) {
|
||||
index = it.next();
|
||||
assertEquals(i, index);
|
||||
index = it.previous();// so we don't go into an infinite loop
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
it = pm.getPropertyIterator(5, 15);
|
||||
i = 10;
|
||||
while (it.hasNext()) {
|
||||
long index = it.next();
|
||||
assertEquals(i, index);
|
||||
if (it.hasPrevious()) {
|
||||
index = it.previous();
|
||||
assertEquals(i, index);
|
||||
index = it.next();// so we don't go into an infinite loop
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
pm.removeRange(0, 2000);
|
||||
it = pm.getPropertyIterator(5, 15);
|
||||
if (it.hasPrevious()) {
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
|
@ -184,7 +239,7 @@ public class IntPropertySetTest extends AbstractGenericTest {
|
|||
|
||||
ps = null;
|
||||
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
|
||||
ps = (IntPropertySet) in.readObject();
|
||||
ps = (IntValueMap) in.readObject();
|
||||
in.close();
|
||||
}
|
||||
finally {
|
|
@ -1,92 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.LongIterator;
|
||||
|
||||
// Test the LongIteratorImpl and LongIteratorMatcherImpl classes.
|
||||
|
||||
public class IteratorTest extends AbstractGenericTest {
|
||||
|
||||
|
||||
public IteratorTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAll() {
|
||||
|
||||
StringPropertySet pm = new StringPropertySet("Test");
|
||||
for (int i=0; i<20; i++) {
|
||||
String s = "test " + (i+10);
|
||||
pm.putString(i+10, s);
|
||||
}
|
||||
LongIterator it = pm.getPropertyIterator(10, 30);
|
||||
|
||||
int i = 10;
|
||||
while (it.hasNext()) {
|
||||
long index = it.next();
|
||||
assertEquals(i, index);
|
||||
if (it.hasPrevious()) {
|
||||
index = it.previous();
|
||||
assertEquals(i,index);
|
||||
index = it.next();// so we don't go into an infinite loop
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
it = pm.getPropertyIterator(12);
|
||||
i=11;
|
||||
while (it.hasPrevious()) {
|
||||
long index = it.previous();
|
||||
assertEquals(i,index);
|
||||
if (it.hasNext()) {
|
||||
index = it.next();
|
||||
assertEquals(i, index);
|
||||
index = it.previous();// so we don't go into an infinite loop
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
it = pm.getPropertyIterator(5, 15);
|
||||
i = 10;
|
||||
while (it.hasNext()) {
|
||||
long index = it.next();
|
||||
assertEquals(i, index);
|
||||
if (it.hasPrevious()) {
|
||||
index = it.previous();
|
||||
assertEquals(i, index);
|
||||
index = it.next();// so we don't go into an infinite loop
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
pm.removeRange(0, 2000);
|
||||
it = pm.getPropertyIterator(5, 15);
|
||||
if (it.hasPrevious()) {
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
|
||||
}//end doTest()
|
||||
|
||||
}
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
@ -26,19 +25,20 @@ import org.junit.Test;
|
|||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
import ghidra.util.map.ObjectValueMap;
|
||||
|
||||
public class ObjectPropertySetTest extends AbstractGenericTest {
|
||||
ObjectPropertySet ps;
|
||||
public class ObjectValueMapTest extends AbstractGenericTest {
|
||||
ObjectValueMap<Integer> ps;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ps = new ObjectPropertySet("Test");
|
||||
ps = new ObjectValueMap<>("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSize() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(10000 * i, new Integer(i));
|
||||
ps.putObject(10000 * i, i);
|
||||
|
||||
}
|
||||
assertEquals(1000, ps.getSize());
|
||||
|
@ -47,14 +47,14 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testGetProperty() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(10000 * i, new Integer(i));
|
||||
ps.putObject(10000 * i, i);
|
||||
|
||||
}
|
||||
|
||||
assertEquals(new Integer(0), ps.getObject(0));
|
||||
assertEquals(new Integer(50), ps.getObject(500000));
|
||||
assertEquals(Integer.valueOf(0), ps.getObject(0));
|
||||
assertEquals(Integer.valueOf(50), ps.getObject(500000));
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
assertEquals(new Integer(i), ps.getObject(10000 * i));
|
||||
assertEquals(Integer.valueOf(i), ps.getObject(10000 * i));
|
||||
}
|
||||
|
||||
assertNull(ps.getObject(1));
|
||||
|
@ -64,7 +64,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testPropertyIndex() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(10000 * i, new Integer(i));
|
||||
ps.putObject(10000 * i, i);
|
||||
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testPropertyIndex2() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(3 * i, new Integer(i));
|
||||
ps.putObject(3 * i, i);
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
|
@ -111,7 +111,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testPropertyIndex3() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(i, new Integer(i));
|
||||
ps.putObject(i, i);
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
|
@ -134,7 +134,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testIterator() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(100 * i, new Integer(i));
|
||||
ps.putObject(100 * i, i);
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
|
@ -149,7 +149,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testIterator2() {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(i, new Integer(i));
|
||||
ps.putObject(i, i);
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
|
@ -161,10 +161,11 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
assertEquals(i, 10000);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(i, new Integer(i));
|
||||
ps.putObject(i, i);
|
||||
}
|
||||
|
||||
File tmpFile = createTempFile("ObjectPropertySetTest", ".ser");
|
||||
|
@ -177,7 +178,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
|
||||
ps = null;
|
||||
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
|
||||
ps = (ObjectPropertySet) in.readObject();
|
||||
ps = (ObjectValueMap<Integer>) in.readObject();
|
||||
in.close();
|
||||
}
|
||||
finally {
|
||||
|
@ -201,7 +202,7 @@ public class ObjectPropertySetTest extends AbstractGenericTest {
|
|||
}
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
assertEquals(new Integer(i), ps.getObject(i));
|
||||
assertEquals(Integer.valueOf(i), ps.getObject(i));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.ObjectStorage;
|
||||
import ghidra.util.Saveable;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class SaveableInt implements Saveable {
|
||||
private int i;
|
||||
private Class<?>[] fields = new Class<?>[] {
|
||||
Integer.class
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for SaveableInt.
|
||||
*/
|
||||
public SaveableInt(int i){
|
||||
this.i = i;
|
||||
}
|
||||
public SaveableInt() {
|
||||
}
|
||||
/**
|
||||
* @see Saveable#restore(ObjectStorage)
|
||||
*/
|
||||
@Override
|
||||
public void restore(ObjectStorage objStorage) {
|
||||
i = objStorage.getInt();
|
||||
}
|
||||
/**
|
||||
* @see Saveable#save(ObjectStorage)
|
||||
*/
|
||||
@Override
|
||||
public void save(ObjectStorage objStorage) {
|
||||
objStorage.putInt(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getObjectStorageFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ""+i;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof SaveableInt)) {
|
||||
return false;
|
||||
}
|
||||
return i == ((SaveableInt)obj).i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.Saveable#getSchemaVersion()
|
||||
*/
|
||||
@Override
|
||||
public int getSchemaVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.Saveable#isUpgradeable(int)
|
||||
*/
|
||||
@Override
|
||||
public boolean isUpgradeable(int oldSchemaVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.util.Saveable#upgrade(ghidra.util.ObjectStorage, int, ghidra.util.ObjectStorage)
|
||||
*/
|
||||
@Override
|
||||
public boolean upgrade(ObjectStorage oldObjStorage, int oldSchemaVersion, ObjectStorage currentObjStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivate() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
|
||||
public class SaveableObjectPropertySetTest extends AbstractGenericTest {
|
||||
SaveableObjectPropertySet ps;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ps = new SaveableObjectPropertySet("Test", SaveableInt.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSize() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(10000 * i, new SaveableInt(i));
|
||||
|
||||
}
|
||||
assertEquals(1000, ps.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProperty() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(10000 * i, new SaveableInt(i));
|
||||
|
||||
}
|
||||
|
||||
assertEquals(new SaveableInt(0), ps.getObject(0));
|
||||
assertEquals(new SaveableInt(50), ps.getObject(500000));
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
assertEquals(new SaveableInt(i), ps.getObject(10000 * i));
|
||||
}
|
||||
|
||||
assertNull(ps.getObject(1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(10000 * i, new SaveableInt(i));
|
||||
|
||||
}
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(9990000, ps.getLastPropertyIndex());
|
||||
assertEquals(10000, ps.getNextPropertyIndex(0));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(10000));
|
||||
assertEquals(10000, ps.getNextPropertyIndex(1));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(1000, count);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex2() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(3 * i, new SaveableInt(i));
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(3 * 9999, ps.getLastPropertyIndex());
|
||||
assertEquals(3, ps.getNextPropertyIndex(0));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(3));
|
||||
assertEquals(3, ps.getNextPropertyIndex(1));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(10000, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex3() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(i, new SaveableInt(i));
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(9999, ps.getLastPropertyIndex());
|
||||
assertEquals(1, ps.getNextPropertyIndex(0));
|
||||
assertEquals(2, ps.getPreviousPropertyIndex(3));
|
||||
assertEquals(2, ps.getNextPropertyIndex(1));
|
||||
assertEquals(1, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(10000, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putObject(100 * i, new SaveableInt(i));
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
long l = it.next();
|
||||
assertEquals(100 * i, l);
|
||||
i++;
|
||||
}
|
||||
assertEquals(i, 1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator2() {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(i, new SaveableInt(i));
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
long l = it.next();
|
||||
assertEquals(i, l);
|
||||
i++;
|
||||
}
|
||||
assertEquals(i, 10000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putObject(i, new SaveableInt(i));
|
||||
}
|
||||
File tmpFile = createTempFile("SaveablePropertySetTest", ".ser");
|
||||
ObjectOutputStream out = null;
|
||||
ObjectInputStream in = null;
|
||||
try {
|
||||
out = new ObjectOutputStream(new FileOutputStream(tmpFile));
|
||||
out.writeObject(ps);
|
||||
out.close();
|
||||
|
||||
ps = null;
|
||||
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
|
||||
ps = (SaveableObjectPropertySet) in.readObject();
|
||||
in.close();
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
assertEquals(new SaveableInt(i), ps.getObject(i));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// squash
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// squash
|
||||
}
|
||||
}
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
}//end doTest()
|
||||
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import ghidra.util.ObjectStorage;
|
||||
import ghidra.util.Saveable;
|
||||
|
||||
public class SaveableString implements Saveable {
|
||||
|
||||
private String string;
|
||||
|
||||
private Class<?>[] fields = new Class<?>[] { String.class };
|
||||
|
||||
public SaveableString(String string) {
|
||||
if (string == null) {
|
||||
throw new IllegalArgumentException("Saved string cannot be null");
|
||||
}
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public SaveableString() {
|
||||
// for restoring
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getObjectStorageFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(ObjectStorage objStorage) {
|
||||
objStorage.putString(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(ObjectStorage objStorage) {
|
||||
objStorage.getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSchemaVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpgradeable(int oldSchemaVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean upgrade(ObjectStorage oldObjStorage, int oldSchemaVersion,
|
||||
ObjectStorage currentObjStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return string.equals(((SaveableString) obj).string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return string.hashCode();
|
||||
}
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
|
||||
public class StringPropertySetTest extends AbstractGenericTest {
|
||||
StringPropertySet ps;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ps = new StringPropertySet("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSize() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putString(10000 * i, "" + i);
|
||||
|
||||
}
|
||||
assertEquals(1000, ps.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProperty() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putString(10000 * i, "" + i);
|
||||
|
||||
}
|
||||
|
||||
assertEquals("" + 0, ps.getString(0));
|
||||
assertEquals("" + 50, ps.getString(500000));
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
assertEquals("" + i, ps.getString(10000 * i));
|
||||
}
|
||||
|
||||
assertNull(ps.getString(1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putString(10000 * i, "" + i);
|
||||
|
||||
}
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(9990000, ps.getLastPropertyIndex());
|
||||
assertEquals(10000, ps.getNextPropertyIndex(0));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(10000));
|
||||
assertEquals(10000, ps.getNextPropertyIndex(1));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(1000, count);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex2() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putString(3 * i, "" + i);
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(3 * 9999, ps.getLastPropertyIndex());
|
||||
assertEquals(3, ps.getNextPropertyIndex(0));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(3));
|
||||
assertEquals(3, ps.getNextPropertyIndex(1));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(10000, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex3() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putString(i, "" + i);
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(9999, ps.getLastPropertyIndex());
|
||||
assertEquals(1, ps.getNextPropertyIndex(0));
|
||||
assertEquals(2, ps.getPreviousPropertyIndex(3));
|
||||
assertEquals(2, ps.getNextPropertyIndex(1));
|
||||
assertEquals(1, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(10000, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.putString(100 * i, "" + i);
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
long l = it.next();
|
||||
assertEquals(100 * i, l);
|
||||
i++;
|
||||
}
|
||||
assertEquals(i, 1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator2() {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putString(i, "" + i);
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
long l = it.next();
|
||||
assertEquals(i, l);
|
||||
i++;
|
||||
}
|
||||
assertEquals(i, 10000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.putString(i, "" + i);
|
||||
}
|
||||
|
||||
File tmpFile = createTempFile("StringPropertySetTest", ".ser");
|
||||
ObjectOutputStream out = null;
|
||||
ObjectInputStream in = null;
|
||||
try {
|
||||
out = new ObjectOutputStream(new FileOutputStream(tmpFile));
|
||||
out.writeObject(ps);
|
||||
out.close();
|
||||
|
||||
ps = null;
|
||||
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
|
||||
ps = (StringPropertySet) in.readObject();
|
||||
in.close();
|
||||
}
|
||||
finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// squash
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// squash
|
||||
}
|
||||
}
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
assertEquals("" + i, ps.getString(i));
|
||||
}
|
||||
|
||||
}//end doTest()
|
||||
|
||||
}
|
|
@ -1,207 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.util.prop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
|
||||
public class VoidPropertySetTest extends AbstractGenericTest {
|
||||
VoidPropertySet ps;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ps = new VoidPropertySet("Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSize() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.put(10000 * i);
|
||||
|
||||
}
|
||||
assertEquals(1000, ps.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProperty() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.put(10000 * i);
|
||||
|
||||
}
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
assertTrue(ps.hasProperty(10000 * i));
|
||||
}
|
||||
|
||||
assertTrue(!ps.hasProperty(1));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.put(10000 * i);
|
||||
|
||||
}
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(9990000, ps.getLastPropertyIndex());
|
||||
assertEquals(10000, ps.getNextPropertyIndex(0));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(10000));
|
||||
assertEquals(10000, ps.getNextPropertyIndex(1));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(1000, count);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex2() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.put(3 * i);
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(3 * 9999, ps.getLastPropertyIndex());
|
||||
assertEquals(3, ps.getNextPropertyIndex(0));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(3));
|
||||
assertEquals(3, ps.getNextPropertyIndex(1));
|
||||
assertEquals(0, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(10000, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyIndex3() throws NoSuchIndexException {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.put(i);
|
||||
}
|
||||
assertEquals(10000, ps.getSize());
|
||||
|
||||
assertEquals(0, ps.getFirstPropertyIndex());
|
||||
assertEquals(9999, ps.getLastPropertyIndex());
|
||||
assertEquals(1, ps.getNextPropertyIndex(0));
|
||||
assertEquals(2, ps.getPreviousPropertyIndex(3));
|
||||
assertEquals(2, ps.getNextPropertyIndex(1));
|
||||
assertEquals(1, ps.getPreviousPropertyIndex(2));
|
||||
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int count = 0;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
assertEquals(10000, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
ps.put(100 * i);
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
long l = it.next();
|
||||
assertEquals(100 * i, l);
|
||||
i++;
|
||||
}
|
||||
assertEquals(i, 1000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator2() {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.put(i);
|
||||
}
|
||||
LongIterator it = ps.getPropertyIterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
long l = it.next();
|
||||
assertEquals(i, l);
|
||||
i++;
|
||||
}
|
||||
assertEquals(i, 10000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws Exception {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
ps.put(i);
|
||||
}
|
||||
|
||||
File tmpFile = createTempFile("VoidPropertySetTest", ".ser");
|
||||
ObjectOutputStream out = null;
|
||||
ObjectInputStream in = null;
|
||||
try {
|
||||
out = new ObjectOutputStream(new FileOutputStream(tmpFile));
|
||||
out.writeObject(ps);
|
||||
out.close();
|
||||
|
||||
ps = null;
|
||||
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(tmpFile)));
|
||||
ps = (VoidPropertySet) in.readObject();
|
||||
in.close();
|
||||
}
|
||||
finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// squash
|
||||
}
|
||||
}
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// squash
|
||||
}
|
||||
}
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
assertTrue(ps.hasProperty(i));
|
||||
}
|
||||
assertTrue(!ps.hasProperty(10001));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -24,10 +24,9 @@ import ghidra.program.model.listing.CodeUnit;
|
|||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.TypeMismatchException;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -411,20 +410,6 @@ abstract class PseudoCodeUnit implements CodeUnit {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the visit() method of the specified PropertyVisitor if the named
|
||||
* property exists for this code unit.
|
||||
*
|
||||
* @param visitor
|
||||
* the class implementing the PropertyVisitor interface.
|
||||
* @param propertyName
|
||||
* the name of the property to be visited.
|
||||
*/
|
||||
@Override
|
||||
public void visitProperty(PropertyVisitor visitor, String propertyName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label for this code unit.
|
||||
*
|
||||
|
|
|
@ -22,9 +22,7 @@ import db.*;
|
|||
import ghidra.framework.data.ContentHandler;
|
||||
import ghidra.framework.data.DomainObjectAdapterDB;
|
||||
import ghidra.framework.store.FileSystem;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.database.map.AddressMapDB;
|
||||
import ghidra.program.database.mem.MemoryMapDB;
|
||||
import ghidra.program.database.properties.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
|
@ -36,7 +34,6 @@ import ghidra.util.Msg;
|
|||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
/**
|
||||
* <code>ProgramUserDataDB</code> stores user data associated with a specific program.
|
||||
|
@ -105,7 +102,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
private Language language;
|
||||
private LanguageTranslator languageUpgradeTranslator;
|
||||
private AddressFactory addressFactory;
|
||||
private HashMap<Long, PropertyMap> propertyMaps = new HashMap<Long, PropertyMap>();
|
||||
private HashMap<Long, PropertyMap<?>> propertyMaps = new HashMap<Long, PropertyMap<?>>();
|
||||
private HashSet<String> propertyMapOwners = null;
|
||||
|
||||
private final ChangeManager changeMgr = new ChangeManagerAdapter() {
|
||||
|
@ -137,7 +134,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
int id = startTransaction("create user data");
|
||||
|
||||
createDatabase();
|
||||
if (createManagers(CREATE, program, TaskMonitorAdapter.DUMMY_MONITOR) != null) {
|
||||
if (createManagers(CREATE, program, TaskMonitor.DUMMY) != null) {
|
||||
throw new AssertException("Unexpected version exception on create");
|
||||
}
|
||||
//initManagers(CREATE, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
@ -165,7 +162,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
super(dbh, getName(program), 500, program);
|
||||
this.program = program;
|
||||
if (monitor == null) {
|
||||
monitor = TaskMonitorAdapter.DUMMY_MONITOR;
|
||||
monitor = TaskMonitor.DUMMY;
|
||||
}
|
||||
|
||||
setEventsEnabled(false); // events not support
|
||||
|
@ -204,7 +201,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
if (languageVersionExc != null) {
|
||||
try {
|
||||
setLanguage(languageUpgradeTranslator, monitor);
|
||||
addressMap.memoryMapChanged((MemoryMapDB) program.getMemory());
|
||||
addressMap.memoryMapChanged(program.getMemory());
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
if (e.getCause() instanceof CancelledException) {
|
||||
|
@ -212,9 +209,6 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
}
|
||||
throw e;
|
||||
}
|
||||
catch (LockException e) {
|
||||
throw new AssertException("Upgrade mode requires exclusive access", e);
|
||||
}
|
||||
}
|
||||
|
||||
endTransaction(id, true);
|
||||
|
@ -233,7 +227,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
/**
|
||||
* Language corresponding to languageId was found. Check language version
|
||||
* for language upgrade situation.
|
||||
* @throws LanguageNotFoundException
|
||||
* @throws LanguageNotFoundException if language version has changed
|
||||
* @return VersionException if language upgrade required
|
||||
*/
|
||||
private VersionException checkLanguageVersion() throws LanguageNotFoundException {
|
||||
|
@ -276,10 +270,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
* Language specified by languageName was not found. Check for
|
||||
* valid language translation/migration. Old language version specified by
|
||||
* languageVersion.
|
||||
* @param openMode one of:
|
||||
* READ_ONLY: the original database will not be modified
|
||||
* UPDATE: the database can be written to.
|
||||
* UPGRADE: the database is upgraded to the lastest schema as it is opened.
|
||||
* @param e language not found exception
|
||||
* @return true if language upgrade required
|
||||
* @throws LanguageNotFoundException if a suitable replacement language not found
|
||||
*/
|
||||
|
@ -368,6 +359,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
storedVersion = Integer.parseInt(record.getString(VALUE_COL));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// assume version 1 - value not stored
|
||||
}
|
||||
if (storedVersion > DB_VERSION) {
|
||||
throw new VersionException(VersionException.NEWER_VERSION, false);
|
||||
|
@ -414,7 +406,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
return versionExc;
|
||||
}
|
||||
}
|
||||
addressMap.memoryMapChanged((MemoryMapDB) program1.getMemory());
|
||||
addressMap.memoryMapChanged(program1.getMemory());
|
||||
monitor.checkCanceled();
|
||||
|
||||
return versionExc;
|
||||
|
@ -423,11 +415,9 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
/**
|
||||
* Translate language
|
||||
* @param translator language translator, if null only re-disassembly will occur.
|
||||
* @param monitor
|
||||
* @throws LockException
|
||||
* @param monitor task monitor
|
||||
*/
|
||||
private void setLanguage(LanguageTranslator translator, TaskMonitor monitor)
|
||||
throws LockException {
|
||||
private void setLanguage(LanguageTranslator translator, TaskMonitor monitor) {
|
||||
lock.acquire();
|
||||
try {
|
||||
//setEventsEnabled(false);
|
||||
|
@ -470,7 +460,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
return dbh.canUpdate();
|
||||
}
|
||||
|
||||
private PropertyMap getPropertyMap(String owner, String propertyName, int propertyType,
|
||||
private PropertyMap<?> getPropertyMap(String owner, String propertyName, int propertyType,
|
||||
Class<?> saveableClass, boolean create) throws PropertyTypeMismatchException {
|
||||
|
||||
try {
|
||||
|
@ -506,7 +496,7 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
if (saveableClass != null) {
|
||||
rec.setString(PROPERTY_CLASS_COL, saveableClass.getName());
|
||||
}
|
||||
PropertyMap map = null;
|
||||
PropertyMap<?> map = null;
|
||||
boolean success = false;
|
||||
try {
|
||||
map = getPropertyMap(rec);
|
||||
|
@ -530,38 +520,38 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
return null;
|
||||
}
|
||||
|
||||
private PropertyMap getPropertyMap(DBRecord rec) throws IOException {
|
||||
private PropertyMap<?> getPropertyMap(DBRecord rec) throws IOException {
|
||||
try {
|
||||
PropertyMap map;
|
||||
PropertyMap<?> map;
|
||||
int type = rec.getIntValue(PROPERTY_TYPE_COL);
|
||||
switch (type) {
|
||||
case PROPERTY_TYPE_STRING:
|
||||
map = new StringPropertyMapDB(dbh, DBConstants.UPGRADE, this, changeMgr,
|
||||
addressMap, rec.getString(PROPERTY_NAME_COL),
|
||||
TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
TaskMonitor.DUMMY);
|
||||
break;
|
||||
case PROPERTY_TYPE_LONG:
|
||||
map =
|
||||
new LongPropertyMapDB(dbh, DBConstants.UPGRADE, this, changeMgr, addressMap,
|
||||
rec.getString(PROPERTY_NAME_COL), TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
rec.getString(PROPERTY_NAME_COL), TaskMonitor.DUMMY);
|
||||
break;
|
||||
case PROPERTY_TYPE_INT:
|
||||
map =
|
||||
new IntPropertyMapDB(dbh, DBConstants.UPGRADE, this, changeMgr, addressMap,
|
||||
rec.getString(PROPERTY_NAME_COL), TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
rec.getString(PROPERTY_NAME_COL), TaskMonitor.DUMMY);
|
||||
break;
|
||||
case PROPERTY_TYPE_BOOLEAN:
|
||||
map =
|
||||
new VoidPropertyMapDB(dbh, DBConstants.UPGRADE, this, changeMgr, addressMap,
|
||||
rec.getString(PROPERTY_NAME_COL), TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
rec.getString(PROPERTY_NAME_COL), TaskMonitor.DUMMY);
|
||||
break;
|
||||
case PROPERTY_TYPE_SAVEABLE:
|
||||
String className = rec.getString(PROPERTY_CLASS_COL);
|
||||
Class<? extends Saveable> c =
|
||||
ObjectPropertyMapDB.getSaveableClassForName(className);
|
||||
return new ObjectPropertyMapDB(dbh, DBConstants.UPGRADE, this, changeMgr,
|
||||
return new ObjectPropertyMapDB<>(dbh, DBConstants.UPGRADE, this, changeMgr,
|
||||
addressMap, rec.getString(PROPERTY_NAME_COL), c,
|
||||
TaskMonitorAdapter.DUMMY_MONITOR, true);
|
||||
TaskMonitor.DUMMY, true);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported property type: " + type);
|
||||
}
|
||||
|
@ -578,8 +568,8 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<PropertyMap> getProperties(String owner) {
|
||||
List<PropertyMap> list = new ArrayList<PropertyMap>();
|
||||
public synchronized List<PropertyMap<?>> getProperties(String owner) {
|
||||
List<PropertyMap<?>> list = new ArrayList<PropertyMap<?>>();
|
||||
try {
|
||||
for (Field key : registryTable.findRecords(new StringField(owner),
|
||||
PROPERTY_OWNER_COL)) {
|
||||
|
@ -640,11 +630,12 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
create);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public synchronized ObjectPropertyMap getObjectProperty(String owner, String propertyName,
|
||||
Class<? extends Saveable> saveableObjectClass, boolean create)
|
||||
public synchronized <T extends Saveable> ObjectPropertyMap<T> getObjectProperty(String owner,
|
||||
String propertyName, Class<T> saveableObjectClass, boolean create)
|
||||
throws PropertyTypeMismatchException {
|
||||
return (ObjectPropertyMap) getPropertyMap(owner, propertyName, PROPERTY_TYPE_SAVEABLE,
|
||||
return (ObjectPropertyMap<T>) getPropertyMap(owner, propertyName, PROPERTY_TYPE_SAVEABLE,
|
||||
saveableObjectClass, create);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import ghidra.program.model.listing.BookmarkType;
|
|||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.util.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -164,7 +165,7 @@ class OldBookmarkManager {
|
|||
OldBookmark bookmark = null;
|
||||
ObjectPropertyMap map = getMap(type, false);
|
||||
if (map != null) {
|
||||
bookmark = (OldBookmark) map.getObject(addr);
|
||||
bookmark = (OldBookmark) map.get(addr);
|
||||
if (bookmark != null) {
|
||||
bookmark.setContext(program, type);
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
|
|||
public void setProgram(ProgramDB program) {
|
||||
this.program = program;
|
||||
equateTable = program.getEquateTable();
|
||||
symbolTable = (SymbolManager) program.getSymbolTable();
|
||||
symbolTable = program.getSymbolTable();
|
||||
contextMgr = program.getProgramContext();
|
||||
refManager = program.getReferenceManager();
|
||||
propertyMapMgr = program.getUsrPropertyManager();
|
||||
|
|
|
@ -32,7 +32,6 @@ import ghidra.program.model.symbol.*;
|
|||
import ghidra.program.model.util.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
|
||||
/**
|
||||
* Database implementation of CodeUnit.
|
||||
|
@ -308,11 +307,11 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
@Override
|
||||
public Saveable getObjectProperty(String name) {
|
||||
PropertyMapManager upm = codeMgr.getPropertyMapManager();
|
||||
ObjectPropertyMap pm = upm.getObjectPropertyMap(name);
|
||||
ObjectPropertyMap<?> pm = upm.getObjectPropertyMap(name);
|
||||
if (pm != null) {
|
||||
try {
|
||||
refreshIfNeeded();
|
||||
return (Saveable) pm.getObject(address);
|
||||
return pm.get(address);
|
||||
}
|
||||
catch (ConcurrentModificationException e) {
|
||||
}
|
||||
|
@ -381,7 +380,7 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
@Override
|
||||
public boolean getVoidProperty(String name) {
|
||||
PropertyMapManager upm = codeMgr.getPropertyMapManager();
|
||||
PropertyMap pm = upm.getPropertyMap(name);
|
||||
VoidPropertyMap pm = upm.getVoidPropertyMap(name);
|
||||
if (pm != null) {
|
||||
try {
|
||||
refreshIfNeeded();
|
||||
|
@ -396,7 +395,7 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
@Override
|
||||
public boolean hasProperty(String name) {
|
||||
PropertyMapManager upm = codeMgr.getPropertyMapManager();
|
||||
PropertyMap pm = upm.getPropertyMap(name);
|
||||
PropertyMap<?> pm = upm.getPropertyMap(name);
|
||||
if (pm != null) {
|
||||
try {
|
||||
refreshIfNeeded();
|
||||
|
@ -450,7 +449,7 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
@Override
|
||||
public void removeProperty(String name) {
|
||||
PropertyMapManager upm = codeMgr.getPropertyMapManager();
|
||||
PropertyMap pm = upm.getPropertyMap(name);
|
||||
PropertyMap<?> pm = upm.getPropertyMap(name);
|
||||
if (pm != null) {
|
||||
try {
|
||||
refreshIfNeeded();
|
||||
|
@ -542,14 +541,14 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void setProperty(String name, Saveable value) {
|
||||
public <T extends Saveable> void setProperty(String name, T value) {
|
||||
PropertyMapManager mgr = codeMgr.getPropertyMapManager();
|
||||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
ObjectPropertyMap pm = mgr.getObjectPropertyMap(name);
|
||||
|
||||
ObjectPropertyMap<?> pm = mgr.getObjectPropertyMap(name);
|
||||
if (pm == null) {
|
||||
try {
|
||||
pm = mgr.createObjectPropertyMap(name, value.getClass());
|
||||
|
@ -559,7 +558,8 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
"Assert problem in CodeUnitImpl.setProperty(Stirng,Object)");
|
||||
}
|
||||
}
|
||||
pm.add(address, value);
|
||||
// Will throw IllegalArgumentException if map is not applicable for T
|
||||
((ObjectPropertyMap<T>) pm).add(address, value);
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
|
@ -626,20 +626,6 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
refMgr.addRegisterReference(address, opIndex, reg, refType, sourceType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitProperty(PropertyVisitor visitor, String propertyName) {
|
||||
PropertyMapManager upm = codeMgr.getPropertyMapManager();
|
||||
PropertyMap pm = upm.getPropertyMap(propertyName);
|
||||
if (pm != null) {
|
||||
try {
|
||||
refreshIfNeeded();
|
||||
pm.applyValue(visitor, address);
|
||||
}
|
||||
catch (ConcurrentModificationException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes(byte[] b, int offset) {
|
||||
lock.acquire();
|
||||
|
@ -787,7 +773,6 @@ abstract class CodeUnitDB extends DatabaseObject implements CodeUnit, ProcessorC
|
|||
/**
|
||||
* Returns a string that represents this code unit with default markup.
|
||||
* Only the mnemonic and operands are included.
|
||||
* @see CodeUnitFormat#getRepresentationString(CodeUnit, boolean) for full mark-up formatting
|
||||
*/
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
|
|
@ -33,8 +33,8 @@ import ghidra.program.model.util.*;
|
|||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
/**
|
||||
* Manages generic address keyed properties.
|
||||
|
@ -46,7 +46,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
private AddressMap addrMap;
|
||||
private ChangeManager changeMgr;
|
||||
private PropertiesDBAdapter propertiesDBAdapter;
|
||||
private TreeMap<String, PropertyMap> propertyMapCache;
|
||||
private TreeMap<String, PropertyMapDB<?>> propertyMapCache;
|
||||
private Lock lock;
|
||||
|
||||
static final int CURRENT_PROPERTIES_TABLE_VERSION = 0;
|
||||
|
@ -82,9 +82,9 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
* @param openMode the program open mode.
|
||||
* @param lock the program synchronization lock
|
||||
* @param monitor the task monitor
|
||||
* @throws IOException
|
||||
* @throws VersionException
|
||||
* @throws CancelledException
|
||||
* @throws IOException if an IO error occurs
|
||||
* @throws VersionException if a version error occurs
|
||||
* @throws CancelledException if task is cancelled
|
||||
*/
|
||||
public DBPropertyMapManager(DBHandle handle, ChangeManager changeMgr, AddressMap addrMap,
|
||||
int openMode, Lock lock, TaskMonitor monitor)
|
||||
|
@ -97,7 +97,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
dbHandle.createTable(PROPERTIES_TABLE_NAME, PROPERTIES_SCHEMA);
|
||||
}
|
||||
findAdapters(handle);
|
||||
propertyMapCache = new TreeMap<String, PropertyMap>();
|
||||
propertyMapCache = new TreeMap<String, PropertyMapDB<?>>();
|
||||
loadPropertyMaps(openMode, monitor);
|
||||
}
|
||||
|
||||
|
@ -126,9 +126,10 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
lock.acquire();
|
||||
try {
|
||||
propertyMapCache.clear();
|
||||
loadPropertyMaps(-1, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
loadPropertyMaps(-1, TaskMonitor.DUMMY);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (VersionException e) {
|
||||
throw new AssertException();
|
||||
|
@ -147,7 +148,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
DBRecord rec = iter.next();
|
||||
String name = rec.getKeyField().getString();
|
||||
byte propertyType = rec.getByteValue(PROPERTY_TYPE_COL);
|
||||
PropertyMap pm = null;
|
||||
PropertyMapDB<?> pm = null;
|
||||
try {
|
||||
switch (propertyType) {
|
||||
case INT_PROPERTY_TYPE:
|
||||
|
@ -178,12 +179,12 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
throw new VersionException(VersionException.OLDER_VERSION,
|
||||
true);
|
||||
}
|
||||
pm = new ObjectPropertyMapDB(dbHandle, openMode, program, changeMgr,
|
||||
addrMap, name, OldBookmark.class, monitor, false);
|
||||
pm = new ObjectPropertyMapDB<>(dbHandle, openMode, program,
|
||||
changeMgr, addrMap, name, OldBookmark.class, monitor, false);
|
||||
}
|
||||
else {
|
||||
pm = new ObjectPropertyMapDB(dbHandle, openMode, program, changeMgr,
|
||||
addrMap, name,
|
||||
pm = new ObjectPropertyMapDB<>(dbHandle, openMode, program,
|
||||
changeMgr, addrMap, name,
|
||||
ObjectPropertyMapDB.getSaveableClassForName(className), monitor,
|
||||
false);
|
||||
}
|
||||
|
@ -233,10 +234,10 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
if (propertyMapCache.containsKey(propertyName)) {
|
||||
throw new DuplicateNameException();
|
||||
}
|
||||
IntPropertyMap pm = null;
|
||||
IntPropertyMapDB pm = null;
|
||||
try {
|
||||
pm = new IntPropertyMapDB(dbHandle, DBConstants.CREATE, program, changeMgr, addrMap,
|
||||
propertyName, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
propertyName, TaskMonitor.DUMMY);
|
||||
propertiesDBAdapter.putRecord(propertyName, INT_PROPERTY_TYPE, null);
|
||||
propertyMapCache.put(propertyName, pm);
|
||||
}
|
||||
|
@ -244,6 +245,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
throw new AssertException();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (IOException e) {
|
||||
program.dbError(e);
|
||||
|
@ -270,10 +272,10 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
if (propertyMapCache.containsKey(propertyName)) {
|
||||
throw new DuplicateNameException();
|
||||
}
|
||||
LongPropertyMap pm = null;
|
||||
LongPropertyMapDB pm = null;
|
||||
try {
|
||||
pm = new LongPropertyMapDB(dbHandle, DBConstants.CREATE, program, changeMgr,
|
||||
addrMap, propertyName, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
addrMap, propertyName, TaskMonitor.DUMMY);
|
||||
propertiesDBAdapter.putRecord(propertyName, LONG_PROPERTY_TYPE, null);
|
||||
propertyMapCache.put(propertyName, pm);
|
||||
}
|
||||
|
@ -281,6 +283,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
throw new AssertException();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (IOException e) {
|
||||
program.dbError(e);
|
||||
|
@ -308,10 +311,10 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
if (propertyMapCache.containsKey(propertyName)) {
|
||||
throw new DuplicateNameException();
|
||||
}
|
||||
StringPropertyMap pm = null;
|
||||
StringPropertyMapDB pm = null;
|
||||
try {
|
||||
pm = new StringPropertyMapDB(dbHandle, DBConstants.CREATE, program, changeMgr,
|
||||
addrMap, propertyName, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
addrMap, propertyName, TaskMonitor.DUMMY);
|
||||
propertiesDBAdapter.putRecord(propertyName, STRING_PROPERTY_TYPE, null);
|
||||
propertyMapCache.put(propertyName, pm);
|
||||
}
|
||||
|
@ -319,6 +322,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
throw new AssertException();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (IOException e) {
|
||||
program.dbError(e);
|
||||
|
@ -331,26 +335,19 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ObjectPropertyMap with the given name.
|
||||
* @param propertyName the name of the property to create.
|
||||
* @param objectClass the class of the objects that will be stored in the property.
|
||||
* @exception DuplicateNameException thrown if a PropertyMap already
|
||||
* exists with that name.
|
||||
*/
|
||||
@Override
|
||||
public ObjectPropertyMap createObjectPropertyMap(String propertyName,
|
||||
Class<? extends Saveable> objectClass) throws DuplicateNameException {
|
||||
public <T extends Saveable> ObjectPropertyMap<T> createObjectPropertyMap(String propertyName,
|
||||
Class<T> objectClass) throws DuplicateNameException {
|
||||
|
||||
lock.acquire();
|
||||
try {
|
||||
if (propertyMapCache.containsKey(propertyName)) {
|
||||
throw new DuplicateNameException();
|
||||
}
|
||||
ObjectPropertyMap pm = null;
|
||||
ObjectPropertyMapDB<T> pm = null;
|
||||
try {
|
||||
pm = new ObjectPropertyMapDB(dbHandle, DBConstants.CREATE, program, changeMgr,
|
||||
addrMap, propertyName, objectClass, TaskMonitorAdapter.DUMMY_MONITOR, false);
|
||||
pm = new ObjectPropertyMapDB<>(dbHandle, DBConstants.CREATE, program, changeMgr,
|
||||
addrMap, propertyName, objectClass, TaskMonitor.DUMMY, false);
|
||||
propertiesDBAdapter.putRecord(propertyName, OBJECT_PROPERTY_TYPE,
|
||||
objectClass.getName());
|
||||
propertyMapCache.put(propertyName, pm);
|
||||
|
@ -359,6 +356,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
throw new AssertException();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (IOException e) {
|
||||
program.dbError(e);
|
||||
|
@ -386,10 +384,10 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
if (propertyMapCache.containsKey(propertyName)) {
|
||||
throw new DuplicateNameException();
|
||||
}
|
||||
VoidPropertyMap pm = null;
|
||||
VoidPropertyMapDB pm = null;
|
||||
try {
|
||||
pm = new VoidPropertyMapDB(dbHandle, DBConstants.CREATE, program, changeMgr,
|
||||
addrMap, propertyName, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
addrMap, propertyName, TaskMonitor.DUMMY);
|
||||
propertiesDBAdapter.putRecord(propertyName, VOID_PROPERTY_TYPE, null);
|
||||
propertyMapCache.put(propertyName, pm);
|
||||
}
|
||||
|
@ -397,6 +395,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
throw new AssertException();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (IOException e) {
|
||||
program.dbError(e);
|
||||
|
@ -415,7 +414,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
* @param propertyName the name of the property to retrieve.
|
||||
*/
|
||||
@Override
|
||||
public PropertyMap getPropertyMap(String propertyName) {
|
||||
public PropertyMap<?> getPropertyMap(String propertyName) {
|
||||
lock.acquire();
|
||||
try {
|
||||
return propertyMapCache.get(propertyName);
|
||||
|
@ -437,7 +436,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
|
||||
lock.acquire();
|
||||
try {
|
||||
PropertyMap pm = propertyMapCache.get(propertyName);
|
||||
PropertyMapDB<?> pm = propertyMapCache.get(propertyName);
|
||||
if (pm == null || pm instanceof IntPropertyMap) {
|
||||
return (IntPropertyMap) pm;
|
||||
}
|
||||
|
@ -459,7 +458,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
public LongPropertyMap getLongPropertyMap(String propertyName) {
|
||||
lock.acquire();
|
||||
try {
|
||||
PropertyMap pm = propertyMapCache.get(propertyName);
|
||||
PropertyMapDB<?> pm = propertyMapCache.get(propertyName);
|
||||
if (pm == null || pm instanceof LongPropertyMap) {
|
||||
return (LongPropertyMap) pm;
|
||||
}
|
||||
|
@ -481,7 +480,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
public StringPropertyMap getStringPropertyMap(String propertyName) {
|
||||
lock.acquire();
|
||||
try {
|
||||
PropertyMap pm = propertyMapCache.get(propertyName);
|
||||
PropertyMapDB<?> pm = propertyMapCache.get(propertyName);
|
||||
if (pm == null || pm instanceof StringPropertyMap) {
|
||||
return (StringPropertyMap) pm;
|
||||
}
|
||||
|
@ -500,12 +499,12 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
* exists but is not an ObjectPropertyMap.
|
||||
*/
|
||||
@Override
|
||||
public ObjectPropertyMap getObjectPropertyMap(String propertyName) {
|
||||
public ObjectPropertyMap<?> getObjectPropertyMap(String propertyName) {
|
||||
lock.acquire();
|
||||
try {
|
||||
PropertyMap pm = propertyMapCache.get(propertyName);
|
||||
PropertyMapDB<?> pm = propertyMapCache.get(propertyName);
|
||||
if (pm == null || pm instanceof ObjectPropertyMap) {
|
||||
return (ObjectPropertyMap) pm;
|
||||
return (ObjectPropertyMap<?>) pm;
|
||||
}
|
||||
throw new TypeMismatchException("Property " + propertyName + " is not object type");
|
||||
|
||||
|
@ -525,7 +524,7 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
public VoidPropertyMap getVoidPropertyMap(String propertyName) {
|
||||
lock.acquire();
|
||||
try {
|
||||
PropertyMap pm = propertyMapCache.get(propertyName);
|
||||
PropertyMapDB<?> pm = propertyMapCache.get(propertyName);
|
||||
if (pm == null || pm instanceof VoidPropertyMap) {
|
||||
return (VoidPropertyMap) pm;
|
||||
}
|
||||
|
@ -536,17 +535,12 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the PropertyMap with the given name.
|
||||
* @param propertyName the name of the property to remove.
|
||||
* @return true if a PropertyMap with that name was found (and removed)
|
||||
*/
|
||||
@Override
|
||||
public boolean removePropertyMap(String propertyName) {
|
||||
lock.acquire();
|
||||
try {
|
||||
if (propertyMapCache.containsKey(propertyName)) {
|
||||
PropertyMapDB pm = (PropertyMapDB) propertyMapCache.get(propertyName);
|
||||
PropertyMapDB<?> pm = propertyMapCache.remove(propertyName);
|
||||
if (pm != null) {
|
||||
pm.delete();
|
||||
propertiesDBAdapter.removeRecord(propertyName);
|
||||
propertyMapCache.remove(propertyName);
|
||||
|
@ -565,9 +559,6 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the names of all existing PropertyMangers.
|
||||
*/
|
||||
@Override
|
||||
public Iterator<String> propertyManagers() {
|
||||
lock.acquire();
|
||||
|
@ -580,18 +571,13 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any property at the given address from all defined
|
||||
* PropertyManagers.
|
||||
* @param addr the address at which to remove all properties.
|
||||
*/
|
||||
@Override
|
||||
public void removeAll(Address addr) {
|
||||
lock.acquire();
|
||||
try {
|
||||
Iterator<PropertyMap> iter = propertyMapCache.values().iterator();
|
||||
Iterator<PropertyMapDB<?>> iter = propertyMapCache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
PropertyMapDB pm = (PropertyMapDB) iter.next();
|
||||
PropertyMapDB<?> pm = iter.next();
|
||||
pm.remove(addr);
|
||||
}
|
||||
|
||||
|
@ -601,18 +587,15 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMapManager#removeAll(ghidra.program.model.address.Address, ghidra.program.model.address.Address, ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void removeAll(Address startAddr, Address endAddr, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
lock.acquire();
|
||||
try {
|
||||
Iterator<PropertyMap> iter = propertyMapCache.values().iterator();
|
||||
Iterator<PropertyMapDB<?>> iter = propertyMapCache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
monitor.checkCanceled();
|
||||
PropertyMapDB pm = (PropertyMapDB) iter.next();
|
||||
PropertyMapDB<?> pm = iter.next();
|
||||
pm.removeRange(startAddr, endAddr);
|
||||
}
|
||||
|
||||
|
@ -622,18 +605,15 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.database.ManagerDB#moveAddressRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, long, ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void moveAddressRange(Address fromAddr, Address toAddr, long length, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
lock.acquire();
|
||||
try {
|
||||
Iterator<PropertyMap> iter = propertyMapCache.values().iterator();
|
||||
Iterator<PropertyMapDB<?>> iter = propertyMapCache.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
monitor.checkCanceled();
|
||||
PropertyMapDB pm = (PropertyMapDB) iter.next();
|
||||
PropertyMapDB<?> pm = iter.next();
|
||||
pm.moveRange(fromAddr, fromAddr.add(length - 1), toAddr);
|
||||
}
|
||||
|
||||
|
@ -643,9 +623,6 @@ public class DBPropertyMapManager implements PropertyMapManager, ManagerDB {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.database.ManagerDB#deleteAddressRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void deleteAddressRange(Address startAddr, Address endAddr, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.program.database.properties;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
import db.*;
|
||||
import ghidra.util.ObjectStorage;
|
||||
import ghidra.util.Saveable;
|
||||
|
@ -49,39 +51,26 @@ public class GenericSaveable implements Saveable {
|
|||
return fieldClasses;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.Saveable#save(ghidra.util.ObjectStorage)
|
||||
*/
|
||||
@Override
|
||||
public void save(ObjectStorage objStorage) {
|
||||
throw new UnsupportedOperationException("not supported by GenericSaveable");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.Saveable#restore(ghidra.util.ObjectStorage)
|
||||
*/
|
||||
@Override
|
||||
public void restore(ObjectStorage objStorage) {
|
||||
throw new UnsupportedOperationException("not supported by GenericSaveable");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.Saveable#getSchemaVersion()
|
||||
*/
|
||||
@Override
|
||||
public int getSchemaVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.Saveable#isUpgradeable(int)
|
||||
*/
|
||||
@Override
|
||||
public boolean isUpgradeable(int oldSchemaVersion) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.Saveable#upgrade(ghidra.util.ObjectStorage, int, ghidra.util.ObjectStorage)
|
||||
*/
|
||||
@Override
|
||||
public boolean upgrade(ObjectStorage oldObjStorage, int oldSchemaVersion,
|
||||
ObjectStorage currentObjStorage) {
|
||||
|
@ -124,9 +113,6 @@ public class GenericSaveable implements Saveable {
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (record == null || schema == null) {
|
||||
|
|
|
@ -24,14 +24,13 @@ import ghidra.program.model.address.Address;
|
|||
import ghidra.program.model.util.IntPropertyMap;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* int type and stored with a database table.
|
||||
*/
|
||||
public class IntPropertyMapDB extends PropertyMapDB implements IntPropertyMap {
|
||||
public class IntPropertyMapDB extends PropertyMapDB<Integer> implements IntPropertyMap {
|
||||
|
||||
/**
|
||||
* Construct a integer property map.
|
||||
|
@ -53,9 +52,6 @@ public class IntPropertyMapDB extends PropertyMapDB implements IntPropertyMap {
|
|||
checkMapVersion(openMode, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.IntPropertyMap#add(ghidra.program.model.address.Address, int)
|
||||
*/
|
||||
@Override
|
||||
public void add(Address addr, int value) {
|
||||
lock.acquire();
|
||||
|
@ -72,7 +68,7 @@ public class IntPropertyMapDB extends PropertyMapDB implements IntPropertyMap {
|
|||
if (oldValue == null) {
|
||||
DBRecord rec = propertyTable.getRecord(key);
|
||||
if (rec != null) {
|
||||
oldValue = new Integer(rec.getIntValue(PROPERTY_VALUE_COL));
|
||||
oldValue = rec.getIntValue(PROPERTY_VALUE_COL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,9 +76,9 @@ public class IntPropertyMapDB extends PropertyMapDB implements IntPropertyMap {
|
|||
|
||||
rec.setIntValue(PROPERTY_VALUE_COL, value);
|
||||
propertyTable.putRecord(rec);
|
||||
cache.put(key, new Integer(value));
|
||||
cache.put(key, value);
|
||||
|
||||
changeMgr.setPropertyChanged(name, addr, oldValue, new Integer(value));
|
||||
changeMgr.setPropertyChanged(name, addr, oldValue, value);
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -92,9 +88,6 @@ public class IntPropertyMapDB extends PropertyMapDB implements IntPropertyMap {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.IntPropertyMap#getInt(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public int getInt(Address addr) throws NoValueException {
|
||||
if (propertyTable == null) {
|
||||
|
@ -127,29 +120,14 @@ public class IntPropertyMapDB extends PropertyMapDB implements IntPropertyMap {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public Object getObject(Address addr) {
|
||||
public Integer get(Address addr) {
|
||||
try {
|
||||
return new Integer(getInt(addr));
|
||||
return getInt(addr);
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#applyValue(ghidra.util.prop.PropertyVisitor, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
try {
|
||||
visitor.visit(getInt(addr));
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,14 +24,13 @@ import ghidra.program.model.address.Address;
|
|||
import ghidra.program.model.util.LongPropertyMap;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* long type and stored with a database table.
|
||||
*/
|
||||
public class LongPropertyMapDB extends PropertyMapDB implements LongPropertyMap {
|
||||
public class LongPropertyMapDB extends PropertyMapDB<Long> implements LongPropertyMap {
|
||||
|
||||
/**
|
||||
* Construct a long property map.
|
||||
|
@ -53,9 +52,6 @@ public class LongPropertyMapDB extends PropertyMapDB implements LongPropertyMap
|
|||
checkMapVersion(openMode, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.LongPropertyMap#add(ghidra.program.model.address.Address, long)
|
||||
*/
|
||||
@Override
|
||||
public void add(Address addr, long value) {
|
||||
Long oldValue = null;
|
||||
|
@ -70,15 +66,15 @@ public class LongPropertyMapDB extends PropertyMapDB implements LongPropertyMap
|
|||
if (oldValue == null) {
|
||||
DBRecord rec = propertyTable.getRecord(key);
|
||||
if (rec != null) {
|
||||
oldValue = new Long(rec.getLongValue(PROPERTY_VALUE_COL));
|
||||
oldValue = rec.getLongValue(PROPERTY_VALUE_COL);
|
||||
}
|
||||
}
|
||||
}
|
||||
DBRecord rec = schema.createRecord(key);
|
||||
rec.setLongValue(PROPERTY_VALUE_COL, value);
|
||||
propertyTable.putRecord(rec);
|
||||
cache.put(key, new Long(value));
|
||||
changeMgr.setPropertyChanged(name, addr, oldValue, new Long(value));
|
||||
cache.put(key, value);
|
||||
changeMgr.setPropertyChanged(name, addr, oldValue, value);
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -89,9 +85,6 @@ public class LongPropertyMapDB extends PropertyMapDB implements LongPropertyMap
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.LongPropertyMap#getLong(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public long getLong(Address addr) throws NoValueException {
|
||||
if (propertyTable == null) {
|
||||
|
@ -124,25 +117,14 @@ public class LongPropertyMapDB extends PropertyMapDB implements LongPropertyMap
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public Object getObject(Address addr) {
|
||||
public Long get(Address addr) {
|
||||
try {
|
||||
return new Long(getLong(addr));
|
||||
return getLong(addr);
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#applyValue(ghidra.util.prop.PropertyVisitor, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
throw new NotYetImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,18 +27,20 @@ import ghidra.util.Msg;
|
|||
import ghidra.util.Saveable;
|
||||
import ghidra.util.classfinder.ClassTranslator;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* a Saveable Object type and store within a database table.
|
||||
* a {@link Saveable} Object type and store within a database table.
|
||||
* @param <T> {@link Saveable} property value type
|
||||
*/
|
||||
public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectPropertyMap {
|
||||
public class ObjectPropertyMapDB<T extends Saveable> extends PropertyMapDB<T>
|
||||
implements ObjectPropertyMap<T> {
|
||||
|
||||
private Class<? extends Saveable> saveableObjectClass;
|
||||
private Class<T> saveableObjectClass;
|
||||
private int saveableObjectVersion;
|
||||
private boolean supportsPrivate;
|
||||
private boolean saveableErrorReported = false;
|
||||
|
||||
/**
|
||||
* Construct an Saveable object property map.
|
||||
|
@ -48,36 +50,34 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
* @param changeMgr change manager for event notification
|
||||
* @param addrMap address map.
|
||||
* @param name property name.
|
||||
* @param saveableObjectClass saveable implementation class
|
||||
* @param monitor progress monitor that is only used when upgrading
|
||||
* @param supportsPrivate if private saveable changes should not be broadcast
|
||||
* @throws CancelledException if the user cancels the upgrade operation.
|
||||
* @throws IOException if a database io error occurs.
|
||||
* @throws VersionException the map version is incompatible with
|
||||
* the current Saveable object class version. This will never be thrown
|
||||
* if upgrade is true.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ObjectPropertyMapDB(DBHandle dbHandle, int openMode, ErrorHandler errHandler,
|
||||
ChangeManager changeMgr, AddressMap addrMap, String name,
|
||||
Class<? extends Saveable> saveableObjectClass, TaskMonitor monitor,
|
||||
boolean supportsPrivate) throws VersionException, CancelledException, IOException {
|
||||
Class<T> saveableObjectClass, TaskMonitor monitor, boolean supportsPrivate)
|
||||
throws VersionException, CancelledException, IOException {
|
||||
super(dbHandle, errHandler, changeMgr, addrMap, name);
|
||||
this.saveableObjectClass = saveableObjectClass;
|
||||
this.supportsPrivate = supportsPrivate;
|
||||
Saveable tokenInstance = null;
|
||||
T tokenInstance = null;
|
||||
try {
|
||||
if (saveableObjectClass == GenericSaveable.class) {
|
||||
tokenInstance = new GenericSaveable(null, null);
|
||||
tokenInstance = (T) new GenericSaveable(null, null);
|
||||
}
|
||||
else {
|
||||
tokenInstance = saveableObjectClass.newInstance();
|
||||
tokenInstance = saveableObjectClass.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw new RuntimeException(
|
||||
saveableObjectClass.getName() + " must provide public default constructor");
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(
|
||||
saveableObjectClass.getName() + " must provide public default constructor");
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
saveableObjectVersion = tokenInstance.getSchemaVersion();
|
||||
checkMapVersion(openMode, tokenInstance, monitor);
|
||||
|
@ -123,11 +123,14 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
|
||||
/**
|
||||
* Verify that the storage schema has not changed.
|
||||
* @param upgrade
|
||||
* @param tokenInstance
|
||||
* @throws VersionException
|
||||
* @param openMode open mode
|
||||
* @param tokenInstance token saveable instance
|
||||
* @param monitor task monitor
|
||||
* @throws VersionException if saveable schema version error occurs
|
||||
* @throws CancelledException if task is cancelled
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
private void checkMapVersion(int openMode, Saveable tokenInstance, TaskMonitor monitor)
|
||||
private void checkMapVersion(int openMode, T tokenInstance, TaskMonitor monitor)
|
||||
throws VersionException, CancelledException, IOException {
|
||||
if (propertyTable == null) {
|
||||
return;
|
||||
|
@ -149,7 +152,6 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
Msg.showError(this, null, "Properties Removed on Upgrade",
|
||||
"Warning! unable to upgrade properties for " + saveableObjectClass.getName() +
|
||||
"\nThese properties have been removed.");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,11 +159,14 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
/**
|
||||
* Attempt to upgrade the map table records to the current schema.
|
||||
* If unable to upgrade any of the map records, the table is removed.
|
||||
* @param tokenInstance
|
||||
* @param tokenInstance token saveable instance
|
||||
* @param monitor task monitor
|
||||
* @return true if all records were successfully upgrade. A false
|
||||
* value indicates that one or more entries were dropped.
|
||||
* @throws CancelledException if task is cancelled
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
private boolean upgradeTable(Saveable tokenInstance, TaskMonitor monitor)
|
||||
private boolean upgradeTable(T tokenInstance, TaskMonitor monitor)
|
||||
throws CancelledException, IOException {
|
||||
|
||||
boolean allRecordsUpgraded = true;
|
||||
|
@ -247,14 +252,14 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr, Saveable value) {
|
||||
public void add(Address addr, T value) {
|
||||
lock.acquire();
|
||||
try {
|
||||
if (!saveableObjectClass.isAssignableFrom(value.getClass())) {
|
||||
throw new IllegalArgumentException();
|
||||
throw new IllegalArgumentException("value is not " + saveableObjectClass.getName());
|
||||
}
|
||||
long key = addrMap.getKey(addr, true);
|
||||
Saveable oldValue = (Saveable) getObject(addr);
|
||||
T oldValue = get(addr);
|
||||
|
||||
String tableName = getTableName();
|
||||
Schema s;
|
||||
|
@ -316,17 +321,18 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectClass() {
|
||||
public Class<T> getValueClass() {
|
||||
return saveableObjectClass;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object getObject(Address addr) {
|
||||
public T get(Address addr) {
|
||||
if (propertyTable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Saveable obj = null;
|
||||
T obj = null;
|
||||
|
||||
lock.acquire();
|
||||
try {
|
||||
|
@ -334,7 +340,7 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
if (key == AddressMap.INVALID_ADDRESS_KEY) {
|
||||
return null;
|
||||
}
|
||||
obj = (Saveable) cache.get(key);
|
||||
obj = (T) cache.get(key);
|
||||
if (obj != null) {
|
||||
return obj;
|
||||
}
|
||||
|
@ -345,10 +351,10 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
}
|
||||
ObjectStorageAdapterDB objStorage = new ObjectStorageAdapterDB(rec);
|
||||
if (saveableObjectClass == GenericSaveable.class) {
|
||||
obj = new GenericSaveable(rec, propertyTable.getSchema());
|
||||
obj = (T) new GenericSaveable(rec, propertyTable.getSchema());
|
||||
}
|
||||
else {
|
||||
obj = saveableObjectClass.newInstance();
|
||||
obj = saveableObjectClass.getDeclaredConstructor().newInstance();
|
||||
obj.restore(objStorage);
|
||||
}
|
||||
}
|
||||
|
@ -372,22 +378,6 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
Saveable obj = (Saveable) getObject(addr);
|
||||
if (obj != null) {
|
||||
visitor.visit(obj);
|
||||
}
|
||||
}
|
||||
|
||||
// @see PropertyMapDB#getPropertyFieldClass() <- doesn't exist
|
||||
/**
|
||||
* NOTE: Custom schema is utilized.
|
||||
*/
|
||||
protected Class<?> getPropertyFieldClass() {
|
||||
throw new AssertException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the necessary table(s) to support this property.
|
||||
* Schema will vary depending upon Saveable object.
|
||||
|
@ -396,23 +386,4 @@ public class ObjectPropertyMapDB extends PropertyMapDB implements ObjectProperty
|
|||
throw new AssertException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to upgrade the specified object map.
|
||||
* @param dbHandle
|
||||
* @param errHandler
|
||||
* @param changeMgr
|
||||
* @param addrMap
|
||||
* @param name
|
||||
* @param saveableObjectClass
|
||||
* @param version
|
||||
* @return upgraded map instance or null if unable to upgrade.
|
||||
*/
|
||||
static ObjectPropertyMapDB upgradeMap(DBHandle dbHandle, ErrorHandler errHandler,
|
||||
ChangeManager changeMgr, AddressMap addrMap, String name, Class<?> saveableObjectClass,
|
||||
int version) {
|
||||
|
||||
// TODO Fill-in stuff here....
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -24,7 +23,8 @@ interface PropertiesDBAdapter {
|
|||
|
||||
/**
|
||||
* Iterate over the records contained within the Properties table.
|
||||
* @return RecordIterator
|
||||
* @return RecordIterator record iterator
|
||||
* @throws IOException if an IO error occurs
|
||||
*/
|
||||
RecordIterator getRecords() throws IOException;
|
||||
|
||||
|
@ -34,12 +34,14 @@ interface PropertiesDBAdapter {
|
|||
* @param type property map type
|
||||
* @param objClassName full class name for Saveable objects when
|
||||
* type is OBJECT_PROPERTY_TYPE, else value should be null.
|
||||
* @throws IOException if an IO error occurs
|
||||
*/
|
||||
void putRecord(String propertyName, byte type, String objClassName) throws IOException;
|
||||
|
||||
/**
|
||||
* Remove a specific property map definition record.
|
||||
* @param propertyName
|
||||
* @param propertyName property map name
|
||||
* @throws IOException if an IO error occurs
|
||||
*/
|
||||
void removeRecord(String propertyName) throws IOException;
|
||||
|
||||
|
|
|
@ -15,34 +15,31 @@
|
|||
*/
|
||||
package ghidra.program.database.properties;
|
||||
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import db.*;
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
||||
class PropertiesDBAdapterV0 implements PropertiesDBAdapter {
|
||||
|
||||
private Table propertiesTable;
|
||||
|
||||
/**
|
||||
* @param dbHandle
|
||||
* Construct property map DB adapter
|
||||
* @param dbHandle database handle
|
||||
* @throws VersionException if version error occurs
|
||||
*/
|
||||
public PropertiesDBAdapterV0(DBHandle dbHandle) throws VersionException {
|
||||
propertiesTable = dbHandle.getTable(DBPropertyMapManager.PROPERTIES_TABLE_NAME);
|
||||
testVersion(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.database.properties.PropertiesDBAdapter#iterator()
|
||||
*/
|
||||
@Override
|
||||
public RecordIterator getRecords() throws IOException {
|
||||
return propertiesTable.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.database.properties.PropertiesDBAdapter#createRecord(java.lang.String, byte, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void putRecord(String propertyName, byte type, String objClassName) throws IOException {
|
||||
DBRecord rec =
|
||||
DBPropertyMapManager.PROPERTIES_SCHEMA.createRecord(new StringField(propertyName));
|
||||
|
@ -54,9 +51,7 @@ class PropertiesDBAdapterV0 implements PropertiesDBAdapter {
|
|||
propertiesTable.putRecord(rec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.database.properties.PropertiesDBAdapter#removeRecord(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void removeRecord(String propertyName) throws IOException {
|
||||
propertiesTable.deleteRecord(new StringField(propertyName));
|
||||
}
|
||||
|
|
|
@ -30,13 +30,13 @@ import ghidra.util.Lock;
|
|||
import ghidra.util.datastruct.ObjectCache;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
/**
|
||||
* Abstract class which defines a map containing properties over a set of addresses.
|
||||
* The map is stored within a database table.
|
||||
* @param <T> property value type
|
||||
*/
|
||||
public abstract class PropertyMapDB implements PropertyMap {
|
||||
public abstract class PropertyMapDB<T> implements PropertyMap<T> {
|
||||
|
||||
private static final String PROPERTY_TABLE_PREFIX = "Property Map - ";
|
||||
|
||||
|
@ -72,7 +72,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
* @param changeMgr notification of events
|
||||
* @param addrMap address map.
|
||||
* @param name property name.
|
||||
* @param lock the synchronization lock
|
||||
*/
|
||||
PropertyMapDB(DBHandle dbHandle, ErrorHandler errHandler, ChangeManager changeMgr,
|
||||
AddressMap addrMap, String name) {
|
||||
|
@ -173,7 +172,8 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
* Create the default propertyTable.
|
||||
* This method may be called by add property methods if propertyTable
|
||||
* is null.
|
||||
* @throws IOException
|
||||
* @param valueField property value field type
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
protected void createTable(Field valueField) throws IOException {
|
||||
if (valueField != null) {
|
||||
|
@ -188,9 +188,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
propertyTable = dbHandle.createTable(getTableName(), schema);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
@ -215,7 +212,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
* Delete this property map and all underlying tables.
|
||||
* This method should be overidden if any table other than the
|
||||
* default propertyTable is used.
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
lock.acquire();
|
||||
|
@ -231,9 +228,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#intersects(ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public boolean intersects(Address startAddr, Address endAddr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -250,9 +244,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#intersects(ghidra.program.model.address.AddressSetView)
|
||||
*/
|
||||
@Override
|
||||
public boolean intersects(AddressSetView set) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -269,9 +260,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#removeRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public boolean removeRange(Address startAddr, Address endAddr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -293,9 +281,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#remove(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public boolean remove(Address addr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -318,9 +303,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#hasProperty(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasProperty(Address addr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -343,9 +325,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getNextPropertyAddress(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public Address getNextPropertyAddress(Address addr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -356,6 +335,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return addrMap.decodeAddress(iter.next());
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -363,9 +343,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPreviousPropertyAddress(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public Address getPreviousPropertyAddress(Address addr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -376,6 +353,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return addrMap.decodeAddress(iter.previous());
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -383,9 +361,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getFirstPropertyAddress()
|
||||
*/
|
||||
@Override
|
||||
public Address getFirstPropertyAddress() {
|
||||
if (propertyTable == null) {
|
||||
|
@ -396,6 +371,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return addrMap.decodeAddress(iter.next());
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -403,9 +379,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getLastPropertyAddress()
|
||||
*/
|
||||
@Override
|
||||
public Address getLastPropertyAddress() {
|
||||
if (propertyTable == null) {
|
||||
|
@ -417,6 +390,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return addrMap.decodeAddress(iter.previous());
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -424,9 +398,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getSize()
|
||||
*/
|
||||
@Override
|
||||
public int getSize() {
|
||||
return propertyTable != null ? propertyTable.getRecordCount() : 0;
|
||||
|
@ -438,7 +409,7 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
* @param atStart true if the iterator should be positioned at the start
|
||||
* of the range
|
||||
* @return long address iterator.
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public AddressKeyIterator getAddressKeyIterator(AddressSetView set, boolean atStart)
|
||||
throws IOException {
|
||||
|
@ -453,10 +424,10 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
|
||||
/**
|
||||
* Get an iterator over the long address keys which contain a property value.
|
||||
* @param start
|
||||
* @param start iterator starting position
|
||||
* @param before true if the iterator should be positioned before the start address
|
||||
* @return long address iterator.
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public AddressKeyIterator getAddressKeyIterator(Address start, boolean before)
|
||||
throws IOException {
|
||||
|
@ -469,12 +440,12 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
|
||||
/**
|
||||
* Get an iterator over the long address keys which contain a property value.
|
||||
* @param start
|
||||
* @param end
|
||||
* @param start start of iterator address range
|
||||
* @param end end of iterator address range
|
||||
* @param atStart true if the iterator should be positioned at the start
|
||||
* of the range
|
||||
* @return long address iterator.
|
||||
* @throws IOException
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
public AddressKeyIterator getAddressKeyIterator(Address start, Address end, boolean atStart)
|
||||
throws IOException {
|
||||
|
@ -488,9 +459,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return new AddressKeyIterator(propertyTable, addrMap, start, end, end, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(Address start, Address end) {
|
||||
AddressKeyIterator keyIter = null;
|
||||
|
@ -503,9 +471,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return new AddressKeyAddressIterator(keyIter, true, addrMap, errHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, ghidra.program.model.address.Address, boolean)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(Address start, Address end, boolean forward) {
|
||||
AddressKeyIterator keyIter = null;
|
||||
|
@ -518,9 +483,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return new AddressKeyAddressIterator(keyIter, forward, addrMap, errHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator()
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator() {
|
||||
if (propertyTable == null) {
|
||||
|
@ -536,9 +498,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return new AddressKeyAddressIterator(keyIter, true, addrMap, errHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.AddressSetView)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(AddressSetView asv) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -555,9 +514,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return new AddressKeyAddressIterator(keyIter, true, addrMap, errHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.AddressSetView, boolean)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) {
|
||||
if (propertyTable == null || (asv != null && asv.isEmpty())) {
|
||||
|
@ -580,9 +536,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
return new AddressKeyAddressIterator(keyIter, forward, addrMap, errHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, boolean)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(Address start, boolean forward) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -613,9 +566,6 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#moveRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void moveRange(Address start, Address end, Address newStart) {
|
||||
lock.acquire();
|
||||
|
@ -624,9 +574,10 @@ public abstract class PropertyMapDB implements PropertyMap {
|
|||
if (propertyTable != null) {
|
||||
try {
|
||||
DatabaseTableUtils.updateAddressKey(propertyTable, addrMap, start, end,
|
||||
newStart, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
newStart, TaskMonitor.DUMMY);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// will not happen
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
|
|
@ -25,14 +25,13 @@ import ghidra.program.model.util.StringPropertyMap;
|
|||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* String type and stored with a database table.
|
||||
*/
|
||||
public class StringPropertyMapDB extends PropertyMapDB implements StringPropertyMap {
|
||||
public class StringPropertyMapDB extends PropertyMapDB<String> implements StringPropertyMap {
|
||||
|
||||
/**
|
||||
* Construct an String property map.
|
||||
|
@ -54,9 +53,6 @@ public class StringPropertyMapDB extends PropertyMapDB implements StringProperty
|
|||
checkMapVersion(openMode, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.StringPropertyMap#add(ghidra.program.model.address.Address, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void add(Address addr, String value) {
|
||||
lock.acquire();
|
||||
|
@ -91,9 +87,6 @@ public class StringPropertyMapDB extends PropertyMapDB implements StringProperty
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.StringPropertyMap#getString(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public String getString(Address addr) {
|
||||
if (propertyTable == null) {
|
||||
|
@ -130,23 +123,9 @@ public class StringPropertyMapDB extends PropertyMapDB implements StringProperty
|
|||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public Object getObject(Address addr) {
|
||||
public String get(Address addr) {
|
||||
return getString(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#applyValue(ghidra.util.prop.PropertyVisitor, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
String str = getString(addr);
|
||||
if (str != null) {
|
||||
visitor.visit(str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,19 +17,21 @@ package ghidra.program.database.properties;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
import db.DBHandle;
|
||||
import db.util.ErrorHandler;
|
||||
import ghidra.program.database.map.AddressMap;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import db.DBHandle;
|
||||
import db.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* This class provides a dummy map for an unsupported map.
|
||||
*/
|
||||
public class UnsupportedMapDB extends PropertyMapDB {
|
||||
public class UnsupportedMapDB extends PropertyMapDB<Object> {
|
||||
|
||||
/**
|
||||
* Construct a dummy property map.
|
||||
|
@ -52,18 +53,24 @@ public class UnsupportedMapDB extends PropertyMapDB {
|
|||
checkMapVersion(openMode, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#applyValue(ghidra.util.prop.PropertyVisitor, ghidra.program.model.address.Address)
|
||||
*/
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
throw new AssertException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
@Override
|
||||
public Class<Object> getValueClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Address addr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasProperty(Address addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Address addr, Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,26 +15,26 @@
|
|||
*/
|
||||
package ghidra.program.database.properties;
|
||||
|
||||
import ghidra.program.database.map.AddressMap;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.util.VoidPropertyMap;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import db.DBHandle;
|
||||
import db.DBRecord;
|
||||
import db.util.ErrorHandler;
|
||||
import ghidra.program.database.map.AddressMap;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.util.VoidPropertyMap;
|
||||
import ghidra.program.util.ChangeManager;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* "void" type, which is a marker for whether a property exists.
|
||||
* Records contain only a address key are stored within the underlying database table.
|
||||
* Object values returned are either {@link Boolean#TRUE} or null.
|
||||
*/
|
||||
public class VoidPropertyMapDB extends PropertyMapDB implements VoidPropertyMap {
|
||||
public class VoidPropertyMapDB extends PropertyMapDB<Boolean> implements VoidPropertyMap {
|
||||
|
||||
private static Object VOID_OBJECT = new Object();
|
||||
|
||||
|
@ -58,14 +58,12 @@ public class VoidPropertyMapDB extends PropertyMapDB implements VoidPropertyMap
|
|||
checkMapVersion(openMode, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.VoidPropertyMap#add(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void add(Address addr) {
|
||||
lock.acquire();
|
||||
try {
|
||||
long key = addrMap.getKey(addr, true);
|
||||
Boolean oldValue = new Boolean(hasProperty(addr));
|
||||
Boolean oldValue = hasProperty(addr);
|
||||
|
||||
if (propertyTable == null) {
|
||||
createTable(null);
|
||||
|
@ -73,7 +71,7 @@ public class VoidPropertyMapDB extends PropertyMapDB implements VoidPropertyMap
|
|||
DBRecord rec = schema.createRecord(key);
|
||||
propertyTable.putRecord(rec);
|
||||
cache.put(key, VOID_OBJECT);
|
||||
changeMgr.setPropertyChanged(name, addr, oldValue, new Boolean(true));
|
||||
changeMgr.setPropertyChanged(name, addr, oldValue, true);
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
|
@ -83,19 +81,8 @@ public class VoidPropertyMapDB extends PropertyMapDB implements VoidPropertyMap
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#applyValue(ghidra.util.prop.PropertyVisitor, ghidra.program.model.address.Address)
|
||||
*/
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
if (hasProperty(addr)) {
|
||||
visitor.visit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
@Override
|
||||
public Boolean get(Address addr) {
|
||||
if (hasProperty(addr)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,7 +16,7 @@
|
|||
package ghidra.program.model.address;
|
||||
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
import ghidra.util.prop.ObjectPropertySet;
|
||||
import ghidra.util.map.ObjectValueMap;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -51,7 +50,7 @@ import java.io.Serializable;
|
|||
public class AddressObjectMap {
|
||||
|
||||
private AddressMapImpl addrMap = new AddressMapImpl();
|
||||
private ObjectPropertySet objMarkers = new ObjectPropertySet("AddressObjectMap");
|
||||
private ObjectValueMap objMarkers = new ObjectValueMap("AddressObjectMap");
|
||||
|
||||
private static final Object [] emptyArray = new Object[0];
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package ghidra.program.model.listing;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.Register;
|
||||
|
@ -26,14 +25,12 @@ import ghidra.program.model.mem.MemBuffer;
|
|||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.program.model.util.PropertySet;
|
||||
|
||||
/**
|
||||
* Interface common to both instructions and data.
|
||||
*/
|
||||
public interface CodeUnit extends MemBuffer {
|
||||
public interface CodeUnit extends MemBuffer, PropertySet {
|
||||
|
||||
/**
|
||||
* Indicator for a mnemonic (versus an operand).
|
||||
|
@ -94,88 +91,6 @@ public interface CodeUnit extends MemBuffer {
|
|||
*/
|
||||
public String getAddressString(boolean showBlockName, boolean pad);
|
||||
|
||||
/**
|
||||
* Set the named property with the given value at the address of this codeunit.
|
||||
* @param name the name of the property.
|
||||
* @param value value to be stored.
|
||||
*/
|
||||
public void setProperty(String name, Saveable value);
|
||||
|
||||
/**
|
||||
* Set the named property with the given value at the address of this codeunit.
|
||||
* @param name the name of the property.
|
||||
* @param value value to be stored.
|
||||
*/
|
||||
public void setProperty(String name, String value);
|
||||
|
||||
/**
|
||||
* Set the named property with the given value at the address of this codeunit.
|
||||
* @param name the name of the property.
|
||||
* @param value value to be stored.
|
||||
*/
|
||||
public void setProperty(String name, int value);
|
||||
|
||||
/**
|
||||
* Set the named property. This method is used for "void" properites. The
|
||||
* property is either set or not set - there is no value
|
||||
* @param name the name of the property.
|
||||
*/
|
||||
public void setProperty(String name);
|
||||
|
||||
/**
|
||||
* Get the object property for name; returns null if
|
||||
* there is no name property for this code unit.
|
||||
* @param name the name of the property
|
||||
*/
|
||||
public Saveable getObjectProperty(String name);
|
||||
|
||||
/**
|
||||
* Get the string property for name; returns null if
|
||||
* there is no name property for this code unit.
|
||||
* @param name the name of the property
|
||||
*/
|
||||
public String getStringProperty(String name);
|
||||
|
||||
/**
|
||||
* Get the int property for name.
|
||||
* @param name the name of the property
|
||||
* @throws NoValueException if there is not name property
|
||||
* for this code unit
|
||||
*/
|
||||
public int getIntProperty(String name) throws NoValueException;
|
||||
|
||||
/**
|
||||
* Returns true if the codeunit has the given property defined.
|
||||
* @param name the name of the property
|
||||
*/
|
||||
public boolean hasProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns whether this code unit is marked as having the
|
||||
* name property.
|
||||
* @param name the name of the property
|
||||
*/
|
||||
boolean getVoidProperty(String name);
|
||||
|
||||
/**
|
||||
* Get an iterator over the property names.
|
||||
*/
|
||||
public Iterator<String> propertyNames();
|
||||
|
||||
/**
|
||||
* Remove the property with the given name from this code unit.
|
||||
* @param name the name of the property
|
||||
*/
|
||||
public void removeProperty(String name);
|
||||
|
||||
/**
|
||||
* Invokes the visit() method of the specified PropertyVisitor if the named
|
||||
* property exists for this code unit.
|
||||
* @param visitor the class implementing the PropertyVisitor interface.
|
||||
* @param propertyName the name of the property to be visited.
|
||||
*/
|
||||
public void visitProperty(PropertyVisitor visitor, String propertyName);
|
||||
|
||||
/**
|
||||
* Get the label for this code unit.
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,6 @@ import ghidra.program.model.scalar.Scalar;
|
|||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
|
||||
/**
|
||||
* DataStub can be extended for use by tests. It throws an UnsupportedOperationException
|
||||
|
@ -100,11 +99,6 @@ public class DataStub implements Data {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitProperty(PropertyVisitor visitor, String propertyName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -28,7 +28,6 @@ import ghidra.program.model.scalar.Scalar;
|
|||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
|
||||
/**
|
||||
* InstructionStub can be extended for use by tests. It throws an UnsupportedOperationException
|
||||
|
@ -97,11 +96,6 @@ public class InstructionStub implements Instruction {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitProperty(PropertyVisitor visitor, String propertyName) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -88,18 +88,19 @@ public interface ProgramUserData extends UserData {
|
|||
* @param propertyName the name of property map
|
||||
* @param saveableObjectClass the class type for the object property map
|
||||
* @param create creates the property map if it does not exist
|
||||
* @param <T> {@link Saveable} property value type
|
||||
* @return property map
|
||||
* @throws PropertyTypeMismatchException if a conflicting map definition was found
|
||||
*/
|
||||
public ObjectPropertyMap getObjectProperty(String owner, String propertyName,
|
||||
Class<? extends Saveable> saveableObjectClass, boolean create);
|
||||
public <T extends Saveable> ObjectPropertyMap<T> getObjectProperty(String owner,
|
||||
String propertyName, Class<T> saveableObjectClass, boolean create);
|
||||
|
||||
/**
|
||||
* Get all property maps associated with a specific owner.
|
||||
* @param owner name of property owner (e.g., plugin name)
|
||||
* @return list of property maps
|
||||
*/
|
||||
public List<PropertyMap> getProperties(String owner);
|
||||
public List<PropertyMap<?>> getProperties(String owner);
|
||||
|
||||
/**
|
||||
* Returns list of all property owners for which property maps have been defined.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,50 +17,39 @@ package ghidra.program.model.util;
|
|||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.IntPropertySet;
|
||||
import ghidra.util.map.IntValueMap;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* int type.
|
||||
*/
|
||||
public class DefaultIntPropertyMap extends DefaultPropertyMap implements IntPropertyMap {
|
||||
public class DefaultIntPropertyMap extends DefaultPropertyMap<Integer> implements IntPropertyMap {
|
||||
|
||||
private final static long serialVersionUID = 1;
|
||||
private IntPropertySet ips;
|
||||
private IntValueMap ips;
|
||||
|
||||
/**
|
||||
* Construct a new IntPropertyMap
|
||||
* @param name name of property
|
||||
*/
|
||||
public DefaultIntPropertyMap(String name) {
|
||||
super(new IntPropertySet(name));
|
||||
ips = (IntPropertySet)propertyMgr;
|
||||
super(new IntValueMap(name));
|
||||
ips = (IntValueMap)propertyMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an int value at the specified address.
|
||||
* @param addr address for the property
|
||||
* @param value value of the property
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void add(Address addr, int value) {
|
||||
ips.putInt(addrMap.getKey(addr), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the integer value at the given address.
|
||||
* @param addr the address from where to get the int value
|
||||
* @throws NoValueException if there is no property value at addr.
|
||||
*/
|
||||
@Override
|
||||
public int getInt(Address addr) throws NoValueException {
|
||||
return ips.getInt(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
@Override
|
||||
public Integer get(Address addr) {
|
||||
try {
|
||||
return new Integer(getInt(addr));
|
||||
return getInt(addr);
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.LongPropertySet;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* long type.
|
||||
*/
|
||||
public class DefaultLongPropertyMap extends DefaultPropertyMap implements LongPropertyMap {
|
||||
|
||||
private final static long serialVersionUID = 1;
|
||||
private LongPropertySet lps;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new LongPropertyMap
|
||||
* @param name name of property
|
||||
*/
|
||||
public DefaultLongPropertyMap(String name) {
|
||||
super(new LongPropertySet(name));
|
||||
lps = (LongPropertySet)propertyMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a long value at the specified address.
|
||||
* @param addr address for the property
|
||||
* @param value value of the property
|
||||
* @exception TypeMismatchException thrown if the
|
||||
* property does not have long values.
|
||||
*/
|
||||
public void add(Address addr, long value) {
|
||||
lps.putLong(addrMap.getKey(addr), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long value at the given address.
|
||||
* @param addr the address from where to get the long value
|
||||
* @throws NoValueException if there is no property value at addr.
|
||||
*/
|
||||
public long getLong(Address addr) throws NoValueException {
|
||||
return lps.getLong(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
try {
|
||||
return new Long(getLong(addr));
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.prop.SaveableObjectPropertySet;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* Object type. The Object type must implement the Saveable interface.
|
||||
*/
|
||||
public class DefaultObjectPropertyMap extends DefaultPropertyMap implements ObjectPropertyMap {
|
||||
|
||||
private SaveableObjectPropertySet propSet;
|
||||
|
||||
/**
|
||||
* Construct a new ObjectPropertyMap
|
||||
* @param name of property
|
||||
* @param objectClass class of objects to be stored in this map
|
||||
*/
|
||||
public DefaultObjectPropertyMap(String name, Class<?> objectClass) {
|
||||
super(new SaveableObjectPropertySet(name, objectClass));
|
||||
propSet = (SaveableObjectPropertySet)propertyMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object value at the specified address.
|
||||
* @param addr address for the property
|
||||
* @param value value of the property
|
||||
* @exception TypeMismatchException thrown if the
|
||||
* property does not have Saveable object values.
|
||||
*/
|
||||
public void add(Address addr, Saveable value) {
|
||||
propSet.putObject(addrMap.getKey(addr), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object value at the given address.
|
||||
* @param addr the address from where to get the int value
|
||||
* @return Saveable object or null if property not found at addr.
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
return propSet.getObject(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.ObjectPropertyMap#getObjectClass()
|
||||
*/
|
||||
public Class<?> getObjectClass() {
|
||||
return propSet.getObjectClass();
|
||||
}
|
||||
|
||||
}
|
|
@ -24,8 +24,7 @@ import java.util.NoSuchElementException;
|
|||
import ghidra.program.model.address.*;
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
import ghidra.util.prop.PropertySet;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
import ghidra.util.map.ValueMap;
|
||||
|
||||
/**
|
||||
* PropertyMap is used to store values for a fixed property at
|
||||
|
@ -38,11 +37,12 @@ import ghidra.util.prop.PropertyVisitor;
|
|||
* to efficiently search for the next and previous occurrence of the
|
||||
* property relative to a given address.
|
||||
* The subclass provides the createPage() method that dictates
|
||||
* the type of PropertyPage that will be managed.
|
||||
* the type of PropertyPage that will be managed.
|
||||
* @param <T> property value type
|
||||
*/
|
||||
public abstract class DefaultPropertyMap implements PropertyMap {
|
||||
public abstract class DefaultPropertyMap<T> implements PropertyMap<T> {
|
||||
|
||||
protected PropertySet propertyMgr;
|
||||
protected ValueMap<T> propertyMgr;
|
||||
protected AddressMapImpl addrMap;
|
||||
protected String description;
|
||||
|
||||
|
@ -51,14 +51,11 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
* @param propertyMgr property manager that manages storage of
|
||||
* properties
|
||||
*/
|
||||
public DefaultPropertyMap(PropertySet propertyMgr) {
|
||||
public DefaultPropertyMap(ValueMap<T> propertyMgr) {
|
||||
this.propertyMgr = propertyMgr;
|
||||
this.addrMap = new AddressMapImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name for this property manager.
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return propertyMgr.getName();
|
||||
|
@ -82,23 +79,11 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given two addresses, indicate whether there is an address in
|
||||
* that range (inclusive) having the property.<p>
|
||||
* @param start the start of the range.
|
||||
* @param end the end of the range.
|
||||
*
|
||||
* @return boolean true if at least one address in the range
|
||||
* has the property, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean intersects(Address start, Address end) {
|
||||
return propertyMgr.intersects(addrMap.getKey(start), addrMap.getKey(end));
|
||||
}
|
||||
|
||||
/*
|
||||
* @see ghidra.program.model.util.PropertyMap#intersects(ghidra.program.model.address.AddressSetView)
|
||||
*/
|
||||
@Override
|
||||
public boolean intersects(AddressSetView set) {
|
||||
AddressRangeIterator ranges = set.getAddressRanges();
|
||||
|
@ -111,43 +96,22 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all property values within a given range.
|
||||
* @param start begin range
|
||||
* @param end end range, inclusive
|
||||
* @return true if any property value was removed; return
|
||||
* false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean removeRange(Address start, Address end) {
|
||||
return propertyMgr.removeRange(addrMap.getKey(start), addrMap.getKey(end));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the property value at the given address.
|
||||
* @return true if the property value was removed, false
|
||||
* otherwise.
|
||||
* @param addr the address where the property should be removed
|
||||
*/
|
||||
@Override
|
||||
public boolean remove(Address addr) {
|
||||
return propertyMgr.remove(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns whether there is a property value at addr.
|
||||
* @param addr the address in question
|
||||
*/
|
||||
@Override
|
||||
public boolean hasProperty(Address addr) {
|
||||
return propertyMgr.hasProperty(addrMap.getKey(addr));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next address where the property value exists.
|
||||
* @param addr the address from which to begin the search (exclusive).
|
||||
*/
|
||||
@Override
|
||||
public Address getNextPropertyAddress(Address addr) {
|
||||
|
||||
|
@ -161,11 +125,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the previous Address where a property value exists.
|
||||
* @param addr the address from which
|
||||
* to begin the search (exclusive).
|
||||
*/
|
||||
@Override
|
||||
public Address getPreviousPropertyAddress(Address addr) {
|
||||
try {
|
||||
|
@ -177,9 +136,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first Address where a property value exists.
|
||||
*/
|
||||
@Override
|
||||
public Address getFirstPropertyAddress() {
|
||||
try {
|
||||
|
@ -192,9 +148,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last Address where a property value exists.
|
||||
*/
|
||||
@Override
|
||||
public Address getLastPropertyAddress() {
|
||||
try {
|
||||
|
@ -206,82 +159,41 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of properties in the map.
|
||||
*/
|
||||
@Override
|
||||
public int getSize() {
|
||||
return propertyMgr.getSize();
|
||||
}
|
||||
|
||||
/** Returns an iterator over addresses that have a property value within the
|
||||
* given address range.
|
||||
* @param start the first address in the range.
|
||||
* @param end the last address in the range.
|
||||
* @exception TypeMismatchException thrown if the property does not
|
||||
* have values of type <CODE>Object</CODE>.
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(Address start, Address end) {
|
||||
return new AddressPropertyIterator(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, ghidra.program.model.address.Address, boolean)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(Address start, Address end, boolean forward) {
|
||||
return new AddressPropertyIterator(start, end, forward);
|
||||
}
|
||||
|
||||
/** Returns an iterator over addresses that have a property value within the
|
||||
* property map.
|
||||
* @exception TypeMismatchException thrown if the property does not
|
||||
* have values of type <CODE>Object</CODE>.
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator() {
|
||||
return new AddressPropertyIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the addresses that have a property value and
|
||||
* are in the given address set.
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(AddressSetView asv) {
|
||||
return new AddressSetPropertyIterator(asv, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.AddressSetView, boolean)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) {
|
||||
return new AddressSetPropertyIterator(asv, forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getPropertyIterator(ghidra.program.model.address.Address, boolean)
|
||||
*/
|
||||
@Override
|
||||
public AddressIterator getPropertyIterator(Address start, boolean forward) {
|
||||
return new AddressPropertyIterator(start, forward);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.program.model.util.PropertyMap#applyValue(ghidra.util.prop.PropertyVisitor, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void applyValue(PropertyVisitor visitor, Address addr) {
|
||||
propertyMgr.applyValue(visitor, addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.program.model.util.PropertyMap#moveRange(ghidra.program.model.address.Address, ghidra.program.model.address.Address, ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public void moveRange(Address start, Address end, Address newStart) {
|
||||
propertyMgr.moveRange(addrMap.getKey(start), addrMap.getKey(end), addrMap.getKey(newStart));
|
||||
|
@ -338,17 +250,11 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Iterator#remove()
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AddressIterator#hasNext()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (forward) {
|
||||
|
@ -357,9 +263,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return iter.hasPrevious();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AddressIterator#next()
|
||||
*/
|
||||
@Override
|
||||
public Address next() {
|
||||
try {
|
||||
|
@ -392,17 +295,11 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
this.atStart = atStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.util.Iterator#remove()
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AddressIterator#hasNext()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (nextAddr == null) {
|
||||
|
@ -411,21 +308,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return nextAddr != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AddressIterator#hasPrevious()
|
||||
*/
|
||||
public boolean hasPrevious() {
|
||||
throw new UnsupportedOperationException();
|
||||
// nextAddr = null;
|
||||
// if (prevAddr == null) {
|
||||
// prevAddr = findPrevious();
|
||||
// }
|
||||
// return prevAddr != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AddressIterator#next()
|
||||
*/
|
||||
@Override
|
||||
public Address next() {
|
||||
if (hasNext()) {
|
||||
|
@ -436,19 +318,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AddressIterator#previous()
|
||||
*/
|
||||
public Address previous() {
|
||||
throw new UnsupportedOperationException();
|
||||
// if (hasPrevious()) {
|
||||
// Address addr = prevAddr;
|
||||
// prevAddr = null;
|
||||
// return addr;
|
||||
// }
|
||||
// return null;
|
||||
}
|
||||
|
||||
private Address findNext() {
|
||||
if ((iter != null) && iter.hasNext()) {
|
||||
return iter.next();
|
||||
|
@ -469,26 +338,6 @@ public abstract class DefaultPropertyMap implements PropertyMap {
|
|||
return null;
|
||||
}
|
||||
|
||||
// private Address findPrevious() {
|
||||
// if ((iter != null) && iter.hasPrevious()) {
|
||||
// return iter.previous();
|
||||
// }
|
||||
// while(ranges.hasPrevious()) {
|
||||
// AddressRange range = ranges.previous();
|
||||
// if (range == curRange) {
|
||||
// continue;
|
||||
// }
|
||||
// curRange = range;
|
||||
// iter = new AddressPropertyIterator(range.getMinAddress(),
|
||||
// range.getMaxAddress(),
|
||||
// atStart);
|
||||
// if (iter.hasPrevious()) {
|
||||
// return iter.previous();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Iterator<Address> iterator() {
|
||||
return this;
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.prop.ObjectPropertySet;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* Settings type.
|
||||
*/
|
||||
public class DefaultSettingsPropertyMap extends DefaultPropertyMap implements SettingsPropertyMap {
|
||||
|
||||
private ObjectPropertySet propSet;
|
||||
|
||||
/**
|
||||
* Construct a new DefaultSettingsPropertyMap
|
||||
* @param name of property
|
||||
*/
|
||||
public DefaultSettingsPropertyMap(String name) {
|
||||
super(new ObjectPropertySet(name));
|
||||
propSet = (ObjectPropertySet)propertyMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an object value at the specified address.
|
||||
* @param addr address for the property
|
||||
* @param value value of the property
|
||||
* @exception TypeMismatchException thrown if the
|
||||
* property does not have Settings object values.
|
||||
*/
|
||||
public void add(Address addr, Settings value) {
|
||||
propSet.putObject(addrMap.getKey(addr), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Settings object value at the given address.
|
||||
* @param addr the address from where to get the int value
|
||||
* @return Settings object or null if property not found at addr.
|
||||
*/
|
||||
public Settings getSettings(Address addr) {
|
||||
return (Settings)propSet.getObject(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
return getSettings(addr);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.prop.StringPropertySet;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* String type.
|
||||
*/
|
||||
public class DefaultStringPropertyMap extends DefaultPropertyMap implements StringPropertyMap {
|
||||
|
||||
private StringPropertySet propSet;
|
||||
|
||||
/**
|
||||
* Construct a new StringPropertyMap
|
||||
* @param name name of property
|
||||
*/
|
||||
public DefaultStringPropertyMap(String name) {
|
||||
super(new StringPropertySet(name));
|
||||
propSet = (StringPropertySet)propertyMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a String value at the specified address.
|
||||
* @param addr address for the property
|
||||
* @param value value of the property
|
||||
* @exception TypeMismatchException thrown if the
|
||||
* property does not have String values.
|
||||
*/
|
||||
public void add(Address addr, String value) {
|
||||
propSet.putString(addrMap.getKey(addr), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the String value at the given address.
|
||||
* @param addr the address from where to get the String value
|
||||
*/
|
||||
public String getString(Address addr) {
|
||||
return propSet.getString(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
return getString(addr);
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.prop.VoidPropertySet;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* "void" type, which is a marker for whether a property exists.
|
||||
*/
|
||||
public class DefaultVoidPropertyMap extends DefaultPropertyMap implements VoidPropertyMap {
|
||||
|
||||
private VoidPropertySet propSet;
|
||||
|
||||
/**
|
||||
* Construct a new VoidPropertyMap
|
||||
* @param name of property
|
||||
*/
|
||||
public DefaultVoidPropertyMap(String name) {
|
||||
super(new VoidPropertySet(name));
|
||||
propSet = (VoidPropertySet)propertyMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the specified address as having a property
|
||||
* @param addr address for the property
|
||||
*/
|
||||
public void add(Address addr) {
|
||||
propSet.put(addrMap.getKey(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.util.PropertyMap#getObject(ghidra.program.model.address.Address)
|
||||
*/
|
||||
public Object getObject(Address addr) {
|
||||
if (hasProperty(addr)) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,7 +22,12 @@ import ghidra.util.exception.NoValueException;
|
|||
* Property manager that deals with properties that are of
|
||||
* int type.
|
||||
*/
|
||||
public interface IntPropertyMap extends PropertyMap {
|
||||
public interface IntPropertyMap extends PropertyMap<Integer> {
|
||||
|
||||
@Override
|
||||
public default Class<Integer> getValueClass() {
|
||||
return Integer.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an int value at the specified address.
|
||||
|
@ -35,7 +39,20 @@ public interface IntPropertyMap extends PropertyMap {
|
|||
/**
|
||||
* Get the integer value at the given address.
|
||||
* @param addr the address from where to get the int value
|
||||
* @return integer property value
|
||||
* @throws NoValueException if there is no property value at addr.
|
||||
*/
|
||||
public int getInt(Address addr) throws NoValueException;
|
||||
|
||||
@Override
|
||||
public default void add(Address addr, Object value) {
|
||||
if (value == null) {
|
||||
remove(addr);
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof Integer)) {
|
||||
throw new IllegalArgumentException("Integer value required");
|
||||
}
|
||||
add(addr, (int) value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,7 +22,12 @@ import ghidra.util.exception.NoValueException;
|
|||
* Property manager that deals with properties that are of
|
||||
* long type.
|
||||
*/
|
||||
public interface LongPropertyMap extends PropertyMap {
|
||||
public interface LongPropertyMap extends PropertyMap<Long> {
|
||||
|
||||
@Override
|
||||
public default Class<Long> getValueClass() {
|
||||
return Long.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a long value at the specified address.
|
||||
|
@ -35,8 +39,20 @@ public interface LongPropertyMap extends PropertyMap {
|
|||
/**
|
||||
* Get the long value at the given address.
|
||||
* @param addr the address from where to get the long value
|
||||
* @return long property value
|
||||
* @throws NoValueException if there is no property value at addr.
|
||||
*/
|
||||
public long getLong(Address addr) throws NoValueException;
|
||||
|
||||
@Override
|
||||
public default void add(Address addr, Object value) {
|
||||
if (value == null) {
|
||||
remove(addr);
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof Long)) {
|
||||
throw new IllegalArgumentException("Long value required");
|
||||
}
|
||||
add(addr, (long) value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,18 +21,29 @@ import ghidra.util.Saveable;
|
|||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* Object type.
|
||||
* @param <T> {@link Saveable} implementation type
|
||||
*/
|
||||
public interface ObjectPropertyMap extends PropertyMap {
|
||||
public interface ObjectPropertyMap<T extends Saveable> extends PropertyMap<T> {
|
||||
|
||||
/**
|
||||
* Add an object value at the specified address.
|
||||
* @param addr address for the property
|
||||
* @param value value of the property
|
||||
* @throws IllegalArgumentException if value is type is inconsistent with map
|
||||
*/
|
||||
public void add(Address addr, Saveable value);
|
||||
|
||||
/**
|
||||
* Returns Saveable object class.
|
||||
*/
|
||||
public Class<?> getObjectClass();
|
||||
public void add(Address addr, T value) throws IllegalArgumentException;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public default void add(Address addr, Object value) {
|
||||
if (value == null) {
|
||||
remove(addr);
|
||||
return;
|
||||
}
|
||||
Class<? extends Saveable> saveableObjectClass = getValueClass();
|
||||
if (!saveableObjectClass.isAssignableFrom(value.getClass())) {
|
||||
throw new IllegalArgumentException("value is not " + saveableObjectClass.getName());
|
||||
}
|
||||
((ObjectPropertyMap<Saveable>) this).add(addr, (Saveable) value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,24 @@
|
|||
package ghidra.program.model.util;
|
||||
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.util.datastruct.NoSuchIndexException;
|
||||
import ghidra.util.prop.PropertyVisitor;
|
||||
|
||||
/**
|
||||
* Interface to define a map containing properties over a set of addresses.
|
||||
* @param <T> property value type
|
||||
*/
|
||||
public interface PropertyMap {
|
||||
public interface PropertyMap<T> {
|
||||
/**
|
||||
* Get the name for this property map.
|
||||
* @return map name
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Returns property value class.
|
||||
* @return property value class or null for an unsupported map type
|
||||
*/
|
||||
public Class<T> getValueClass();
|
||||
|
||||
/**
|
||||
* Given two addresses, indicate whether there is an address in
|
||||
* that range (inclusive) having the property.<p>
|
||||
|
@ -63,11 +70,21 @@ public interface PropertyMap {
|
|||
* @param addr the address where the property should be removed
|
||||
*/
|
||||
public boolean remove(Address addr);
|
||||
|
||||
/**
|
||||
* returns whether there is a property value at addr.
|
||||
* @param addr the address in question
|
||||
* @return true if map has value at specified address
|
||||
*/
|
||||
public boolean hasProperty(Address addr);
|
||||
|
||||
/**
|
||||
* Add a map-specific value type to the specified address
|
||||
* @param addr property address
|
||||
* @param value property value or null (null remove value at address)
|
||||
* @throws IllegalArgumentException if property value type is inappropriate for this map
|
||||
*/
|
||||
public void add(Address addr, Object value);
|
||||
|
||||
/**
|
||||
* Returns the property value stored at the specified
|
||||
|
@ -75,57 +92,61 @@ public interface PropertyMap {
|
|||
* @param addr property address
|
||||
* @return property value
|
||||
*/
|
||||
public Object getObject(Address addr);
|
||||
public T get(Address addr);
|
||||
|
||||
/**
|
||||
* Get the next address where the property value exists.
|
||||
* @param addr the address from which to begin the search (exclusive).
|
||||
* @return property value location after specified {@code addr} or null if none found
|
||||
*/
|
||||
public Address getNextPropertyAddress(Address addr);
|
||||
|
||||
/**
|
||||
* Get the previous Address where a property value exists.
|
||||
* @param addr the address from which
|
||||
* to begin the search (exclusive).
|
||||
* @param addr the address from which to begin the search (exclusive).
|
||||
* @return property value location after specified {@code addr} or null if none found
|
||||
*/
|
||||
public Address getPreviousPropertyAddress(Address addr);
|
||||
|
||||
/**
|
||||
* Get the first Address where a property value exists.
|
||||
* @return first property value location or null if none found
|
||||
*/
|
||||
public Address getFirstPropertyAddress();
|
||||
|
||||
/**
|
||||
* Get the last Address where a property value exists.
|
||||
* @return last property value location or null if none found
|
||||
*/
|
||||
public Address getLastPropertyAddress();
|
||||
|
||||
/**
|
||||
* Get the number of properties in the map.
|
||||
* @return number of stored property values
|
||||
*/
|
||||
public int getSize();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the indices having a property
|
||||
* value.
|
||||
* @exception TypeMismatchException thrown if the property does not
|
||||
* have values of type <CODE>Object</CODE>.
|
||||
* Returns an iterator over the indices having a property value.
|
||||
* @param start minimum address
|
||||
* @param end maximum address
|
||||
* @return forward property address iterator
|
||||
*/
|
||||
public AddressIterator getPropertyIterator(
|
||||
Address start,
|
||||
Address end);
|
||||
public AddressIterator getPropertyIterator(Address start, Address end);
|
||||
|
||||
/**
|
||||
* Returns an iterator over addresses that have a property
|
||||
* value.
|
||||
* Returns an iterator over addresses that have a property value.
|
||||
* @param start minimum address
|
||||
* @param end maximum address
|
||||
* @param forward if true will iterate in increasing address order, otherwise it will start at
|
||||
* the end and iterate in decreasing address order
|
||||
* @exception TypeMismatchException thrown if the property does not
|
||||
* have values of type <CODE>Object</CODE>.
|
||||
* @return property address iterator
|
||||
*/
|
||||
public AddressIterator getPropertyIterator(
|
||||
Address start,
|
||||
Address end,
|
||||
boolean forward);
|
||||
public AddressIterator getPropertyIterator(Address start, Address end, boolean forward);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the addresses that a property
|
||||
* value.
|
||||
* @exception TypeMismatchException thrown if the property does not
|
||||
* have values of type <CODE>Object</CODE>.
|
||||
* Returns an iterator over the addresses that a property value.
|
||||
* @return forward property address iterator
|
||||
*/
|
||||
public AddressIterator getPropertyIterator();
|
||||
|
||||
|
@ -133,37 +154,29 @@ public interface PropertyMap {
|
|||
* Returns an iterator over the addresses that have a property value and
|
||||
* are in the given address set.
|
||||
* @param asv the set of addresses to iterate over.
|
||||
* @return forward property address iterator
|
||||
*/
|
||||
public AddressIterator getPropertyIterator(AddressSetView asv);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the addresses that have a property value and
|
||||
* are in the given address set.
|
||||
* @param asv the set of addresses to iterate over.
|
||||
* @param forward if true will iterate in increasing address order, otherwise it will start at
|
||||
* the end and iterate in decreasing address order
|
||||
* @return property address iterator
|
||||
*/
|
||||
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward);
|
||||
|
||||
/**
|
||||
* Returns an iterator over the address having a property
|
||||
* value.
|
||||
* Returns an iterator over the address having a property value.
|
||||
* @param start the starting address
|
||||
* @param forward if true will iterate in increasing address order, otherwise it will start at
|
||||
* the end and iterate in decreasing address order
|
||||
* @exception TypeMismatchException thrown if the property does not
|
||||
* have values of type <CODE>Object</CODE>.
|
||||
* @return property address iterator
|
||||
*/
|
||||
public AddressIterator getPropertyIterator(Address start, boolean forward);
|
||||
|
||||
/**
|
||||
* Applies a property value at the indicated address without knowing its
|
||||
* type (String, int, long, etc.) by using the property visitor.
|
||||
* @param visitor the property visitor that lets you apply the property
|
||||
* without knowing its specific type ahead of time.
|
||||
* @param addr the address where the property is to be applied.
|
||||
*/
|
||||
public void applyValue(PropertyVisitor visitor, Address addr);
|
||||
|
||||
/**
|
||||
* Moves the properties defined in the range from the start address thru the
|
||||
* end address to now be located beginning at the newStart address.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,14 +15,15 @@
|
|||
*/
|
||||
package ghidra.program.model.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface for managing a set of PropertyManagers.
|
||||
|
@ -33,6 +33,7 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Creates a new IntPropertyMap with the given name.
|
||||
* @param propertyName the name for the new property.
|
||||
* @return newly created integer object map
|
||||
* @exception DuplicateNameException thrown if a PropertyMap already
|
||||
* exists with that name.
|
||||
*/
|
||||
|
@ -41,6 +42,7 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Creates a new LongPropertyMap with the given name.
|
||||
* @param propertyName the name for the new property.
|
||||
* @return newly created long object map
|
||||
* @exception DuplicateNameException thrown if a PropertyMap already
|
||||
* exists with that name.
|
||||
*/
|
||||
|
@ -49,6 +51,7 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Creates a new StringPropertyMap with the given name.
|
||||
* @param propertyName the name for the new property.
|
||||
* @return newly created string object map
|
||||
* @exception DuplicateNameException thrown if a PropertyMap already
|
||||
* exists with that name.
|
||||
*/
|
||||
|
@ -57,16 +60,20 @@ public interface PropertyMapManager {
|
|||
|
||||
/**
|
||||
* Creates a new ObjectPropertyMap with the given name.
|
||||
* @param <T> {@link Saveable} property value type
|
||||
* @param propertyName the name for the new property.
|
||||
* @param objectClass {@link Saveable} implementation class
|
||||
* @return newly created {@link Saveable} object map
|
||||
* @exception DuplicateNameException thrown if a PropertyMap already
|
||||
* exists with that name.
|
||||
*/
|
||||
public ObjectPropertyMap createObjectPropertyMap(String propertyName,
|
||||
Class<? extends Saveable> objectClass) throws DuplicateNameException;
|
||||
public <T extends Saveable> ObjectPropertyMap<T> createObjectPropertyMap(String propertyName,
|
||||
Class<T> objectClass) throws DuplicateNameException;
|
||||
|
||||
/**
|
||||
* Creates a new VoidPropertyMap with the given name.
|
||||
* @param propertyName the name for the new property.
|
||||
* @return newly created void map
|
||||
* @exception DuplicateNameException thrown if a PropertyMap already
|
||||
* exists with that name.
|
||||
*/
|
||||
|
@ -75,13 +82,15 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Returns the PropertyMap with the given name or null if no PropertyMap
|
||||
* exists with that name.
|
||||
* @return existing map or null if not found
|
||||
* @param propertyName the name of the property to retrieve.
|
||||
*/
|
||||
public PropertyMap getPropertyMap(String propertyName);
|
||||
public PropertyMap<?> getPropertyMap(String propertyName);
|
||||
|
||||
/**
|
||||
* Returns the IntPropertyMap associated with the given name.
|
||||
* @param propertyName the name of the property to retrieve.
|
||||
* @return existing map or null if not found
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an IntPropertyMap.
|
||||
*/
|
||||
|
@ -90,6 +99,7 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Returns the LongPropertyMap associated with the given name.
|
||||
* @param propertyName the name of the property to retrieve.
|
||||
* @return existing map or null if not found
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an LongPropertyMap.
|
||||
*/
|
||||
|
@ -98,6 +108,7 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Returns the StringPropertyMap associated with the given name.
|
||||
* @param propertyName the name of the property to retrieve.
|
||||
* @return existing map or null if not found
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not a StringPropertyMap.
|
||||
*/
|
||||
|
@ -106,14 +117,16 @@ public interface PropertyMapManager {
|
|||
/**
|
||||
* Returns the ObjectPropertyMap associated with the given name.
|
||||
* @param propertyName the name of the property to retrieve.
|
||||
* @return existing map or null if not found
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an ObjectPropertyMap.
|
||||
*/
|
||||
public ObjectPropertyMap getObjectPropertyMap(String propertyName);
|
||||
public ObjectPropertyMap<? extends Saveable> getObjectPropertyMap(String propertyName);
|
||||
|
||||
/**
|
||||
* Returns the VoidPropertyMap associated with the given name.
|
||||
* @param propertyName the name of the property to retrieve.
|
||||
* @return existing map or null if not found
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not a VoidPropertyMap.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.util.Saveable;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
public interface PropertySet {
|
||||
|
||||
/**
|
||||
* Set the named property with the given {@link Saveable} value.
|
||||
* @param name the name of the property.
|
||||
* @param value value to be stored.
|
||||
* @param <T> {@link Saveable} implementation
|
||||
* @throws IllegalArgumentException if value type is inconsistent with named map
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an ObjectPropertyMap.
|
||||
*/
|
||||
public <T extends Saveable> void setProperty(String name, T value)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Set the named string property with the given value.
|
||||
* @param name the name of the property.
|
||||
* @param value value to be stored.
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not a StringPropertyMap.
|
||||
*/
|
||||
public void setProperty(String name, String value);
|
||||
|
||||
/**
|
||||
* Set the named integer property with the given value.
|
||||
* @param name the name of the property.
|
||||
* @param value value to be stored.
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an IntPropertyMap.
|
||||
*/
|
||||
public void setProperty(String name, int value);
|
||||
|
||||
/**
|
||||
* Set the named property. This method is used for "void" properites. The
|
||||
* property is either set or not set - there is no value
|
||||
* @param name the name of the property.
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not a VoidPropertyMap.
|
||||
*/
|
||||
public void setProperty(String name);
|
||||
|
||||
/**
|
||||
* Get the object property for name; returns null if
|
||||
* there is no name property for this code unit.
|
||||
* @param name the name of the property
|
||||
* @return {@link Saveable} property value, with map-specific implementation class, or null.
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an ObjectPropertyMap.
|
||||
*/
|
||||
public Saveable getObjectProperty(String name);
|
||||
|
||||
/**
|
||||
* Get the string property for name; returns null if
|
||||
* there is no name property for this code unit.
|
||||
* @param name the name of the property
|
||||
* @return string property value or null
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an StringPropertyMap.
|
||||
*/
|
||||
public String getStringProperty(String name);
|
||||
|
||||
/**
|
||||
* Get the int property for name.
|
||||
* @param name the name of the property
|
||||
* @return integer property value property has been set
|
||||
* @throws NoValueException if there is not name property
|
||||
* for this code unit
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an IntPropertyMap.
|
||||
*/
|
||||
public int getIntProperty(String name) throws NoValueException;
|
||||
|
||||
/**
|
||||
* Returns true if the codeunit has the given property defined.
|
||||
* This method works for all property map types.
|
||||
* @param name the name of the property
|
||||
* @return true if property has been set, else false
|
||||
*/
|
||||
public boolean hasProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns whether this code unit is marked as having the
|
||||
* name property.
|
||||
* @param name the name of the property
|
||||
* @return true if property has been set, else false
|
||||
* @throws TypeMismatchException if a propertyMap named propertyName
|
||||
* exists but is not an VoidPropertyMap.
|
||||
*/
|
||||
boolean getVoidProperty(String name);
|
||||
|
||||
/**
|
||||
* Get an iterator over the property names which have values applied.
|
||||
* @return iterator of all property map names which have values applied
|
||||
*/
|
||||
public Iterator<String> propertyNames();
|
||||
|
||||
/**
|
||||
* Remove the property value associated with the given name .
|
||||
* @param name the name of the property
|
||||
*/
|
||||
public void removeProperty(String name);
|
||||
}
|
|
@ -21,7 +21,7 @@ import ghidra.program.model.address.Address;
|
|||
/**
|
||||
* Property map interface for storing Settings objects.
|
||||
*/
|
||||
public interface SettingsPropertyMap extends PropertyMap {
|
||||
public interface SettingsPropertyMap extends PropertyMap<Settings> {
|
||||
/**
|
||||
* Add an Settings object value at the specified address.
|
||||
* @param addr address for the property
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,13 +16,19 @@
|
|||
package ghidra.program.model.util;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* String type.
|
||||
*/
|
||||
public interface StringPropertyMap extends PropertyMap {
|
||||
public interface StringPropertyMap extends PropertyMap<String> {
|
||||
|
||||
@Override
|
||||
public default Class<String> getValueClass() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a String value at the specified address.
|
||||
* @param addr address for the property
|
||||
|
@ -40,4 +45,16 @@ public interface StringPropertyMap extends PropertyMap {
|
|||
*/
|
||||
public String getString(Address addr);
|
||||
|
||||
@Override
|
||||
public default void add(Address addr, Object value) {
|
||||
if (value == null) {
|
||||
remove(addr);
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof String)) {
|
||||
throw new IllegalArgumentException("String value required");
|
||||
}
|
||||
add(addr, (String) value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -21,13 +20,43 @@ import ghidra.program.model.address.Address;
|
|||
/**
|
||||
* Property manager that deals with properties that are of
|
||||
* "void" type, which is a marker for whether a property exists.
|
||||
* Object values returned are either {@link Boolean#TRUE} or null.
|
||||
*/
|
||||
public interface VoidPropertyMap extends PropertyMap {
|
||||
public interface VoidPropertyMap extends PropertyMap<Boolean> {
|
||||
|
||||
@Override
|
||||
public default Class<Boolean> getValueClass() {
|
||||
return Boolean.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the specified address as having a property
|
||||
* @param addr address for the property
|
||||
*/
|
||||
public void add(Address addr);
|
||||
|
||||
/**
|
||||
* Apply property value to specified address.
|
||||
* @param addr property address
|
||||
* @param value boolean value (null or false will remove property value)
|
||||
* @throws IllegalArgumentException if value specified is not a Boolean or null
|
||||
*/
|
||||
@Override
|
||||
public default void add(Address addr, Object value) {
|
||||
if (value == null) {
|
||||
remove(addr);
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof Boolean)) {
|
||||
throw new IllegalArgumentException("Boolean value required");
|
||||
}
|
||||
Boolean b = (Boolean) value;
|
||||
if (!b) {
|
||||
remove(addr);
|
||||
}
|
||||
else {
|
||||
add(addr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue