Merge branch 'GP-0_ghidra1_EmptyAddressSetIterators' into patch

This commit is contained in:
ghidra1 2021-07-06 22:01:28 -04:00
commit ef8ebf8eaa
20 changed files with 169 additions and 65 deletions

View file

@ -115,7 +115,7 @@ public class AddressKeyIteratorTest extends AbstractGhidraHeadedIntegrationTest
@Test @Test
public void testIterator0() throws Exception { public void testIterator0() throws Exception {
AddressKeyIterator it = new AddressKeyIterator(); AddressKeyIterator it = AddressKeyIterator.EMPTY_ITERATOR;
assertTrue(!it.hasNext()); assertTrue(!it.hasNext());
assertTrue(!it.hasPrevious()); assertTrue(!it.hasPrevious());
try { try {
@ -123,12 +123,14 @@ public class AddressKeyIteratorTest extends AbstractGhidraHeadedIntegrationTest
Assert.fail(); Assert.fail();
} }
catch (NoSuchElementException e) { catch (NoSuchElementException e) {
// expected
} }
try { try {
it.previous(); it.previous();
Assert.fail(); Assert.fail();
} }
catch (NoSuchElementException e) { catch (NoSuchElementException e) {
// expected
} }
} }

View file

@ -1174,6 +1174,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
if (addrSetView == null) { if (addrSetView == null) {
addrSetView = program.getMemory(); addrSetView = program.getMemory();
} }
else if (addrSetView.isEmpty()) {
return CodeUnitIterator.EMPTY_ITERATOR;
}
if (property.equals(CodeUnit.COMMENT_PROPERTY)) { if (property.equals(CodeUnit.COMMENT_PROPERTY)) {
try { try {
@ -1219,7 +1222,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
/** /**
* Get a forward iterator over code units that have comments of the given type. * Get a forward iterator over code units that have comments of the given type.
* @param commentType comment type defined in CodeUnit * @param commentType comment type defined in CodeUnit
* @param set address set * @param set address set (null for all defined memory)
* @return code unit iterator
*/ */
public CodeUnitIterator getCommentCodeUnitIterator(int commentType, AddressSetView set) { public CodeUnitIterator getCommentCodeUnitIterator(int commentType, AddressSetView set) {
CodeUnitIterator it = getCodeUnitIterator(CodeUnit.COMMENT_PROPERTY, set, true); CodeUnitIterator it = getCodeUnitIterator(CodeUnit.COMMENT_PROPERTY, set, true);
@ -1229,10 +1233,15 @@ public class CodeManager implements ErrorHandler, ManagerDB {
/** /**
* Get a forward iterator over addresses that have comments of the given type. * Get a forward iterator over addresses that have comments of the given type.
* @param commentType comment type defined in CodeUnit * @param commentType comment type defined in CodeUnit
* @param set address set * @param set address set (null for all defined memory)
* @param forward true to iterate in the direction of increasing addresses.
* @return address iterator
*/ */
public AddressIterator getCommentAddressIterator(int commentType, AddressSetView set, public AddressIterator getCommentAddressIterator(int commentType, AddressSetView set,
boolean forward) { boolean forward) {
if (set != null && set.isEmpty()) {
return AddressIterator.EMPTY_ITERATOR;
}
try { try {
AddressKeyIterator keyIter = commentAdapter.getKeys(set, forward); AddressKeyIterator keyIter = commentAdapter.getKeys(set, forward);
AddressIterator addrIter = AddressIterator addrIter =
@ -1251,6 +1260,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
* @param forward true to iterate in the direction of increasing addresses. * @param forward true to iterate in the direction of increasing addresses.
*/ */
public AddressIterator getCommentAddressIterator(AddressSetView addrSet, boolean forward) { public AddressIterator getCommentAddressIterator(AddressSetView addrSet, boolean forward) {
if (addrSet != null && addrSet.isEmpty()) {
return AddressIterator.EMPTY_ITERATOR;
}
try { try {
AddressKeyIterator keyIter = commentAdapter.getKeys(addrSet, forward); AddressKeyIterator keyIter = commentAdapter.getKeys(addrSet, forward);
return new AddressKeyAddressIterator(keyIter, forward, addrMap, program); return new AddressKeyAddressIterator(keyIter, forward, addrMap, program);
@ -1632,6 +1644,9 @@ public class CodeManager implements ErrorHandler, ManagerDB {
searchSet = new AddressSet( searchSet = new AddressSet(
initializedMemoryOnly ? mem.getLoadedAndInitializedAddressSet() : mem); initializedMemoryOnly ? mem.getLoadedAndInitializedAddressSet() : mem);
} }
else if (set.isEmpty()) {
return set;
}
else { else {
searchSet = new AddressSet(set); searchSet = new AddressSet(set);
searchSet = searchSet.intersect( searchSet = searchSet.intersect(
@ -1855,13 +1870,19 @@ public class CodeManager implements ErrorHandler, ManagerDB {
* Returns the next undefined data whose min address falls within the address set * Returns the next undefined data whose min address falls within the address set
* searching in the forward direction {@code (e.g., 0 -> 0xfff).} * searching in the forward direction {@code (e.g., 0 -> 0xfff).}
* *
* @param set the address set to look within. * @param set the address set to look within (required).
* @param monitor the current monitor. * @param monitor the current monitor.
* @return Data the first undefined data within the address set, or null if there is none. * @return Data the first undefined data within the address set, or null if there is none.
*/ */
public Data getFirstUndefinedData(AddressSetView set, TaskMonitor monitor) { public Data getFirstUndefinedData(AddressSetView set, TaskMonitor monitor) {
if (set.isEmpty()) {
return null;
}
Memory mem = program.getMemory(); Memory mem = program.getMemory();
set = mem.intersect(set); set = mem.intersect(set);
if (set.isEmpty()) {
return null;
}
int i = 0; int i = 0;
CodeUnitIterator it = getCodeUnits(set, true); CodeUnitIterator it = getCodeUnits(set, true);
@ -2172,8 +2193,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
private boolean exceedsLimitOn64BitAddressSegments(List<Address> longSegmentAddressList, private boolean exceedsLimitOn64BitAddressSegments(List<Address> longSegmentAddressList,
Address toAddr) { Address toAddr) {
long maskedOffset = toAddr.getOffset() & 0xffffffff00000000L; long maskedOffset = toAddr.getOffset() & 0xffffffff00000000L;
for (int i = 0; i < longSegmentAddressList.size(); i++) { for (Address address : longSegmentAddressList) {
Address address = longSegmentAddressList.get(i);
long offset = address.getOffset(); long offset = address.getOffset();
if ((offset & 0xffffffff00000000L) == maskedOffset) { if ((offset & 0xffffffff00000000L) == maskedOffset) {
return false; return false;
@ -2419,6 +2439,7 @@ public class CodeManager implements ErrorHandler, ManagerDB {
* @param forward if true the iterator returns all codeUnits from the given * @param forward if true the iterator returns all codeUnits from the given
* start address to the end of the program, otherwise it returns all codeUnits * start address to the end of the program, otherwise it returns all codeUnits
* from the given start address to the start of the program. * from the given start address to the start of the program.
* @return code unit iterator
*/ */
public CodeUnitIterator getCodeUnits(Address start, boolean forward) { public CodeUnitIterator getCodeUnits(Address start, boolean forward) {
@ -2439,6 +2460,10 @@ public class CodeManager implements ErrorHandler, ManagerDB {
bounds = program.getAddressFactory().getAddressSet(min, start); bounds = program.getAddressFactory().getAddressSet(min, start);
} }
AddressSet set = mem.intersect(bounds);
if (set.isEmpty()) {
return CodeUnitIterator.EMPTY_ITERATOR;
}
return new CodeUnitRecordIterator(this, getInstructions(start, forward), return new CodeUnitRecordIterator(this, getInstructions(start, forward),
getDefinedData(start, forward), mem.intersect(bounds), forward); getDefinedData(start, forward), mem.intersect(bounds), forward);
} }
@ -2447,10 +2472,15 @@ public class CodeManager implements ErrorHandler, ManagerDB {
* Returns an iterator over all codeUnits in the given addressSet. The iterator * Returns an iterator over all codeUnits in the given addressSet. The iterator
* will go from the lowest address to the largest or from the largest to the * will go from the lowest address to the largest or from the largest to the
* lowest depending on the forward parameter. * lowest depending on the forward parameter.
* @param set the memory address set over which code units should be iterated (required)
* @param forward determines if the iterator goes from lowest address to highest * @param forward determines if the iterator goes from lowest address to highest
* or the other way around. * or the other way around.
* @return code unit iterator
*/ */
public CodeUnitIterator getCodeUnits(AddressSetView set, boolean forward) { public CodeUnitIterator getCodeUnits(AddressSetView set, boolean forward) {
if (set.isEmpty()) {
return CodeUnitIterator.EMPTY_ITERATOR;
}
return new CodeUnitRecordIterator(this, getInstructions(set, forward), return new CodeUnitRecordIterator(this, getInstructions(set, forward),
getDefinedData(set, forward), set, forward); getDefinedData(set, forward), set, forward);
} }
@ -2677,9 +2707,8 @@ public class CodeManager implements ErrorHandler, ManagerDB {
} }
} }
} }
for (int i = 0; i < addrs.size(); i++) { for (Address addr : addrs) {
monitor.checkCanceled(); monitor.checkCanceled();
Address addr = addrs.get(i);
clearCodeUnits(addr, addr, false, monitor); clearCodeUnits(addr, addr, false, monitor);
} }
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,11 +15,11 @@
*/ */
package ghidra.program.database.code; package ghidra.program.database.code;
import java.util.Iterator;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import java.util.Iterator;
/** /**
* Combines an Instruction iterator and Data iterator into a codeunit iterator * Combines an Instruction iterator and Data iterator into a codeunit iterator
*/ */
@ -42,7 +41,7 @@ class CodeUnitRecordIterator implements CodeUnitIterator {
* @param codeMgr the code managaer * @param codeMgr the code managaer
* @param instIt the instruction iterator * @param instIt the instruction iterator
* @param dataIt the data iterator * @param dataIt the data iterator
* @param set the address set * @param set the address set (required)
* @param forward the iterator direction * @param forward the iterator direction
*/ */
CodeUnitRecordIterator(CodeManager codeMgr, InstructionIterator instIt, DataIterator dataIt, CodeUnitRecordIterator(CodeManager codeMgr, InstructionIterator instIt, DataIterator dataIt,

View file

@ -235,7 +235,7 @@ abstract class CommentsDBAdapter {
/** /**
* Returns an address key iterator over the given address set in the given direction. * Returns an address key iterator over the given address set in the given direction.
* @param addrSetView the set to iterator over. * @param addrSetView the set to iterator over (null for all defined memory).
* @param forward the direction to iterate. * @param forward the direction to iterate.
*/ */
abstract AddressKeyIterator getKeys(AddressSetView set, boolean forward) throws IOException; abstract AddressKeyIterator getKeys(AddressSetView set, boolean forward) throws IOException;

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,13 +15,12 @@
*/ */
package ghidra.program.database.map; package ghidra.program.database.map;
import ghidra.program.model.address.*;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import db.*; import db.*;
import ghidra.program.model.address.*;
/** /**
* Iterator of indexed fields that are addresses. The longs returned are the address longs. * Iterator of indexed fields that are addresses. The longs returned are the address longs.
@ -95,7 +93,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
* @param addrMap the address map * @param addrMap the address map
* @param absolute if true, only absolute memory address encodings are considered, otherwise * @param absolute if true, only absolute memory address encodings are considered, otherwise
* only standard/relocatable address encodings are considered. * only standard/relocatable address encodings are considered.
* @param set the set of addresses to iterator over. * @param set the set of addresses to iterator over or null for all addresses.
* @param atStart if true, iterates forward, otherwise iterates backwards. * @param atStart if true, iterates forward, otherwise iterates backwards.
* @throws IOException if a database io error occurs. * @throws IOException if a database io error occurs.
*/ */
@ -192,6 +190,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#hasNext() * @see db.DBLongIterator#hasNext()
*/ */
@Override
public boolean hasNext() throws IOException { public boolean hasNext() throws IOException {
if (it == null) { if (it == null) {
return false; return false;
@ -217,6 +216,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#hasPrevious() * @see db.DBLongIterator#hasPrevious()
*/ */
@Override
public boolean hasPrevious() throws IOException { public boolean hasPrevious() throws IOException {
if (it == null) { if (it == null) {
return false; return false;
@ -242,6 +242,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#next() * @see db.DBLongIterator#next()
*/ */
@Override
public long next() throws IOException { public long next() throws IOException {
if (hasNext()) { if (hasNext()) {
return ((LongField) it.next()).getLongValue(); return ((LongField) it.next()).getLongValue();
@ -252,6 +253,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#previous() * @see db.DBLongIterator#previous()
*/ */
@Override
public long previous() throws IOException { public long previous() throws IOException {
if (hasPrevious()) { if (hasPrevious()) {
return ((LongField) it.previous()).getLongValue(); return ((LongField) it.previous()).getLongValue();
@ -262,6 +264,7 @@ public class AddressIndexKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#delete() * @see db.DBLongIterator#delete()
*/ */
@Override
public boolean delete() throws IOException { public boolean delete() throws IOException {
if (it != null) { if (it != null) {
return it.delete(); return it.delete();

View file

@ -93,7 +93,7 @@ public class AddressIndexPrimaryKeyIterator implements DBFieldIterator {
* @param addrMap the address map * @param addrMap the address map
* @param absolute if true, only absolute memory address encodings are considered, otherwise * @param absolute if true, only absolute memory address encodings are considered, otherwise
* only standard/relocatable address encodings are considered. * only standard/relocatable address encodings are considered.
* @param set the set of addresses to iterator over. * @param set the set of addresses to iterator over or null for all addresses.
* @param atStart if true, iterates forward, otherwise iterates backwards. * @param atStart if true, iterates forward, otherwise iterates backwards.
* @throws IOException if a database io error occurs. * @throws IOException if a database io error occurs.
*/ */

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,15 +15,14 @@
*/ */
package ghidra.program.database.map; package ghidra.program.database.map;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressIterator;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import db.DBLongIterator; import db.DBLongIterator;
import db.util.ErrorHandler; import db.util.ErrorHandler;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressIterator;
/** /**
* Converts an AddressKeyIterator or an addressKeyAddressIterator into an AddressIterator * Converts an AddressKeyIterator or an addressKeyAddressIterator into an AddressIterator
@ -39,6 +37,7 @@ public class AddressKeyAddressIterator implements AddressIterator {
/** /**
* Constructor. * Constructor.
* @param keyIter address key iterator, may be null. All long values must decode properly with the specified addrMap. * @param keyIter address key iterator, may be null. All long values must decode properly with the specified addrMap.
* @param forward true to iterate in the direction of increasing addresses.
* @param addrMap address map * @param addrMap address map
* @param errHandler IO error handler (may be null) * @param errHandler IO error handler (may be null)
*/ */

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,14 +15,13 @@
*/ */
package ghidra.program.database.map; package ghidra.program.database.map;
import ghidra.program.model.address.*;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import db.DBLongIterator; import db.DBLongIterator;
import db.Table; import db.Table;
import ghidra.program.model.address.*;
/** /**
* Iterator of primary keys that are addresses. The longs returned are the address longs. * Iterator of primary keys that are addresses. The longs returned are the address longs.
@ -31,6 +29,8 @@ import db.Table;
public class AddressKeyIterator implements DBLongIterator { public class AddressKeyIterator implements DBLongIterator {
public static final AddressKeyIterator EMPTY_ITERATOR = new AddressKeyIterator();
private Table table; private Table table;
private List<KeyRange> keyRangeList; private List<KeyRange> keyRangeList;
@ -40,7 +40,7 @@ public class AddressKeyIterator implements DBLongIterator {
/** /**
* Constructs an empty iterator. * Constructs an empty iterator.
*/ */
public AddressKeyIterator() { private AddressKeyIterator() {
} }
/** /**
@ -96,7 +96,7 @@ public class AddressKeyIterator implements DBLongIterator {
* Memory addresses encoded as Absolute are not included. * Memory addresses encoded as Absolute are not included.
* @param table the database table key by addresses * @param table the database table key by addresses
* @param addrMap the address map * @param addrMap the address map
* @param set the address set to iterator over * @param set the address set to iterator over (may be null for all defined memory)
* @param startAddr the address at which to position the iterator, can be null. The exact * @param startAddr the address at which to position the iterator, can be null. The exact
* position of the iterator depends on the before parameter. * position of the iterator depends on the before parameter.
* @param before positions the iterator before the start address,otherwise after * @param before positions the iterator before the start address,otherwise after
@ -115,7 +115,7 @@ public class AddressKeyIterator implements DBLongIterator {
* @param addrMap the address map * @param addrMap the address map
* @param absolute if true, only absolute memory address encodings are considered, otherwise * @param absolute if true, only absolute memory address encodings are considered, otherwise
* only standard/relocatable address encodings are considered. * only standard/relocatable address encodings are considered.
* @param set the address set to iterator over * @param set the address set to iterator over or null for all addresses.
* @param startAddr the address at which to position the iterator, can be null. The exact * @param startAddr the address at which to position the iterator, can be null. The exact
* position of the iterator depends on the before parameter. * position of the iterator depends on the before parameter.
* @param before positions the iterator before the start address,otherwise after * @param before positions the iterator before the start address,otherwise after
@ -180,6 +180,7 @@ public class AddressKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#hasNext() * @see db.DBLongIterator#hasNext()
*/ */
@Override
public boolean hasNext() throws IOException { public boolean hasNext() throws IOException {
if (it == null) { if (it == null) {
return false; return false;
@ -203,6 +204,7 @@ public class AddressKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#hasPrevious() * @see db.DBLongIterator#hasPrevious()
*/ */
@Override
public boolean hasPrevious() throws IOException { public boolean hasPrevious() throws IOException {
if (it == null) { if (it == null) {
return false; return false;
@ -226,6 +228,7 @@ public class AddressKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#next() * @see db.DBLongIterator#next()
*/ */
@Override
public long next() throws IOException { public long next() throws IOException {
if (hasNext()) { if (hasNext()) {
return it.next(); return it.next();
@ -236,6 +239,7 @@ public class AddressKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#previous() * @see db.DBLongIterator#previous()
*/ */
@Override
public long previous() throws IOException { public long previous() throws IOException {
if (hasPrevious()) { if (hasPrevious()) {
return it.previous(); return it.previous();
@ -246,6 +250,7 @@ public class AddressKeyIterator implements DBLongIterator {
/** /**
* @see db.DBLongIterator#delete() * @see db.DBLongIterator#delete()
*/ */
@Override
public boolean delete() throws IOException { public boolean delete() throws IOException {
if (it != null) { if (it != null) {
return it.delete(); return it.delete();

View file

@ -15,13 +15,12 @@
*/ */
package ghidra.program.database.map; package ghidra.program.database.map;
import ghidra.program.model.address.*;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import db.*; import db.*;
import ghidra.program.model.address.*;
/** /**
* Returns a RecordIterator over records that are address keyed. Various constructors allow * Returns a RecordIterator over records that are address keyed. Various constructors allow
@ -116,7 +115,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
* @param addrMap the address map * @param addrMap the address map
* @param absolute if true, only absolute memory address encodings are considered, otherwise * @param absolute if true, only absolute memory address encodings are considered, otherwise
* only standard/relocatable address encodings are considered. * only standard/relocatable address encodings are considered.
* @param set the address set to iterate over. * @param set the address set to iterate over or null for all addresses
* @param startAddr the address at which to position the iterator. The iterator will be positioned * @param startAddr the address at which to position the iterator. The iterator will be positioned
* either before or after the start address depending on the before parameter. If this parameter * either before or after the start address depending on the before parameter. If this parameter
* is null, then the iterator will start either before the min address or after the max address * is null, then the iterator will start either before the min address or after the max address
@ -174,6 +173,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
/** /**
* @see db.RecordIterator#hasNext() * @see db.RecordIterator#hasNext()
*/ */
@Override
public boolean hasNext() throws IOException { public boolean hasNext() throws IOException {
if (it == null) { if (it == null) {
return false; return false;
@ -197,6 +197,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
/** /**
* @see db.RecordIterator#hasPrevious() * @see db.RecordIterator#hasPrevious()
*/ */
@Override
public boolean hasPrevious() throws IOException { public boolean hasPrevious() throws IOException {
if (it == null) { if (it == null) {
return false; return false;
@ -220,6 +221,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
/** /**
* @see db.RecordIterator#next() * @see db.RecordIterator#next()
*/ */
@Override
public DBRecord next() throws IOException { public DBRecord next() throws IOException {
if (hasNext()) { if (hasNext()) {
return it.next(); return it.next();
@ -230,6 +232,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
/** /**
* @see db.RecordIterator#previous() * @see db.RecordIterator#previous()
*/ */
@Override
public DBRecord previous() throws IOException { public DBRecord previous() throws IOException {
if (hasPrevious()) { if (hasPrevious()) {
return it.previous(); return it.previous();
@ -240,6 +243,7 @@ public class AddressKeyRecordIterator implements RecordIterator {
/** /**
* @see db.RecordIterator#delete() * @see db.RecordIterator#delete()
*/ */
@Override
public boolean delete() throws IOException { public boolean delete() throws IOException {
if (it != null) { if (it != null) {
return it.delete(); return it.delete();

View file

@ -65,7 +65,7 @@ public interface AddressMap {
/** /**
* Search for addr within the "sorted" keyRangeList and return the index of the * Search for addr within the "sorted" keyRangeList and return the index of the
* keyRange which contains the specified addr. * keyRange which contains the specified addr.
* @param keyRangeList * @param keyRangeList key range list to search
* @param addr address or null * @param addr address or null
* @return index of the keyRange within the keyRangeList which contains addr * @return index of the keyRange within the keyRangeList which contains addr
* if it is contained in the list; otherwise, <code>(-(<i>insertion point</i>) - 1)</code>. * if it is contained in the list; otherwise, <code>(-(<i>insertion point</i>) - 1)</code>.
@ -100,7 +100,7 @@ public interface AddressMap {
* Generates a properly ordered list of database key ranges for a * Generates a properly ordered list of database key ranges for a
* a specified address set. If absolute encodings are requested, * a specified address set. If absolute encodings are requested,
* only memory addresses will be included. * only memory addresses will be included.
* @param set address set or null for all real address. * @param set address set or null for all addresses. May not be null if <code>create</code> is true.
* @param create true if a new keys may be generated, otherwise returned * @param create true if a new keys may be generated, otherwise returned
* key-ranges will be limited to those already defined. * key-ranges will be limited to those already defined.
* @return "sorted" list of KeyRange objects * @return "sorted" list of KeyRange objects
@ -113,12 +113,14 @@ public interface AddressMap {
* "absoluteEncoding" method. If the program's default address space is segmented (i.e., SegmentedAddressSpace). * "absoluteEncoding" method. If the program's default address space is segmented (i.e., SegmentedAddressSpace).
* the address returned will be always be normalized to defined segmented memory blocks if possible. * the address returned will be always be normalized to defined segmented memory blocks if possible.
* @param value the long value to convert to an address. * @param value the long value to convert to an address.
* @return address decoded from long
*/ */
public Address decodeAddress(long value); public Address decodeAddress(long value);
/** /**
* Returns the address factory associated with this map. * Returns the address factory associated with this map.
* Null may be returned if map not associated with a specific address factory. * Null may be returned if map not associated with a specific address factory.
* @return associated {@link AddressFactory} or null
*/ */
public AddressFactory getAddressFactory(); public AddressFactory getAddressFactory();
@ -140,7 +142,7 @@ public interface AddressMap {
* Generates a properly ordered list of database key ranges for a * Generates a properly ordered list of database key ranges for a
* a specified address set. If absolute encodings are requested, * a specified address set. If absolute encodings are requested,
* only memory addresses will be included. * only memory addresses will be included.
* @param set address set or null for all real address. * @param set address set or null for all addresses. May not be null if <code>create</code> is true.
* @param absolute if true, absolute key encodings are returned, otherwise * @param absolute if true, absolute key encodings are returned, otherwise
* standard/relocatable address key encodings are returned. * standard/relocatable address key encodings are returned.
* @param create true if a new keys may be generated, otherwise returned * @param create true if a new keys may be generated, otherwise returned

View file

@ -434,7 +434,7 @@ public abstract class PropertyMapDB implements PropertyMap {
/** /**
* Get an iterator over the long address keys which contain a property value. * Get an iterator over the long address keys which contain a property value.
* @param set * @param set addresses over which to iterate (null indicates all defined memory regions)
* @param atStart true if the iterator should be positioned at the start * @param atStart true if the iterator should be positioned at the start
* of the range * of the range
* @return long address iterator. * @return long address iterator.
@ -442,9 +442,8 @@ public abstract class PropertyMapDB implements PropertyMap {
*/ */
public AddressKeyIterator getAddressKeyIterator(AddressSetView set, boolean atStart) public AddressKeyIterator getAddressKeyIterator(AddressSetView set, boolean atStart)
throws IOException { throws IOException {
if (propertyTable == null || (set != null && set.isEmpty())) {
if (propertyTable == null) { return AddressKeyIterator.EMPTY_ITERATOR;
return new AddressKeyIterator();
} }
if (atStart) { if (atStart) {
return new AddressKeyIterator(propertyTable, addrMap, set, set.getMinAddress(), true); return new AddressKeyIterator(propertyTable, addrMap, set, set.getMinAddress(), true);
@ -463,7 +462,7 @@ public abstract class PropertyMapDB implements PropertyMap {
throws IOException { throws IOException {
if (propertyTable == null) { if (propertyTable == null) {
return new AddressKeyIterator(); return AddressKeyIterator.EMPTY_ITERATOR;
} }
return new AddressKeyIterator(propertyTable, addrMap, start, before); return new AddressKeyIterator(propertyTable, addrMap, start, before);
} }
@ -481,7 +480,7 @@ public abstract class PropertyMapDB implements PropertyMap {
throws IOException { throws IOException {
if (propertyTable == null) { if (propertyTable == null) {
return new AddressKeyIterator(); return AddressKeyIterator.EMPTY_ITERATOR;
} }
if (atStart) { if (atStart) {
return new AddressKeyIterator(propertyTable, addrMap, start, end, start, true); return new AddressKeyIterator(propertyTable, addrMap, start, end, start, true);
@ -561,8 +560,8 @@ public abstract class PropertyMapDB implements PropertyMap {
*/ */
@Override @Override
public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) { public AddressIterator getPropertyIterator(AddressSetView asv, boolean forward) {
if (propertyTable == null) { if (propertyTable == null || (asv != null && asv.isEmpty())) {
return new EmptyAddressIterator(); return AddressIterator.EMPTY_ITERATOR;
} }
AddressKeyIterator keyIter = null; AddressKeyIterator keyIter = null;
try { try {

View file

@ -946,6 +946,9 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
@Override @Override
public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet, public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet,
boolean forward) { boolean forward) {
if (addrSet != null && addrSet.isEmpty()) {
return AddressIterator.EMPTY_ITERATOR;
}
try { try {
return toAdapter.getToIterator(addrSet, forward); return toAdapter.getToIterator(addrSet, forward);
} }
@ -973,6 +976,9 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
@Override @Override
public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward) { public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward) {
if (addrSet != null && addrSet.isEmpty()) {
return AddressIterator.EMPTY_ITERATOR;
}
try { try {
return fromAdapter.getFromIterator(addrSet, forward); return fromAdapter.getFromIterator(addrSet, forward);
} }

View file

@ -44,7 +44,7 @@ class AddressSetFilteredSymbolIterator implements SymbolIterator {
/** /**
* Construct a new AddressSetFilteredSymbolIterator. * Construct a new AddressSetFilteredSymbolIterator.
* @param symbolMgr the symbol manager * @param symbolMgr the symbol manager
* @param set the address set to iterator over. * @param set the address set to iterator over (required).
* @param query the query to use as a filter * @param query the query to use as a filter
* @param forward the direction of the iterator. * @param forward the direction of the iterator.
*/ */

View file

@ -1204,6 +1204,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
@Override @Override
public SymbolIterator getPrimarySymbolIterator(AddressSetView set, boolean forward) { public SymbolIterator getPrimarySymbolIterator(AddressSetView set, boolean forward) {
if (set.isEmpty()) {
return SymbolIterator.EMPTY_ITERATOR;
}
Query query1 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_DATA2_COL, new IntField(1)); Query query1 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_DATA2_COL, new IntField(1));
Query query2 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL, Query query2 = new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL,
new ByteField(SymbolType.LABEL.getID())); new ByteField(SymbolType.LABEL.getID()));
@ -1216,6 +1219,9 @@ public class SymbolManager implements SymbolTable, ManagerDB {
@Override @Override
public SymbolIterator getSymbols(AddressSetView set, SymbolType type, boolean forward) { public SymbolIterator getSymbols(AddressSetView set, SymbolType type, boolean forward) {
if (set.isEmpty()) {
return SymbolIterator.EMPTY_ITERATOR;
}
Query query = Query query =
new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL, new ByteField(type.getID())); new FieldMatchQuery(SymbolDatabaseAdapter.SYMBOL_TYPE_COL, new ByteField(type.getID()));
return new AddressSetFilteredSymbolIterator(this, set, query, forward); return new AddressSetFilteredSymbolIterator(this, set, query, forward);

View file

@ -16,6 +16,7 @@
package ghidra.program.model.address; package ghidra.program.model.address;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
import util.CollectionUtils; import util.CollectionUtils;
@ -30,20 +31,24 @@ import util.CollectionUtils;
*/ */
public interface AddressIterator extends Iterator<Address>, Iterable<Address> { public interface AddressIterator extends Iterator<Address>, Iterable<Address> {
/**
* Get the next address.
*
* @return the next address in the iteration.
*/
@Override
public Address next();
/** public static final AddressIterator EMPTY_ITERATOR = new AddressIterator() {
* Checks if there is a next address in the iteration.
*
* @return true if there is a next address.
*/
@Override @Override
public boolean hasNext(); public boolean hasNext() {
return false;
}
@Override
public Address next() {
throw new NoSuchElementException();
}
@Override
public Iterator<Address> iterator() {
return this;
}
};
} }

View file

@ -26,14 +26,35 @@ import util.CollectionUtils;
*/ */
public interface CodeUnitIterator extends Iterator<CodeUnit>, Iterable<CodeUnit> { public interface CodeUnitIterator extends Iterator<CodeUnit>, Iterable<CodeUnit> {
public static final CodeUnitIterator EMPTY_ITERATOR = new CodeUnitIterator() {
@Override
public boolean hasNext() {
return false;
}
@Override
public CodeUnit next() {
return null;
}
@Override
public Iterator<CodeUnit> iterator() {
return this;
}
};
/** /**
* Returns true if the iteration has more elements. * Return true if there is a next CodeUnit.
*/ */
@Override @Override
public boolean hasNext(); public boolean hasNext();
/** /**
* Return the next code unit in the iteration. * Get the next CodeUnit or null if no more CodeUnits.
* <P>NOTE: This deviates from the standard {@link Iterator} interface
* by returning null instead of throwing an exception.
*/ */
@Override @Override
public CodeUnit next(); public CodeUnit next();

View file

@ -213,7 +213,7 @@ public interface Listing {
* addresses are contained in the given address set will be returned by the * addresses are contained in the given address set will be returned by the
* iterator. * iterator.
* *
* @param addrSet the AddressRangeSet to iterate over. * @param addrSet the AddressRangeSet to iterate over (required).
* @param forward true means get iterator in forward direction * @param forward true means get iterator in forward direction
* @return a CodeUnitIterator that is restricted to the give * @return a CodeUnitIterator that is restricted to the give
* AddressRangeSet. * AddressRangeSet.

View file

@ -288,7 +288,7 @@ public interface ReferenceManager {
/** /**
* Returns an iterator over all addresses that are the "From" address in a * Returns an iterator over all addresses that are the "From" address in a
* reference, restricted by the given address set. * reference, restricted by the given address set.
* @param addrSet the set of address to restrict the iterator. * @param addrSet the set of address to restrict the iterator or null for all addresses.
* @param forward true means to iterate in the forward direction * @param forward true means to iterate in the forward direction
*/ */
public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward); public AddressIterator getReferenceSourceIterator(AddressSetView addrSet, boolean forward);
@ -304,7 +304,7 @@ public interface ReferenceManager {
/** /**
* Returns an iterator over all addresses that are the "To" address in a * Returns an iterator over all addresses that are the "To" address in a
* memory reference, restricted by the given address set. * memory reference, restricted by the given address set.
* @param addrSet the set of address to restrict the iterator. * @param addrSet the set of address to restrict the iterator or null for all addresses.
* @param forward true means to iterate in the forward direction * @param forward true means to iterate in the forward direction
*/ */
public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet, boolean forward); public AddressIterator getReferenceDestinationIterator(AddressSetView addrSet, boolean forward);

View file

@ -25,13 +25,37 @@ import util.CollectionUtils;
* @see CollectionUtils#asIterable * @see CollectionUtils#asIterable
*/ */
public interface SymbolIterator extends Iterator<Symbol>, Iterable<Symbol> { public interface SymbolIterator extends Iterator<Symbol>, Iterable<Symbol> {
public static final SymbolIterator EMPTY_ITERATOR = new SymbolIterator() {
@Override
public Iterator<Symbol> iterator() {
return this;
}
@Override
public Symbol next() {
return null;
}
@Override
public boolean hasNext() {
return false;
}
};
/** /**
* Return true if there is a next symbol. * Return true if there is a next symbol.
*/ */
@Override
public boolean hasNext(); public boolean hasNext();
/** /**
* Get the next symbol. * Get the next symbol or null if no more symbols.
* <P>NOTE: This deviates from the standard {@link Iterator} interface
* by returning null instead of throwing an exception.
*/ */
@Override
public Symbol next(); public Symbol next();
} }

View file

@ -420,7 +420,7 @@ public interface SymbolTable {
/** /**
* Returns all the symbols of the given type within the given address set. * Returns all the symbols of the given type within the given address set.
* @param set the address set in which to look for symbols of the given type * @param set the address set in which to look for symbols of the given type (required).
* @param type the SymbolType to look for. * @param type the SymbolType to look for.
* @param forward the direction within the addressSet to search * @param forward the direction within the addressSet to search
* @return symbol iterator * @return symbol iterator
@ -500,7 +500,7 @@ public interface SymbolTable {
/** /**
* Get an iterator over symbols at addresses in the given addressSet * Get an iterator over symbols at addresses in the given addressSet
* @param asv the set of address over which to iterate symbols. * @param asv the set of address over which to iterate symbols (required).
* @param forward true means the iterator is in the forward direction * @param forward true means the iterator is in the forward direction
* @return symbol iterator * @return symbol iterator
*/ */