mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-1556 - Added support for searching for structure fields by offset
This commit is contained in:
parent
883f5a687a
commit
812ea4fe1e
45 changed files with 1461 additions and 840 deletions
|
@ -41,10 +41,10 @@ import utilities.util.reflection.ReflectionUtilities;
|
|||
* the entire application.
|
||||
* <p>
|
||||
* DockingActions can be invoked from the global menu, a popup menu, a toolbar, and/or a keybinding,
|
||||
* depending on whether or not menuBarData, popupMenuData, toolBarData, and/or keyBindingData have
|
||||
* depending on whether or not menuBarData, popupMenuData, toolBarData, and/or keyBindingData have
|
||||
* been set.
|
||||
* <p>
|
||||
* <b>
|
||||
* <b>
|
||||
* Implementors of this class should override {@link #actionPerformed(ActionContext)}.
|
||||
* </b>
|
||||
* <p>
|
||||
|
@ -199,12 +199,12 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
* <P>
|
||||
* If the client wants the action on all windows, then they can call {@link #shouldAddToAllWindows}
|
||||
* <P>
|
||||
* If the client wants the action to be on a window only when the window can produce
|
||||
* a certain context type, the the client should call
|
||||
* If the client wants the action to be on a window only when the window can produce
|
||||
* a certain context type, the the client should call
|
||||
* {@link #addToWindowWhen(Class)}
|
||||
* <P>
|
||||
* Otherwise, by default, the action will only be on the main window.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public final boolean shouldAddToWindow(boolean isMainWindow, Set<Class<?>> contextTypes) {
|
||||
|
@ -212,7 +212,7 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
if (menuBarData == null && toolBarData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// clients can specify that the action should be on all windows.
|
||||
if (shouldAddToAllWindows) {
|
||||
return true;
|
||||
|
@ -242,6 +242,14 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
DockingWindowManager.getHelpService().registerHelp(this, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the help location for this action
|
||||
* @return the help location for this action
|
||||
*/
|
||||
public HelpLocation getHelpLocation() {
|
||||
return DockingWindowManager.getHelpService().getHelpLocation(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals the the help system that this action does not need a help entry. Some actions
|
||||
* are so obvious that they do not require help, such as an action that renames a file.
|
||||
|
@ -579,10 +587,10 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
/**
|
||||
* Sets a predicate for dynamically determining the action's enabled state. If this
|
||||
* predicate is not set, the action's enable state must be controlled directly using the
|
||||
* {@link DockingAction#setEnabled(boolean)} method. See
|
||||
* {@link DockingAction#setEnabled(boolean)} method. See
|
||||
* {@link DockingActionIf#isEnabledForContext(ActionContext)}
|
||||
*
|
||||
* @param predicate the predicate that will be used to dynamically determine an action's
|
||||
*
|
||||
* @param predicate the predicate that will be used to dynamically determine an action's
|
||||
* enabled state.
|
||||
*/
|
||||
public void enabledWhen(Predicate<ActionContext> predicate) {
|
||||
|
@ -592,10 +600,10 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
/**
|
||||
* Sets a predicate for dynamically determining if this action should be included in
|
||||
* an impending pop-up menu. If this predicate is not set, the action's will be included
|
||||
* in an impending pop-up, if it is enabled. See
|
||||
* in an impending pop-up, if it is enabled. See
|
||||
* {@link DockingActionIf#isAddToPopup(ActionContext)}
|
||||
*
|
||||
* @param predicate the predicate that will be used to dynamically determine an action's
|
||||
*
|
||||
* @param predicate the predicate that will be used to dynamically determine an action's
|
||||
* enabled state.
|
||||
*/
|
||||
public void popupWhen(Predicate<ActionContext> predicate) {
|
||||
|
@ -603,10 +611,10 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets a predicate for dynamically determining if this action is valid for the current
|
||||
* Sets a predicate for dynamically determining if this action is valid for the current
|
||||
* {@link ActionContext}. See {@link DockingActionIf#isValidContext(ActionContext)}
|
||||
*
|
||||
* @param predicate the predicate that will be used to dynamically determine an action's
|
||||
*
|
||||
* @param predicate the predicate that will be used to dynamically determine an action's
|
||||
* validity for a given {@link ActionContext}
|
||||
*/
|
||||
public void validContextWhen(Predicate<ActionContext> predicate) {
|
||||
|
@ -620,14 +628,14 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
* that can produce an ActionContext that is appropriate for this action.
|
||||
* <P>
|
||||
* @param contextClass the ActionContext class required to be producible by a
|
||||
* provider that is hosted in that window before this action is added to that
|
||||
* window.
|
||||
*
|
||||
* provider that is hosted in that window before this action is added to that
|
||||
* window.
|
||||
*
|
||||
*/
|
||||
public void addToWindowWhen(Class<? extends ActionContext> contextClass) {
|
||||
addToWindowWhenContextClass = contextClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells this action to add itself to all windows
|
||||
* <P>
|
||||
|
@ -664,5 +672,5 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
String classInfo = trace[0].toString();
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ import docking.widgets.label.GDLabel;
|
|||
import docking.widgets.label.GHtmlLabel;
|
||||
|
||||
/**
|
||||
* A dialog that has text fields to get user input.
|
||||
*
|
||||
* A dialog that has text fields to get user input.
|
||||
*
|
||||
*/
|
||||
public class InputWithChoicesDialog extends DialogComponentProvider {
|
||||
|
||||
|
@ -39,12 +39,12 @@ public class InputWithChoicesDialog extends DialogComponentProvider {
|
|||
/**
|
||||
* Creates a provider for a generic input dialog with the specified title,
|
||||
* a label and a editable comboBox pre-populated with selectable values. The user
|
||||
* can check the value of {@link #isCanceled()} to know whether or not
|
||||
* can check the value of {@link #isCanceled()} to know whether or not
|
||||
* the user canceled the operation. To get the user selected value use the
|
||||
* {@link #getValue()} value(s) entered by the user. If the user cancelled the operation, then
|
||||
* null will be returned from <code>getValue()</code>.
|
||||
* <P>
|
||||
*
|
||||
*
|
||||
* @param dialogTitle used as the name of the dialog's title bar
|
||||
* @param label value to use for the label of the text field
|
||||
* @param optionValues values to populate the combo box
|
||||
|
@ -69,12 +69,12 @@ public class InputWithChoicesDialog extends DialogComponentProvider {
|
|||
/**
|
||||
* Creates a provider for a generic input dialog with the specified title,
|
||||
* a label and a editable comboBox pre-populated with selectable values. The user
|
||||
* can check the value of {@link #isCanceled()} to know whether or not
|
||||
* can check the value of {@link #isCanceled()} to know whether or not
|
||||
* the user canceled the operation. To get the user selected value use the
|
||||
* {@link #getValue()} value(s) entered by the user. If the user cancelled the operation, then
|
||||
* null will be returned from <code>getValue()</code>.
|
||||
* <P>
|
||||
*
|
||||
*
|
||||
* @param dialogTitle used as the name of the dialog's title bar
|
||||
* @param label value to use for the label of the text field
|
||||
* @param optionValues values to populate the combo box
|
||||
|
@ -180,6 +180,11 @@ public class InputWithChoicesDialog extends DialogComponentProvider {
|
|||
if (isCanceled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (allowEdits) {
|
||||
return combo.getText();
|
||||
}
|
||||
|
||||
Object selectedItem = combo.getSelectedItem();
|
||||
return selectedItem == null ? null : selectedItem.toString();
|
||||
}
|
||||
|
@ -188,7 +193,7 @@ public class InputWithChoicesDialog extends DialogComponentProvider {
|
|||
* Set the current choice to value.
|
||||
* @param value updated choice
|
||||
* @throws NoSuchElementException if choice does not permit edits and value is
|
||||
* not a valid choice.
|
||||
* not a valid choice.
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
combo.setSelectedItem(value);
|
||||
|
|
|
@ -57,17 +57,24 @@ public final class NumericUtilities {
|
|||
}
|
||||
|
||||
/**
|
||||
* parses the given string as a numeric value, detecting whether or not it begins with a Hex
|
||||
* Parses the given string as a numeric value, detecting whether or not it begins with a Hex
|
||||
* prefix, and if not, parses as a long int value.
|
||||
* @param numStr the number string
|
||||
* @return the long value or 0
|
||||
*
|
||||
*/
|
||||
public static long parseNumber(String numStr) {
|
||||
long value = 0;
|
||||
return parseNumber(numStr, Long.valueOf(0));
|
||||
}
|
||||
|
||||
public static Long parseNumber(String numStr, Long defaultValue) {
|
||||
|
||||
numStr = (numStr == null ? "" : numStr.trim());
|
||||
if (numStr.length() == 0) {
|
||||
return value;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
long value = 0;
|
||||
try {
|
||||
if (numStr.startsWith(HEX_PREFIX_x) || numStr.startsWith(HEX_PREFIX_X)) {
|
||||
value = Integer.parseInt(numStr.substring(2), 16);
|
||||
|
@ -78,6 +85,7 @@ public final class NumericUtilities {
|
|||
}
|
||||
catch (NumberFormatException exc) {
|
||||
// do nothing special; use default value
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
|
@ -192,7 +200,7 @@ public final class NumericUtilities {
|
|||
/**
|
||||
* returns the value of the specified long as hexadecimal, prefixing with the HEX_PREFIX_x
|
||||
* string.
|
||||
*
|
||||
*
|
||||
* @param value the long value to convert
|
||||
*/
|
||||
public final static String toHexString(long value) {
|
||||
|
@ -202,7 +210,7 @@ public final class NumericUtilities {
|
|||
/**
|
||||
* returns the value of the specified long as hexadecimal, prefixing with the HEX_PREFIX_x
|
||||
* string.
|
||||
*
|
||||
*
|
||||
* @param value the long value to convert
|
||||
* @param size number of bytes to be represented
|
||||
*/
|
||||
|
@ -216,7 +224,7 @@ public final class NumericUtilities {
|
|||
/**
|
||||
* returns the value of the specified long as signed hexadecimal, prefixing with the
|
||||
* HEX_PREFIX_x string.
|
||||
*
|
||||
*
|
||||
* @param value the long value to convert
|
||||
*/
|
||||
public final static String toSignedHexString(long value) {
|
||||
|
@ -230,14 +238,14 @@ public final class NumericUtilities {
|
|||
}
|
||||
|
||||
/**
|
||||
* Converts a <strong>unsigned</strong> long value, which is currently stored in a
|
||||
* Converts a <strong>unsigned</strong> long value, which is currently stored in a
|
||||
* java <strong>signed</strong> long, into a {@link BigInteger}.
|
||||
* <p>
|
||||
* In other words, the full 64 bits of the primitive java <strong>signed</strong>
|
||||
* long is being used to store an <strong>unsigned</strong> value. This
|
||||
* In other words, the full 64 bits of the primitive java <strong>signed</strong>
|
||||
* long is being used to store an <strong>unsigned</strong> value. This
|
||||
* method converts this into a positive BigInteger value.
|
||||
*
|
||||
* @param value java <strong>unsigned</strong> long value stuffed into a
|
||||
*
|
||||
* @param value java <strong>unsigned</strong> long value stuffed into a
|
||||
* java <strong>signed</strong> long
|
||||
* @return new {@link BigInteger} with the positive value of the unsigned long value
|
||||
*/
|
||||
|
@ -258,7 +266,7 @@ public final class NumericUtilities {
|
|||
/**
|
||||
* Get an unsigned aligned value corresponding to the specified unsigned value which will be
|
||||
* greater than or equal the specified value.
|
||||
*
|
||||
*
|
||||
* @param unsignedValue value to be aligned
|
||||
* @param alignment alignment
|
||||
* @return aligned value
|
||||
|
@ -384,7 +392,7 @@ public final class NumericUtilities {
|
|||
* Philosophically, it is hexadecimal, but the only valid digits are 0 and F. Any
|
||||
* partially-included nibble will be broken down into bracketed bits. Displaying masks in this
|
||||
* way is convenient when shown proximal to related masked values.
|
||||
*
|
||||
*
|
||||
* @param msk the mask
|
||||
* @param n the number of nibbles, starting at the right
|
||||
* @param truncate true if leading Xs may be truncated
|
||||
|
@ -441,7 +449,7 @@ public final class NumericUtilities {
|
|||
|
||||
/**
|
||||
* The reverse of {@link #convertMaskedValueToHexString(long, long, int, boolean, int, String)}
|
||||
*
|
||||
*
|
||||
* @param msk an object to receive the resulting mask
|
||||
* @param val an object to receive the resulting value
|
||||
* @param hex the input string to parse
|
||||
|
@ -669,7 +677,7 @@ public final class NumericUtilities {
|
|||
* <td>-64h</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @param number The number to represent
|
||||
* @param radix The base in which <code>number</code> is represented
|
||||
* @param mode Specifies how the number is formatted with respect to its signed-ness
|
||||
|
@ -849,7 +857,7 @@ public final class NumericUtilities {
|
|||
|
||||
/**
|
||||
* Determine if the provided Number is an integer type -- Byte, Short, Integer, or Long.
|
||||
*
|
||||
*
|
||||
* @param number the object to check for for integer-type
|
||||
* @return true if the provided number is an integer-type, false otherwise
|
||||
*/
|
||||
|
@ -860,7 +868,7 @@ public final class NumericUtilities {
|
|||
|
||||
/**
|
||||
* Determine if the provided Number class is an integer type.
|
||||
*
|
||||
*
|
||||
* @param numClass Class of an object
|
||||
* @return true if the class parameter is a integer type, false otherwise
|
||||
*/
|
||||
|
@ -870,7 +878,7 @@ public final class NumericUtilities {
|
|||
|
||||
/**
|
||||
* Determine if the provided Number is a floating-point type -- Float or Double.
|
||||
*
|
||||
*
|
||||
* @param number the object to check for for floating-point-type
|
||||
* @return true if the provided number is a floating-point-type, false otherwise
|
||||
*/
|
||||
|
@ -881,7 +889,7 @@ public final class NumericUtilities {
|
|||
|
||||
/**
|
||||
* Determine if the provided Number class is a floating-point type.
|
||||
*
|
||||
*
|
||||
* @param numClass Class of an object
|
||||
* @return true if the class parameter is a floating-point type, false otherwise
|
||||
*/
|
||||
|
@ -895,7 +903,7 @@ public final class NumericUtilities {
|
|||
private static interface IntegerRadixRenderer {
|
||||
/**
|
||||
* Format the given number in the provided radix base.
|
||||
*
|
||||
*
|
||||
* @param number the number to render
|
||||
* @param radix the base in which to render
|
||||
* @return a string representing the provided number in the given base
|
||||
|
|
|
@ -18,9 +18,8 @@ package ghidra.util.datastruct;
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Provides a list of integer ranges that are maintained in sorted order.
|
||||
* When a range is added any ranges that overlap or are adjacent to one another
|
||||
* will coalesce into a single range.
|
||||
* Provides a list of integer ranges that are maintained in sorted order. When a range is added
|
||||
* any ranges that overlap or are adjacent to one another will coalesce into a single range.
|
||||
*/
|
||||
public class SortedRangeList implements Iterable<Range> {
|
||||
TreeSet<Range> set;
|
||||
|
@ -33,8 +32,7 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new sorted range list with ranges equivalent to those in the
|
||||
* specified list.
|
||||
* Creates a new sorted range list with ranges equivalent to those in the specified list.
|
||||
* @param list the sorted range list to make an equivalent copy of.
|
||||
*/
|
||||
public SortedRangeList(SortedRangeList list) {
|
||||
|
@ -47,9 +45,8 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds the range from min to max to this sorted range list.
|
||||
* If the range is adjacent to or overlaps any other existing ranges,
|
||||
* then those ranges will coalesce.
|
||||
* Adds the range from min to max to this sorted range list. If the range is adjacent to or
|
||||
* overlaps any other existing ranges, then those ranges will coalesce.
|
||||
* @param min the range minimum
|
||||
* @param max the range maximum (inclusive)
|
||||
*/
|
||||
|
@ -82,15 +79,18 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
|
||||
/**
|
||||
* Returns an iterator over all the ranges in this list.
|
||||
* @return the iterator
|
||||
*/
|
||||
public Iterator<Range> getRanges() {
|
||||
return set.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over all the ranges in this list that iterates in the direction specified.
|
||||
* @param forward true indicates to iterate forward from minimum to maximum range.
|
||||
* false indicates backward iteration form maximum to minimum.
|
||||
* Returns an iterator over all the ranges in this list that iterates in the direction
|
||||
* specified.
|
||||
* @param forward true indicates to iterate forward from minimum to maximum range; false
|
||||
* indicates backward iteration form maximum to minimum.
|
||||
* @return the iterator
|
||||
*/
|
||||
public Iterator<Range> getRanges(boolean forward) {
|
||||
if (forward) {
|
||||
|
@ -106,6 +106,7 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
|
||||
/**
|
||||
* Returns the minimum int value in this sorted range list.
|
||||
* @return the min value
|
||||
* @throws NoSuchElementException if the list is empty.
|
||||
*/
|
||||
public int getMin() throws NoSuchElementException {
|
||||
|
@ -115,6 +116,7 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
|
||||
/**
|
||||
* Returns the maximum int value in this sorted range list.
|
||||
* @return the max value
|
||||
* @throws NoSuchElementException if the list is empty.
|
||||
*/
|
||||
public int getMax() throws NoSuchElementException {
|
||||
|
@ -124,13 +126,14 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
|
||||
/**
|
||||
* Returns the number of ranges in the list.
|
||||
* @return the number of ranges
|
||||
*/
|
||||
public int getNumRanges() {
|
||||
return set.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the indicated range of values from the list. This will remove
|
||||
* Removes the indicated range of values from the list. This will remove
|
||||
* any ranges or portion of ranges that overlap the indicated range.
|
||||
* @param min the minimum value for the range to remove.
|
||||
* @param max the maximum value for the range to remove.
|
||||
|
@ -182,6 +185,7 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
/**
|
||||
* Returns true if the value is contained in any ranges within this list.
|
||||
* @param value the value to check for.
|
||||
* @return true if the value is contained in any ranges within this list.
|
||||
*/
|
||||
public boolean contains(int value) {
|
||||
Range key = new Range(value, value);
|
||||
|
@ -217,6 +221,7 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
* Returns true if a single range contains all the values from min to max.
|
||||
* @param min the minimum value
|
||||
* @param max the maximum value
|
||||
* @return true if a single range contains all the values from min to max.
|
||||
*/
|
||||
public boolean contains(int min, int max) {
|
||||
Range range = getRangeContaining(min);
|
||||
|
@ -284,9 +289,12 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the range from min to max intersects (overlaps) any ranges in this sorted range list.
|
||||
* Returns true if the range from min to max intersects (overlaps) any ranges in this sorted
|
||||
* range list.
|
||||
* @param min the range minimum value.
|
||||
* @param max the range maximum value
|
||||
* @param max the range maximum value.
|
||||
* @return true if the range from min to max intersects (overlaps) any ranges in this sorted
|
||||
* range list.
|
||||
*/
|
||||
public boolean intersects(int min, int max) {
|
||||
Range key = new Range(min, min);
|
||||
|
@ -309,6 +317,7 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
|
||||
/**
|
||||
* Returns true if the range list is empty.
|
||||
* @return true if the range list is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return set.isEmpty();
|
||||
|
@ -327,7 +336,8 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a new SortedRangeList that is the intersection of this range list and the other range list specified.
|
||||
* Creates a new SortedRangeList that is the intersection of this range list and the other
|
||||
* range list specified.
|
||||
* @param other the other range list
|
||||
* @return the new SortedRangeList representing the intersection.
|
||||
*/
|
||||
|
@ -339,12 +349,9 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
return srl2;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Iterator<Range> it = getRanges();
|
||||
if (it.hasNext()) {
|
||||
Range r = it.next();
|
||||
|
@ -365,4 +372,28 @@ public class SortedRangeList implements Iterable<Range> {
|
|||
public void clear() {
|
||||
set.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(set);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SortedRangeList other = (SortedRangeList) obj;
|
||||
if (!Objects.equals(set, other.set)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,10 +48,10 @@ public class ReferenceTagProcessor extends TagProcessor {
|
|||
this.anchorManager = anchorManager;
|
||||
|
||||
//
|
||||
// Note: currently all help being built has the required stylesheet living under
|
||||
// Note: currently all help being built has the required stylesheet living under
|
||||
// <help dir>/shared/<stylesheet name>
|
||||
//
|
||||
// If we ever need a more robust styling mechanism, then this code would need to be
|
||||
//
|
||||
// If we ever need a more robust styling mechanism, then this code would need to be
|
||||
// updated to know how to search for the referenced stylesheet
|
||||
Path helpPath = help.getHelpLocation();
|
||||
FileSystem fs = helpPath.getFileSystem();
|
||||
|
@ -81,8 +81,8 @@ public class ReferenceTagProcessor extends TagProcessor {
|
|||
if ("a".equals(tagType)) {
|
||||
if (tagAttributes.containsKey("href")) {
|
||||
try {
|
||||
anchorManager.addAnchorRef(
|
||||
new HREF(help, file, tagAttributes.get("href"), lineNum));
|
||||
anchorManager
|
||||
.addAnchorRef(new HREF(help, file, tagAttributes.get("href"), lineNum));
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
errorCount++;
|
||||
|
@ -102,8 +102,8 @@ public class ReferenceTagProcessor extends TagProcessor {
|
|||
else if ("img".equals(tagType)) {
|
||||
if (tagAttributes.containsKey("src")) {
|
||||
try {
|
||||
anchorManager.addImageRef(
|
||||
new IMG(help, file, tagAttributes.get("src"), lineNum));
|
||||
anchorManager
|
||||
.addImageRef(new IMG(help, file, tagAttributes.get("src"), lineNum));
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
errorCount++;
|
||||
|
@ -119,7 +119,7 @@ public class ReferenceTagProcessor extends TagProcessor {
|
|||
else if ("link".equals(tagType)) {
|
||||
String rel = tagAttributes.get("rel");
|
||||
if (rel != null && "stylesheet".equals(rel.toLowerCase())) {
|
||||
// TODO there is at least one help module that has multiple style sheets. I see no reason to
|
||||
// TODO there is at least one help module that has multiple style sheets. I see no reason to
|
||||
// enforce this constraint:
|
||||
// if (hasStyleSheet) {
|
||||
// errorCount++;
|
||||
|
@ -191,7 +191,8 @@ public class ReferenceTagProcessor extends TagProcessor {
|
|||
if (!hasDefaultStyleSheet) {
|
||||
errorCount++;
|
||||
errors.append("Incorrect stylesheet defined - none match " + defaultStyleSheet +
|
||||
" in file " + htmlFile + EOL);
|
||||
" in file " + htmlFile + EOL + "\tDiscovered stylesheets: " + styleSheets + EOL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,10 +38,10 @@ public interface Data extends CodeUnit, Settings {
|
|||
|
||||
/**
|
||||
* Get the class used to express the value of this data.
|
||||
*
|
||||
*
|
||||
* <p>NOTE: This determination is made based upon data type and settings only and does not
|
||||
* examine memory bytes which are used to construct the data value object.
|
||||
*
|
||||
*
|
||||
* @return value class or null if a consistent class is not utilized.
|
||||
*/
|
||||
public Class<?> getValueClass();
|
||||
|
@ -216,7 +216,7 @@ public interface Data extends CodeUnit, Settings {
|
|||
* Return the first immediate child component that contains the byte at the given offset. It
|
||||
* is important to note that with certain datatypes there may be more than one component
|
||||
* containing the specified offset (see {@link #getComponentsContaining(int)}).
|
||||
*
|
||||
*
|
||||
* @param offset the amount to add to this data items address to get the address of the
|
||||
* requested data item.
|
||||
* @return first data component containing offset or null
|
||||
|
@ -227,10 +227,10 @@ public interface Data extends CodeUnit, Settings {
|
|||
public Data getComponentAt(int offset);
|
||||
|
||||
/**
|
||||
* RReturn the first immediate child component that contains the byte at the given offset. It
|
||||
* Return the first immediate child component that contains the byte at the given offset. It
|
||||
* is important to note that with certain datatypes there may be more than one component
|
||||
* containing the specified offset (see {@link #getComponentsContaining(int)}).
|
||||
*
|
||||
*
|
||||
* @param offset the amount to add to this data items address to get the
|
||||
* @return first data component containing offset or null address of the requested data item.
|
||||
*/
|
||||
|
|
|
@ -17,13 +17,15 @@
|
|||
|
||||
package ghidra.program.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
* The <CODE>FieldNameFieldLocation</CODE> class provides specific information
|
||||
* about the Function Name field within a program location.
|
||||
* The <CODE>FieldNameFieldLocation</CODE> class provides specific information about the Function
|
||||
* Name field within a program location.
|
||||
*/
|
||||
public class FieldNameFieldLocation extends CodeUnitLocation {
|
||||
|
||||
|
@ -31,11 +33,11 @@ public class FieldNameFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Construct a new FieldNameFieldLocation.
|
||||
*
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr the address of the codeunit.
|
||||
* @param componentPath if not null, it is the array of indexes that point
|
||||
* to a specific data type inside of another data type
|
||||
* @param addr the address of the code unit
|
||||
* @param componentPath if not null, it is the array of indexes that point to a specific data
|
||||
* type inside of another data type
|
||||
* @param fieldName the field name
|
||||
* @param charOffset the character position within the field name for this location.
|
||||
*/
|
||||
|
@ -48,14 +50,14 @@ public class FieldNameFieldLocation extends CodeUnitLocation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Default constructor needed for restoring
|
||||
* a field name location from XML
|
||||
* Default constructor needed for restoring a field name location from XML
|
||||
*/
|
||||
public FieldNameFieldLocation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field name of this location.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
|
@ -71,19 +73,19 @@ public class FieldNameFieldLocation extends CodeUnitLocation {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FieldNameFieldLocation other = (FieldNameFieldLocation) obj;
|
||||
if (fieldName == null) {
|
||||
if (other.fieldName != null)
|
||||
return false;
|
||||
}
|
||||
else if (!fieldName.equals(other.fieldName))
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
FieldNameFieldLocation other = (FieldNameFieldLocation) obj;
|
||||
if (!Objects.equals(fieldName, other.fieldName)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,14 +15,16 @@
|
|||
*/
|
||||
package ghidra.program.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.VariableOffset;
|
||||
|
||||
/**
|
||||
* The <CODE>OperandFieldLocation</CODE> class contains specific location information
|
||||
* within the OPERAND field of a CodeUnitLocation object.
|
||||
* The <CODE>OperandFieldLocation</CODE> class contains specific location information within the
|
||||
* OPERAND field of a CodeUnitLocation object.
|
||||
*/
|
||||
public class OperandFieldLocation extends CodeUnitLocation {
|
||||
|
||||
|
@ -32,17 +34,18 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Construct a new OperandFieldLocation object.
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr address of the location; should not be null
|
||||
* @param componentPath array of indexes for each nested data component; the
|
||||
* index is the data component's index within its parent; may be null
|
||||
*
|
||||
* @param program the program of the location.
|
||||
* @param addr address of the location; should not be null.
|
||||
* @param componentPath array of indexes for each nested data component; the index is the data
|
||||
* component's index within its parent; may be null.
|
||||
* @param refAddr the reference 'to' address.
|
||||
* @param rep the String representation of the operand.
|
||||
* @param opIndex the index of the operand at this location.
|
||||
* @param characterOffset the character position from the beginning of the operand.
|
||||
*/
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath,
|
||||
Address refAddr, String rep, int opIndex, int characterOffset) {
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath, Address refAddr,
|
||||
String rep, int opIndex, int characterOffset) {
|
||||
|
||||
super(program, addr, componentPath, refAddr, 0, opIndex, characterOffset);
|
||||
|
||||
|
@ -52,68 +55,63 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Construct a new OperandFieldLocation object.
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr address of the location; should not be null
|
||||
* @param componentPath array of indexes for each nested data component; the
|
||||
* index is the data component's index within its parent; may be null
|
||||
* @param refAddr the "referred to" address if the location is
|
||||
* over a reference; may be null
|
||||
*
|
||||
* @param program the program of the location.
|
||||
* @param addr address of the location; should not be null.
|
||||
* @param componentPath array of indexes for each nested data component; the index is the data
|
||||
* component's index within its parent; may be null .
|
||||
* @param refAddr the "referred to" address if the location is over a reference; may be null.
|
||||
* @param rep the String representation of the operand.
|
||||
* @param opIndex the index indicating the operand the location is on.
|
||||
* @param subOpIndex the index of the Object within the operand, this can
|
||||
* be used to call an instructions getOpObjects() method
|
||||
* @param characterOffset the character position from the beginning of the operand field
|
||||
* @param subOpIndex the index of the Object within the operand, this can be used to call an
|
||||
* instructions getOpObjects() method.
|
||||
* @param characterOffset the character position from the beginning of the operand field.
|
||||
*/
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath,
|
||||
Address refAddr, String rep, int opIndex, int subOpIndex, int characterOffset) {
|
||||
|
||||
public OperandFieldLocation(Program program, Address addr, int[] componentPath, Address refAddr,
|
||||
String rep, int opIndex, int subOpIndex, int characterOffset) {
|
||||
super(program, addr, componentPath, refAddr, 0, opIndex, characterOffset);
|
||||
|
||||
this.rep = rep;
|
||||
this.subOpIndex = subOpIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new OperandFieldLocation object for an instruction operand.
|
||||
*
|
||||
* @param program the program of the location
|
||||
* @param addr address of the location; should not be null
|
||||
* @param variableOffset associated variable offset or null
|
||||
* @param refAddr the "referred to" address if the location is
|
||||
* over a reference; may be null
|
||||
*
|
||||
* @param program the program of the location.
|
||||
* @param addr address of the location; should not be null.
|
||||
* @param variableOffset associated variable offset or null.
|
||||
* @param refAddr the "referred to" address if the location is over a reference; may be null.
|
||||
* @param rep the String representation of the operand.
|
||||
* @param opIndex the index indicating the operand the location is on.
|
||||
* @param subOpIndex the index of the Object within the operand, this can
|
||||
* be used to call an instructions getOpObjects() method
|
||||
* @param characterOffset the character position from the beginning of the operand field
|
||||
* @param subOpIndex the index of the Object within the operand, this can be used to call an
|
||||
* instructions getOpObjects() method.
|
||||
* @param characterOffset the character position from the beginning of the operand field.
|
||||
*/
|
||||
public OperandFieldLocation(Program program, Address addr, VariableOffset variableOffset,
|
||||
Address refAddr, String rep, int opIndex, int subOpIndex, int characterOffset) {
|
||||
|
||||
super(program, addr, null, refAddr, 0, opIndex, characterOffset);
|
||||
|
||||
this.rep = rep;
|
||||
this.subOpIndex = subOpIndex;
|
||||
this.variableOffset = variableOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor needed for restoring
|
||||
* an operand field location from XML.
|
||||
*/
|
||||
* Default constructor needed for restoring an operand field location from XML.
|
||||
*/
|
||||
public OperandFieldLocation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns VariableOffset object if applicable or null
|
||||
* Returns VariableOffset object if applicable or null.
|
||||
* @return the variable offset.
|
||||
*/
|
||||
public VariableOffset getVariableOffset() {
|
||||
return variableOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the opernand at this location.
|
||||
* Returns a string representation of the operand at this location.
|
||||
* @return the representation.
|
||||
*/
|
||||
public String getOperandRepresentation() {
|
||||
return rep;
|
||||
|
@ -121,6 +119,7 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Returns the index of the operand at this location.
|
||||
* @return the index
|
||||
*/
|
||||
public int getOperandIndex() {
|
||||
return getColumn();
|
||||
|
@ -128,18 +127,15 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
/**
|
||||
* Returns the sub operand index at this location.
|
||||
* This index can be used on the instruction.getOpObjects()
|
||||
* to find the actual object (Address, Register, Scalar) the
|
||||
* cursor is over.
|
||||
* <p>
|
||||
* This index can be used on the instruction.getOpObjects() to find the actual object (Address,
|
||||
* Register, Scalar) the cursor is over.
|
||||
* @return 0-n if over a valid OpObject, -1 otherwise
|
||||
*/
|
||||
public int getSubOperandIndex() {
|
||||
return subOpIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this location.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", OpRep = " + rep + ", subOpIndex = " + subOpIndex +
|
||||
|
@ -158,27 +154,25 @@ public class OperandFieldLocation extends CodeUnitLocation {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
}
|
||||
if (!super.equals(obj)) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OperandFieldLocation other = (OperandFieldLocation) obj;
|
||||
if (rep == null) {
|
||||
if (other.rep != null)
|
||||
return false;
|
||||
if (!Objects.equals(rep, other.rep)) {
|
||||
return false;
|
||||
}
|
||||
else if (!rep.equals(other.rep))
|
||||
if (subOpIndex != other.subOpIndex) {
|
||||
return false;
|
||||
if (subOpIndex != other.subOpIndex)
|
||||
return false;
|
||||
if (variableOffset == null) {
|
||||
if (other.variableOffset != null)
|
||||
return false;
|
||||
}
|
||||
else if (!variableOffset.equals(other.variableOffset))
|
||||
if (!Objects.equals(variableOffset, other.variableOffset)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()}" method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address of the location; cannot be null
|
||||
|
@ -118,7 +118,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()} method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address for the location
|
||||
|
@ -132,7 +132,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()} method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address for the location
|
||||
|
@ -150,7 +150,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
* Construct a new ProgramLocation for the given address. The address will be adjusted to the
|
||||
* beginning of the {@link CodeUnit code unit} containing that address (if it exists). The
|
||||
* original address can be retrieved using the {@link #getByteAddress()} method.
|
||||
*
|
||||
*
|
||||
* @param program the program associated with this program location (also used to obtain a
|
||||
* code-unit-aligned address)
|
||||
* @param addr address for the location
|
||||
|
@ -170,6 +170,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
/**
|
||||
* Returns the componentPath for the {@link CodeUnit code unit}. Null will be returned if the
|
||||
* object is an {@link Instruction} or a top-level {@link Data} object.
|
||||
* @return the path.
|
||||
*/
|
||||
public int[] getComponentPath() {
|
||||
return componentPath;
|
||||
|
@ -177,6 +178,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the program associated with this location.
|
||||
* @return the program.
|
||||
*/
|
||||
public Program getProgram() {
|
||||
return program;
|
||||
|
@ -184,11 +186,12 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the address associated with this location.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Note: this may not be the same as the byte address. For example, in a {@link CodeUnit code
|
||||
* unit} location this may be the minimum address of the code unit that contains the byte
|
||||
* address.
|
||||
* @return the address.
|
||||
*/
|
||||
public Address getAddress() {
|
||||
return addr;
|
||||
|
@ -196,6 +199,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the byte level address associated with this location.
|
||||
* @return the byte address.
|
||||
*/
|
||||
public Address getByteAddress() {
|
||||
return byteAddr;
|
||||
|
@ -203,6 +207,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the "referred to" address if the location is over an address in some field.
|
||||
* @return the address.
|
||||
*/
|
||||
public Address getRefAddress() {
|
||||
return refAddr;
|
||||
|
@ -210,7 +215,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Save this program location to the given save state object.
|
||||
*
|
||||
*
|
||||
* @param obj the save state object for saving the location
|
||||
*/
|
||||
public void saveState(SaveState obj) {
|
||||
|
@ -231,7 +236,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Restore this program location using the given program and save state object.
|
||||
*
|
||||
*
|
||||
* @param program1 program to restore from
|
||||
* @param obj the save state to restore from
|
||||
*/
|
||||
|
@ -254,7 +259,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Get the program location for the given program and save state object.
|
||||
*
|
||||
*
|
||||
* @param program the program for the location
|
||||
* @param saveState the state to restore
|
||||
* @return the restored program location
|
||||
|
@ -274,7 +279,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
// no address, it must be in a removed block; we can't use it
|
||||
}
|
||||
catch (RuntimeException e) { // restoreState may not parse the address if it is no longer valid.
|
||||
catch (RuntimeException e) { // state may not parse the address if it is no longer valid
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
// not sure why we are ignoring this--if you know, then please let everyone else know
|
||||
|
@ -419,7 +424,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
CodeUnit cu = p.getListing().getCodeUnitContaining(addr);
|
||||
|
||||
// if the codeunit is a data, try and dig down to the lowest subdata containing the address
|
||||
// if the code unit is data, get the lowest sub-data containing the address
|
||||
if (cu instanceof Data) {
|
||||
Data data = (Data) cu;
|
||||
cu = data.getPrimitiveAt((int) addr.subtract(data.getAddress()));
|
||||
|
@ -437,10 +442,10 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if this location represents a valid location in the given program
|
||||
*
|
||||
* Returns true if this location represents a valid location in the given program.
|
||||
*
|
||||
* @param testProgram the program to test if this location is valid.
|
||||
* @return true if this location represents a valid location in the given program
|
||||
* @return true if this location represents a valid location in the given program.
|
||||
*/
|
||||
public boolean isValid(Program testProgram) {
|
||||
return addr == null || testProgram.getAddressFactory().isValidAddress(addr);
|
||||
|
@ -448,7 +453,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
|
||||
/**
|
||||
* Returns the row within the program location.
|
||||
*
|
||||
*
|
||||
* @return the row within the program location.
|
||||
*/
|
||||
public int getRow() {
|
||||
|
@ -456,9 +461,9 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the character offset in the display item at the (row,col)
|
||||
*
|
||||
* @return the character offset in the display item at the (row,col)
|
||||
* Returns the character offset in the display item at the (row,col).
|
||||
*
|
||||
* @return the character offset in the display item at the (row,col).
|
||||
*/
|
||||
public int getCharOffset() {
|
||||
return charOffset;
|
||||
|
@ -467,6 +472,7 @@ public class ProgramLocation implements Comparable<ProgramLocation> {
|
|||
/**
|
||||
* Returns the column index of the display piece represented by this location. For most
|
||||
* locations, there is only one display item per row, in which case this value will be 0.
|
||||
* @return the column.
|
||||
*/
|
||||
public int getColumn() {
|
||||
return col;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* ###
|
||||
* 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 utility.function;
|
||||
|
||||
/**
|
||||
* A generic functional interface that is more semantically sound than {@link Runnable}. Use
|
||||
* anywhere you wish to have a generic callback function and you need to throw an exception.
|
||||
*
|
||||
* @param <T> the return type of your choice
|
||||
* @param <E> the exception of your choice
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExceptionalSupplier<T, E extends Exception> {
|
||||
|
||||
/**
|
||||
* The supplier method
|
||||
* @return the item to return
|
||||
* @throws E the declared exception
|
||||
*/
|
||||
public T get() throws E;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue