mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-4949 Added Structure.setLength method and made structure editor performance improvements and various bug fixes.
This commit is contained in:
parent
2fe68de0e2
commit
ef724708df
19 changed files with 341 additions and 270 deletions
|
@ -236,9 +236,57 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLength(int len) {
|
||||
if (len < 0) {
|
||||
throw new IllegalArgumentException("Invalid length: " + len);
|
||||
}
|
||||
if (len == structLength || isPackingEnabled()) {
|
||||
return;
|
||||
}
|
||||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
if (len < structLength) {
|
||||
// identify index of first defined-component to be removed
|
||||
int index = Collections.binarySearch(components, Integer.valueOf(len),
|
||||
OffsetComparator.INSTANCE);
|
||||
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
}
|
||||
else {
|
||||
index = backupToFirstComponentContainingOffset(index, len);
|
||||
}
|
||||
int definedComponentCount = components.size();
|
||||
if (index >= 0 && index < definedComponentCount) {
|
||||
for (int i = index; i < definedComponentCount; i++) {
|
||||
doDelete(components.get(i));
|
||||
}
|
||||
components = components.subList(0, index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
numComponents += len - structLength;
|
||||
}
|
||||
structLength = len;
|
||||
repack(false, false);
|
||||
notifySizeChanged(false);
|
||||
}
|
||||
catch (IOException e) {
|
||||
dataMgr.dbError(e);
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void growStructure(int amount) {
|
||||
if (isPackingEnabled()) {
|
||||
if (amount < 0) {
|
||||
throw new IllegalArgumentException("Invalid growth amount: " + amount);
|
||||
}
|
||||
if (amount == 0 || isPackingEnabled()) {
|
||||
return;
|
||||
}
|
||||
lock.acquire();
|
||||
|
|
|
@ -914,6 +914,7 @@ public class StandAloneDataTypeManager extends DataTypeManagerDB implements Clos
|
|||
}
|
||||
}
|
||||
if (restored) {
|
||||
invalidateCache();
|
||||
notifyRestored();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -430,13 +430,22 @@ public interface Structure extends Composite {
|
|||
String comment) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Increases the size of the structure by the specified amount by adding undefined filler at the
|
||||
* Increases the size of the structure by the specified positive amount by adding undefined filler at the
|
||||
* end of the structure. NOTE: This method only has an affect on non-packed structures.
|
||||
*
|
||||
* @param amount the amount by which to grow the structure.
|
||||
* @throws IllegalArgumentException if amount < 1
|
||||
* @throws IllegalArgumentException if amount < 0
|
||||
*/
|
||||
public void growStructure(int amount);
|
||||
|
||||
/**
|
||||
* Set the size of the structure to the specified byte-length. If the length is shortened defined
|
||||
* components will be cleared and removed as required.
|
||||
* NOTE: This method only has an affect on non-packed structures.
|
||||
* @param length new structure length
|
||||
* @throws IllegalArgumentException if length < 0
|
||||
*/
|
||||
public void setLength(int length);
|
||||
|
||||
/**
|
||||
* <code>BitOffsetComparator</code> provides ability to compare an normalized bit offset (see
|
||||
|
|
|
@ -624,9 +624,43 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
return dtc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLength(int len) {
|
||||
if (len < 0) {
|
||||
throw new IllegalArgumentException("Invalid length: " + len);
|
||||
}
|
||||
if (len == structLength || isPackingEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (len < structLength) {
|
||||
// identify index of first defined-component to be removed
|
||||
int index = Collections.binarySearch(components, Integer.valueOf(len),
|
||||
OffsetComparator.INSTANCE);
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
}
|
||||
else {
|
||||
index = backupToFirstComponentContainingOffset(index, len);
|
||||
}
|
||||
int definedComponentCount = components.size();
|
||||
if (index >= 0 && index < definedComponentCount) {
|
||||
components = components.subList(0, index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
numComponents += len - structLength;
|
||||
}
|
||||
structLength = len;
|
||||
repack(false);
|
||||
notifySizeChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void growStructure(int amount) {
|
||||
if (isPackingEnabled()) {
|
||||
if (amount < 0) {
|
||||
throw new IllegalArgumentException("Invalid growth amount: " + amount);
|
||||
}
|
||||
if (amount == 0 || isPackingEnabled()) {
|
||||
return;
|
||||
}
|
||||
doGrowStructure(amount);
|
||||
|
|
|
@ -1449,6 +1449,40 @@ public class StructureDBTest extends AbstractGenericTest {
|
|||
assertEquals(dtc1, barStruct.getComponent(6));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLength() {
|
||||
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(4, struct.getNumComponents());
|
||||
assertEquals(4, struct.getNumDefinedComponents());
|
||||
|
||||
struct.setLength(20);
|
||||
assertEquals(20, struct.getLength());
|
||||
assertEquals(16, struct.getNumComponents());
|
||||
assertEquals(4, struct.getNumDefinedComponents());
|
||||
|
||||
// new length is offcut within 3rd component at offset 0x3 which should get cleared
|
||||
struct.setLength(4);
|
||||
assertEquals(4, struct.getLength());
|
||||
assertEquals(3, struct.getNumComponents());
|
||||
assertEquals(2, struct.getNumDefinedComponents());
|
||||
|
||||
// Maximum length supported by GUI editor is ~Integer.MAX_VALUE/10
|
||||
int len = Integer.MAX_VALUE / 10;
|
||||
struct.setLength(len);
|
||||
assertEquals(len, struct.getLength());
|
||||
assertEquals(len - 1, struct.getNumComponents());
|
||||
assertEquals(2, struct.getNumDefinedComponents());
|
||||
|
||||
len /= 2;
|
||||
struct.replaceAtOffset(len-2, WordDataType.dataType, -1, "x", null); // will be preserved below
|
||||
struct.replaceAtOffset(len+2, WordDataType.dataType, -1, "y", null); // will be cleared below
|
||||
struct.setLength(len);
|
||||
assertEquals(len, struct.getLength());
|
||||
assertEquals(len - 2, struct.getNumComponents());
|
||||
assertEquals(3, struct.getNumDefinedComponents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMany() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue