diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/data/DataManagerTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/data/DataManagerTest.java index e8066598b3..edae0146d6 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/data/DataManagerTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/data/DataManagerTest.java @@ -26,30 +26,14 @@ import ghidra.program.database.ProgramBuilder; import ghidra.program.database.ProgramDB; import ghidra.program.model.data.*; import ghidra.test.AbstractGhidraHeadedIntegrationTest; +import ghidra.util.InvalidNameException; import ghidra.util.task.TaskMonitorAdapter; -/** - * - * Tests for the DataManager. - * - * - */ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { private ProgramDB program; private DataTypeManagerDB dataMgr; private int transactionID; - /** - * Constructor for DataManagerTest. - * @param arg0 - */ - public DataManagerTest() { - super(); - } - - /* - * @see TestCase#setUp() - */ @Before public void setUp() throws Exception { program = createDefaultProgram(testName.getMethodName(), ProgramBuilder._TOY, this); @@ -57,9 +41,6 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { startTransaction(); } - /* - * @see TestCase#tearDown() - */ @After public void tearDown() throws Exception { endTransaction(); @@ -67,14 +48,23 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testGetUniqueName() throws Exception { + public void testSetName() throws InvalidNameException { + String oldName = dataMgr.getName(); + String newName = "NewName"; + dataMgr.setName("NewName"); + + assertEquals(newName, dataMgr.getName()); + } + + @Test + public void testGetUniqueName() throws Exception { DataType bt = new EnumDataType("test", 2); dataMgr.resolve(bt, null); assertEquals("test_1", dataMgr.getUniqueName(CategoryPath.ROOT, "test")); } @Test - public void testGetDataTypeByID() throws Exception { + public void testGetDataTypeByID() throws Exception { Category root = dataMgr.getRootCategory(); Category sub1 = root.createCategory("SubCat-A"); @@ -95,7 +85,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testFindDataTypes() throws Exception { + public void testFindDataTypes() throws Exception { Category root = dataMgr.getRootCategory(); Category sub1 = root.createCategory("SubCat-A"); @@ -147,7 +137,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testFindDataTypesWildcard() throws Exception { + public void testFindDataTypesWildcard() throws Exception { Category root = dataMgr.getRootCategory(); Category sub1 = root.createCategory("SubCat-A"); @@ -180,7 +170,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testFindDataType() throws Exception { + public void testFindDataType() throws Exception { Category root = dataMgr.getRootCategory(); Category subc = root.createCategory("subc"); subc.createCategory("subc2"); @@ -193,7 +183,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreateCategoryHierarchy() throws Exception { + public void testCreateCategoryHierarchy() throws Exception { String fullName = "/cat1/cat2/cat3/cat4/cat5"; CategoryPath cp = new CategoryPath(fullName); dataMgr.createCategory(cp); @@ -211,7 +201,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreateArray() throws Exception { + public void testCreateArray() throws Exception { ArrayDataType adt = new ArrayDataType(new ByteDataType(), 3, 1); Array array = (Array) dataMgr.addDataType(adt, null); assertNotNull(array); @@ -222,7 +212,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreateTypedef() throws Exception { + public void testCreateTypedef() throws Exception { ArrayDataType adt = new ArrayDataType(new ByteDataType(), 3, 1); Array array = (Array) dataMgr.addDataType(adt, null); TypedefDataType tdt = new TypedefDataType("ArrayTypedef", array); @@ -232,7 +222,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreatePointer() throws Exception { + public void testCreatePointer() throws Exception { ArrayDataType adt = new ArrayDataType(new ByteDataType(), 5, 1); Array array = (Array) dataMgr.addDataType(adt, null); @@ -249,7 +239,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreatePointers() throws Exception { + public void testCreatePointers() throws Exception { Array array = new ArrayDataType(new ByteDataType(), 5, 1); TypeDef td = new TypedefDataType("ByteTypedef", array); @@ -269,7 +259,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testRemoveDataType() throws Exception { + public void testRemoveDataType() throws Exception { Array array = new ArrayDataType(new ByteDataType(), 5, 1); TypeDef td = new TypedefDataType("ByteTypedef", array); Pointer p = new Pointer32DataType(td); @@ -292,7 +282,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testRemoveDataType2() throws Exception { + public void testRemoveDataType2() throws Exception { Array array = new ArrayDataType(new ByteDataType(), 5, 1); TypeDef td = new TypedefDataType("ByteTypedef", array); Pointer p = new Pointer32DataType(td); @@ -322,7 +312,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { // } @Test - public void testCreateStructure() { + public void testCreateStructure() { StructureDataType sdt = new StructureDataType("test", 0); Structure struct = (Structure) dataMgr.addDataType(sdt, null); assertNotNull(struct); @@ -333,7 +323,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreateUnion() { + public void testCreateUnion() { UnionDataType udt = new UnionDataType("test"); Union union = (Union) dataMgr.addDataType(udt, null); assertNotNull(union); @@ -342,7 +332,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testCreateFunctionDef() { + public void testCreateFunctionDef() { FunctionDefinitionDataType fdt = new FunctionDefinitionDataType(new FunctionDefinitionDataType("test")); FunctionDefinition funcDef = (FunctionDefinition) dataMgr.addDataType(fdt, null); @@ -366,7 +356,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testDataTypeSizeChanged() { + public void testDataTypeSizeChanged() { Structure dt = new StructureDataType("MyStruct", 100); dt.insert(0, new ByteDataType()); @@ -391,7 +381,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testResolveDataType() { + public void testResolveDataType() { DataTypeManager dtm = new StandAloneDataTypeManager("Test"); int id = dtm.startTransaction(""); @@ -409,7 +399,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testResolveDataType2() throws Exception { + public void testResolveDataType2() throws Exception { DataTypeManager dtm = new StandAloneDataTypeManager("Test"); int id = dtm.startTransaction(""); Category otherRoot = dataMgr.getRootCategory(); @@ -424,7 +414,7 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { } @Test - public void testResolveDataType3() throws Exception { + public void testResolveDataType3() throws Exception { DataTypeManager dtm = new StandAloneDataTypeManager("Test"); int id = dtm.startTransaction(""); Category otherRoot = dataMgr.getRootCategory(); @@ -443,9 +433,8 @@ public class DataManagerTest extends AbstractGhidraHeadedIntegrationTest { dtm.close(); } - @Test - public void testDoubleReplace() throws Exception { + public void testDoubleReplace() throws Exception { Structure struct = new StructureDataType("test", 0); struct.add(new ByteDataType()); struct.add(new WordDataType()); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ProgramDataTypeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ProgramDataTypeManager.java index a1688d12c9..0c43501955 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ProgramDataTypeManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/ProgramDataTypeManager.java @@ -40,8 +40,8 @@ import ghidra.util.task.TaskMonitor; /** * Class for managing data types in a program */ -public class ProgramDataTypeManager extends DataTypeManagerDB implements ManagerDB, - ProgramBasedDataTypeManager { +public class ProgramDataTypeManager extends DataTypeManagerDB + implements ManagerDB, ProgramBasedDataTypeManager { private static final String OLD_DT_ARCHIVE_FILENAMES = "DataTypeArchiveFilenames"; // eliminated with Ghidra 4.3 @@ -61,15 +61,12 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager * @throws IOException if a database io error occurs. */ public ProgramDataTypeManager(DBHandle handle, AddressMap addrMap, int openMode, - ErrorHandler errHandler, Lock lock, TaskMonitor monitor) throws CancelledException, - VersionException, IOException { + ErrorHandler errHandler, Lock lock, TaskMonitor monitor) + throws CancelledException, VersionException, IOException { super(handle, addrMap, openMode, errHandler, lock, monitor); upgrade = (openMode == DBConstants.UPGRADE); } - /** - * @see ghidra.program.database.ManagerDB#setProgram(ghidra.program.database.ProgramDB) - */ @Override public void setProgram(ProgramDB p) { this.program = p; @@ -85,17 +82,11 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager } } - /** - * @see ghidra.program.database.ManagerDB#invalidateCache(boolean) - */ @Override public void invalidateCache(boolean all) throws IOException { super.invalidateCache(); } - /** - * @see ghidra.program.database.ManagerDB#programReady(int, int, ghidra.util.task.TaskMonitor) - */ @Override public void programReady(int openMode, int currentRevision, TaskMonitor monitor) throws IOException, CancelledException { @@ -104,9 +95,6 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager } } - /** - * @see ghidra.program.model.data.DataTypeManager#getName() - */ @Override public String getName() { return program.getName(); @@ -117,9 +105,6 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager return PointerDataType.getPointer(dt, this); } - /** - * @see ghidra.program.model.data.DataTypeManager#setName(java.lang.String) - */ @Override public void setName(String name) throws InvalidNameException { if (name == null || name.length() == 0) { @@ -127,10 +112,10 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager } program.setName(name); - categoryRenamed(CategoryPath.ROOT, null); + Category root = getRootCategory(); + categoryRenamed(CategoryPath.ROOT, root); } - //////////////////// @Override public void sourceArchiveChanged(UniversalID sourceArchiveID) { super.sourceArchiveChanged(sourceArchiveID); @@ -219,7 +204,6 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager super.favoritesChanged(dataType, isFavorite); } - /////////////////// @Override protected void replaceDataTypeIDs(long oldDataTypeID, long newDataTypeID) { if (oldDataTypeID == newDataTypeID) { @@ -249,9 +233,6 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager return program.isChangeable(); } - /** - * @see ghidra.program.model.data.DataTypeManager#startTransaction(java.lang.String) - */ @Override public int startTransaction(String description) { return program.startTransaction(description); @@ -262,34 +243,22 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager program.flushEvents(); } - /** - * @see ghidra.program.model.data.DataTypeManager#endTransaction(int, boolean) - */ @Override public void endTransaction(int transactionID, boolean commit) { program.endTransaction(transactionID, commit); } - /** - * @see ghidra.program.model.data.DataTypeManager#close() - */ @Override public void close() { // do nothing - cannot close the program's data type manager } - /* (non-Javadoc) - * @see ghidra.program.model.data.ProgramDataTypeManager#getProgram() - */ @Override public Program getProgram() { return program; } - /* (non-Javadoc) - * @see ghidra.program.model.data.DomainFileBasedDataTypeManager#getDomainFile() - */ @Override public DomainFile getDomainFile() { return program.getDomainFile(); @@ -319,5 +288,4 @@ public class ProgramDataTypeManager extends DataTypeManagerDB implements Manager } return dataOrganization; } - } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java index 5b969a5d25..86e72c729a 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java @@ -53,22 +53,25 @@ public interface DataTypeManager { public final UniversalID BUILT_IN_ARCHIVE_UNIVERSAL_ID = new UniversalID(BUILT_IN_ARCHIVE_KEY); /** - * Returns the universal ID for this dataType manager. + * Returns the universal ID for this dataType manager + * @return the universal ID for this dataType manager */ public UniversalID getUniversalID(); /** - * Returns true if the given category path exists in this datatype manager. - * @param path - * @return + * Returns true if the given category path exists in this datatype manager + * @param path the path + * @return true if the given category path exists in this datatype manager */ public boolean containsCategory(CategoryPath path); /** * Returns a unique name not currently used by any other dataType or category - * with the same baseName. - * @param baseName the base name to be made unique. - * @return a unique name starting with baseName. + * with the same baseName + * + * @param path the path of the name + * @param baseName the base name to be made unique + * @return a unique name starting with baseName */ public String getUniqueName(CategoryPath path, String baseName); @@ -96,22 +99,26 @@ public interface DataTypeManager { /** * Returns an iterator over all the dataTypes in this manager + * @return an iterator over all the dataTypes in this manager */ public Iterator getAllDataTypes(); /** - * Adds all data types to the specified list. - * @param list + * Adds all data types to the specified list.] + * + * @param list the result list into which the types will be placed */ public void getAllDataTypes(List list); /** - * Returns an iterator over all structures in this manager. + * Returns an iterator over all structures in this manager + * @return the iterator */ public Iterator getAllStructures(); /** - * Returns an iterator over all composite data types (structures and unions) in this manager. + * Returns an iterator over all composite data types (structures and unions) in this manager + * @return the iterator */ public Iterator getAllComposites(); @@ -159,8 +166,9 @@ public interface DataTypeManager { * there is also a category "b" under category "a". A better solution is to use * the {@link #getDataType(DataTypePath)} method because the DataTypePath keeps the * category and datatype name separate. - * @param dataType path; - * @return the dataType or null if it isn't found. + * + * @param dataTypePath path + * @return the dataType or null if it isn't found */ public DataType getDataType(String dataTypePath); @@ -182,31 +190,44 @@ public interface DataTypeManager { /** * Returns the dataTypeId for the given dataType. If the dataType is not - * currently in the dataTypeManger, it will be added. + * currently in the dataTypeManger, it will be added + * + * @param dt the data type + * @return the ID of the resolved type */ public long getResolvedID(DataType dt); /** * Returns the dataTypeId for the given dataType. If the dataType does not exist, * a -1 will be returned - * @param dt the datatype to get an id for. + * + * @param dt the datatype to get an id for + * @return the ID of the type */ public long getID(DataType dt); /** - * Returns the dataType associated with the given dataTypeId or null if the - * dataTypeId is not valid. + * Returns the dataType associated with the given dataTypeId or null if the dataTypeId is + * not valid + * + * @param dataTypeID the ID + * @return the type */ public DataType getDataType(long dataTypeID); /** - * Returns the Category with the given id. - * @param categoryID id of the desired category. + * Returns the Category with the given id + * + * @param categoryID id of the desired category + * @return the category */ public Category getCategory(long categoryID); /** - * Get the category that has the given path. + * Get the category that has the given path + * + * @param path the path + * @return the category */ public Category getCategory(CategoryPath path); @@ -244,18 +265,25 @@ public interface DataTypeManager { /** * Remove the given datatype from this manager - * @param dataType the dataType to be removed. + * @param dataType the dataType to be removed * @param monitor the task monitor + * @return true if the data type existed and was removed */ public boolean remove(DataType dataType, TaskMonitor monitor); /** - * Return true if the given dataType exists in this data type manager. + * Return true if the given dataType exists in this data type manager + * + * @param dataType the type + * @return true if the type is in this manager */ public boolean contains(DataType dataType); /** - * @param path + * Create a category for the given path; returns the current category if it already exits + * + * @param path the path + * @return the category */ public Category createCategory(CategoryPath path); @@ -268,19 +296,22 @@ public interface DataTypeManager { public DataType getDataType(CategoryPath path, String name); /** - * Returns this data type manager's name. + * Returns this data type manager's name + * @return the name */ public String getName(); /** - * Sets this data type manager's name. + * Sets this data type manager's name * @param name the new name + * @throws InvalidNameException if the given name is invalid (such as when null or empty) */ public void setName(String name) throws InvalidNameException; /** * Starts a transaction for making changes in this data type manager. * @param description a short description of the changes to be made. + * @return the transaction ID */ public int startTransaction(String description); @@ -293,22 +324,27 @@ public interface DataTypeManager { /** * Ends the current transaction * @param transactionID id of the transaction to end - * @param commit if true the changes are commited, otherwise all changes in transaction are revoked. + * @param commit true if changes are committed, false if changes in transaction are revoked */ public void endTransaction(int transactionID, boolean commit); + /** + * Force all pending notification events to be flushed + * @throws IllegalStateException if the client is holding this object's lock + */ public void flushEvents(); /** - * Closes this dataType manager. - * + * Closes this dataType manager */ public void close(); /** * Returns a default sized pointer to the given datatype. The pointer size is established * dynamically based upon the data organization established by the compiler specification. - * @param datatype the pointed to data type. + * + * @param datatype the pointed to data type + * @return the pointer */ public Pointer getPointer(DataType datatype); @@ -316,13 +352,16 @@ public interface DataTypeManager { * Returns a pointer of the given size to the given datatype. * Note: It is preferred to use default sized pointers when possible (i.e., size=-1, * see {@link #getPointer(DataType)}) instead of explicitly specifying the size value. - * @param datatype the pointed to data type. - * @param size the size of the pointer to be created or -1 for a default sized pointer. + * + * @param datatype the pointed to data type + * @param size the size of the pointer to be created or -1 for a default sized pointer + * @return the pointer */ public Pointer getPointer(DataType datatype, int size); /** * Returns the root category Manager + * @return the category */ public Category getRootCategory(); @@ -350,13 +389,14 @@ public interface DataTypeManager { /** * Returns the total number of data type categories + * @return the count */ public int getCategoryCount(); /** * Returns the total number of defined data types. - * @param includePointersAndArrays if true all pointers and array - * data types will be included. + * @param includePointersAndArrays if true all pointers and array data types will be included + * @return the count */ public int getDataTypeCount(boolean includePointersAndArrays); @@ -376,16 +416,46 @@ public interface DataTypeManager { */ public DataType findDataTypeForID(UniversalID datatypeID); + /** + * Returns the timestamp of the last time this manager was changed + * @return the timestamp + */ public long getLastChangeTimeForMyManager(); + /** + * Returns the source archive for the given ID + * + * @param sourceID the ID + * @return the archive; null if the ID is null; null if the archive does not exist + */ public SourceArchive getSourceArchive(UniversalID sourceID); + /** + * Returns this manager's archive type + * @return the type + */ public ArchiveType getType(); + /** + * Returns all data types within this manager that have as their source the given archive + * + * @param sourceArchive the archive + * @return the types + */ public List getDataTypes(SourceArchive sourceArchive); + /** + * Returns the source archive for this manager + * @return the archive; null if the ID is null; null if the archive does not exist + */ public SourceArchive getLocalSourceArchive(); + /** + * Change the given data type so that its source archive is the given archive + * + * @param datatype the type + * @param archive the archive + */ public void associateDataTypeWithArchive(DataType datatype, SourceArchive archive); /** @@ -425,8 +495,19 @@ public interface DataTypeManager { */ public List getSourceArchives(); + /** + * Removes the source archive from this manager. This will disassociate all data types in + * this manager from the given archive. + * + * @param sourceArchive the archive + */ public void removeSourceArchive(SourceArchive sourceArchive); + /** + * Returns or creates a persisted version of the given source archive + * @param sourceArchive the archive + * @return the archive + */ public SourceArchive resolveSourceArchive(SourceArchive sourceArchive); /**