mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-1403 added suggested string setting support
This commit is contained in:
parent
3acd14c48a
commit
362bd6b5cb
11 changed files with 255 additions and 20 deletions
|
@ -26,8 +26,7 @@ import db.*;
|
|||
import db.util.ErrorHandler;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.plugin.core.datamgr.archive.BuiltInSourceArchive;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.docking.settings.SettingsDefinition;
|
||||
import ghidra.docking.settings.*;
|
||||
import ghidra.framework.store.db.PackedDBHandle;
|
||||
import ghidra.framework.store.db.PackedDatabase;
|
||||
import ghidra.graph.*;
|
||||
|
@ -121,6 +120,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
private SettingsCache<Long> settingsCache = new SettingsCache<>(200);
|
||||
private List<DataType> sortedDataTypes;
|
||||
private Map<Long, Set<String>> enumValueMap;
|
||||
private Map<String, Set<String>> suggestedSettingsValuesMap = new HashMap<>();
|
||||
|
||||
private List<InvalidatedListener> invalidatedListeners = new ArrayList<>();
|
||||
protected DataTypeManagerChangeListenerHandler defaultListener =
|
||||
|
@ -678,6 +678,13 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
if (rec != null) {
|
||||
SettingDB setting = new SettingDB(rec, settingsAdapter.getSettingName(rec));
|
||||
settingsCache.put(dataTypeId, name, setting);
|
||||
if (strValue != null) {
|
||||
Set<String> suggestions = suggestedSettingsValuesMap.get(name);
|
||||
if (suggestions != null) {
|
||||
// only cache suggestion if suggestions previously requested
|
||||
suggestions.add(strValue);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -691,6 +698,39 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
private Set<String> generateSuggestions(StringSettingsDefinition settingsDefinition) {
|
||||
Set<String> set = new TreeSet<>();
|
||||
try {
|
||||
settingsAdapter.addAllValues(settingsDefinition.getStorageKey(), set);
|
||||
settingsDefinition.addPreferredValues(this, set);
|
||||
}
|
||||
catch (IOException e) {
|
||||
errHandler.dbError(e);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get suggested setting values for a specified settingsDefinition
|
||||
* @param settingsDefinition string settings definition
|
||||
* @return suggested values or empty array if none
|
||||
*/
|
||||
String[] getSuggestedValues(StringSettingsDefinition settingsDefinition) {
|
||||
lock.acquire();
|
||||
try {
|
||||
Set<String> set = suggestedSettingsValuesMap
|
||||
.computeIfAbsent(settingsDefinition.getStorageKey(),
|
||||
n -> generateSuggestions(settingsDefinition));
|
||||
if (set.isEmpty()) {
|
||||
return Settings.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
return set.toArray(new String[set.size()]);
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if transaction is active. With proper lock established
|
||||
* this method may be useful for determining if a lazy record update
|
||||
|
@ -3200,7 +3240,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
fireInvalidated();
|
||||
updateFavorites();
|
||||
idsToDataTypeMap.clear();
|
||||
|
||||
suggestedSettingsValuesMap.clear();
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
|
|
|
@ -89,6 +89,11 @@ class DataTypeSettingsDB implements Settings {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSuggestedValues(StringSettingsDefinition settingsDefinition) {
|
||||
return dataMgr.getSuggestedValues(settingsDefinition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set predicate for settings modification
|
||||
* @param allowedSettingPredicate callback for checking an allowed setting modification
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.program.database.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import db.*;
|
||||
import ghidra.program.database.map.AddressMap;
|
||||
|
@ -289,6 +290,14 @@ abstract class SettingsDBAdapter {
|
|||
*/
|
||||
abstract String[] getSettingsNames(long associationId) throws IOException;
|
||||
|
||||
/**
|
||||
* Add all values stored for the specified setting name to the specified set.
|
||||
* @param name setting name
|
||||
* @param set value set
|
||||
* @throws IOException if there was a problem accessing the database
|
||||
*/
|
||||
abstract void addAllValues(String name, Set<String> set) throws IOException;
|
||||
|
||||
/**
|
||||
* Get the setting name which corresponds to the specified record.
|
||||
* @param record normalized settings record (name column is an integer index value)
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
package ghidra.program.database.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import db.*;
|
||||
import ghidra.util.ReadOnlyException;
|
||||
|
@ -110,6 +111,20 @@ class SettingsDBAdapterV0 extends SettingsDBAdapter {
|
|||
return list.toArray(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
void addAllValues(String name, Set<String> set) throws IOException {
|
||||
RecordIterator recIter = settingsTable.iterator();
|
||||
while (recIter.hasNext()) {
|
||||
DBRecord rec = recIter.next();
|
||||
if (name.equals(rec.getString(V0_SETTINGS_NAME_COL))) {
|
||||
String s = rec.getString(V0_SETTINGS_STRING_VALUE_COL);
|
||||
if (!StringUtils.isBlank(s)) {
|
||||
set.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSettingName(DBRecord normalizedRecord) {
|
||||
short nameIndex = normalizedRecord.getShortValue(SettingsDBAdapter.SETTINGS_NAME_INDEX_COL);
|
||||
|
|
|
@ -18,6 +18,8 @@ package ghidra.program.database.data;
|
|||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import db.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
@ -148,6 +150,24 @@ class SettingsDBAdapterV1 extends SettingsDBAdapter {
|
|||
return list.toArray(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
void addAllValues(String name, Set<String> set) throws IOException {
|
||||
short nameIndex = getNameIndex(name);
|
||||
if (nameIndex < MIN_NAME_INDEX) {
|
||||
return; // no such name defined
|
||||
}
|
||||
RecordIterator recIter = settingsTable.iterator();
|
||||
while (recIter.hasNext()) {
|
||||
DBRecord rec = recIter.next();
|
||||
if (nameIndex == rec.getShortValue(V1_SETTINGS_NAME_INDEX_COL)) {
|
||||
String s = rec.getString(V1_SETTINGS_STRING_VALUE_COL);
|
||||
if (!StringUtils.isBlank(s)) {
|
||||
set.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initNameMaps() throws IOException {
|
||||
if (nameIndexMap != null) {
|
||||
return;
|
||||
|
@ -250,6 +270,8 @@ class SettingsDBAdapterV1 extends SettingsDBAdapter {
|
|||
DBRecord updateSettingsRecord(long associationId, String name, String strValue, long longValue)
|
||||
throws IOException {
|
||||
|
||||
strValue = StringUtils.isBlank(strValue) ? null : strValue.trim();
|
||||
|
||||
DBRecord record = getSettingsRecord(associationId, name);
|
||||
if (record == null) {
|
||||
return createSettingsRecord(associationId, name, strValue, longValue);
|
||||
|
|
|
@ -15,10 +15,14 @@
|
|||
*/
|
||||
package ghidra.program.model.data;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.docking.settings.StringSettingsDefinition;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
|
||||
public class AddressSpaceSettingsDefinition
|
||||
implements StringSettingsDefinition, TypeDefSettingsDefinition {
|
||||
|
@ -101,4 +105,30 @@ public class AddressSpaceSettingsDefinition
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSuggestedValues(Settings settings) {
|
||||
return settings.getSuggestedValues(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSuggestedValues() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPreferredValues(Object settingsOwner, Set<String> set) {
|
||||
if (settingsOwner instanceof ProgramBasedDataTypeManager) {
|
||||
ProgramBasedDataTypeManager dtm = (ProgramBasedDataTypeManager) settingsOwner;
|
||||
AddressFactory addressFactory = dtm.getProgram().getAddressFactory();
|
||||
for (AddressSpace space : addressFactory.getAllAddressSpaces()) {
|
||||
if (space.isLoadedMemorySpace()) {
|
||||
set.add(space.getName());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue