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:
ghidra1 2022-09-15 19:10:18 -04:00
parent 45165ea167
commit c5c651a053
91 changed files with 1909 additions and 5056 deletions

View file

@ -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);

View file

@ -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()) {

View file

@ -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);
}

View file

@ -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;
/**

View file

@ -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}

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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()
*/

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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
}
}

View file

@ -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;
}
}

View file

@ -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());

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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();

View file

@ -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;
}

View file

@ -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|

View file

@ -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();

View file

@ -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);

View file

@ -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()) {

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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) {
}
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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.
*/

View file

@ -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();
}

View file

@ -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>

View file

@ -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) {
// }
}
}

View file

@ -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) {
// }
}
}

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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) {
// }
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}
}

View file

@ -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 {

View file

@ -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()
}

View file

@ -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));
}
}

View file

@ -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;
}
}

View file

@ -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()
}

View file

@ -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();
}
}

View file

@ -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()
}

View file

@ -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));
}
}

View file

@ -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.
*

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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();

View file

@ -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 {

View file

@ -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) {

View file

@ -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) {
}
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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));
}

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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];

View file

@ -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.
*/

View file

@ -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();

View file

@ -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();

View file

@ -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.

View file

@ -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;

View file

@ -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;
}
}
}

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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.

View file

@ -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.
*/

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}
}