mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 13:11:47 +00:00
Merge branch 'GP-943_ghidra1_GetComponentContaining'
This commit is contained in:
commit
a0af911366
@ -302,20 +302,16 @@ public class PreCommentFieldFactory extends FieldFactory {
|
||||
|
||||
if (dt instanceof Structure) {
|
||||
Structure struct = (Structure) dt;
|
||||
lastDtc = struct.getComponentContaining(struct.getLength());
|
||||
int lastDtcOrdinal = struct.getNumComponents() - 1;
|
||||
while (lastDtc != null && lastDtc.isBitFieldComponent() &&
|
||||
lastDtc.getOrdinal() < lastDtcOrdinal) {
|
||||
lastDtc = struct.getComponent(lastDtc.getOrdinal() + 1);
|
||||
}
|
||||
List<DataTypeComponent> components =
|
||||
struct.getComponentsContaining(struct.getLength());
|
||||
lastDtc = components.isEmpty() ? null : components.get(components.size() - 1);
|
||||
}
|
||||
else if (dt instanceof DynamicDataType) {
|
||||
DynamicDataType ddt = (DynamicDataType) dt;
|
||||
lastDtc = ddt.getComponentAt(data.getLength(), data);
|
||||
int lastDtcOrdinal = ddt.getNumComponents(data);
|
||||
while (lastDtc != null && lastDtc.isBitFieldComponent() &&
|
||||
lastDtc.getOrdinal() < lastDtcOrdinal) {
|
||||
lastDtc = ddt.getComponent(lastDtc.getOrdinal() + 1, data);
|
||||
int lastDtcOrdinal = ddt.getNumComponents(data) - 1;
|
||||
if (lastDtc != null && lastDtc.getOrdinal() < lastDtcOrdinal) {
|
||||
lastDtc = ddt.getComponent(lastDtcOrdinal, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -778,20 +778,20 @@ public class DWARFDataTypeImporterTest extends DWARFTestBase {
|
||||
|
||||
DebugInfoEntry structDIE = newStruct("mystruct", 100).create(cu);
|
||||
newMember(structDIE, "f1", intDIE, 0).create(cu);
|
||||
newMember(structDIE, "flexarray", arrayDIE, 99).create(cu);
|
||||
newMember(structDIE, "flexarray", arrayDIE, 100).create(cu);
|
||||
|
||||
importAllDataTypes();
|
||||
|
||||
Structure structdt = (Structure) dataMgr.getDataType(rootCP, "mystruct");
|
||||
|
||||
DataTypeComponent component = structdt.getComponentContaining(99);
|
||||
assertNotNull(component);
|
||||
List<DataTypeComponent> components = structdt.getComponentsContaining(100);
|
||||
assertEquals(1, components.size());
|
||||
DataTypeComponent component = components.get(0);
|
||||
assertEquals(0, component.getLength());
|
||||
DataType dt = component.getDataType();
|
||||
assertTrue(dt.isEquivalent(new ArrayDataType(IntegerDataType.dataType, 0, -1)));
|
||||
|
||||
assertEquals(100, structdt.getLength());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1477,11 +1477,158 @@ public class StructureDataTypeTest extends AbstractGTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testgetComponentContaining() {
|
||||
public void testGetComponentAt() {
|
||||
/**
|
||||
* /TestStruct
|
||||
* pack(disabled)
|
||||
* Structure TestStruct {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 1 word 2 null "Comment2"
|
||||
* 3 dword 4 field3 ""
|
||||
* 7 byte 1 field4 "Comment4"
|
||||
* }
|
||||
* Size = 8 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
DataTypeComponent dtc = struct.getComponentAt(3);
|
||||
assertEquals(" 2 3 dword 4 field3 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentAt(4); // offcut
|
||||
assertNull(dtc);
|
||||
|
||||
assertEquals(8, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentAt(8);
|
||||
assertNull(dtc);
|
||||
|
||||
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), "zarray1", null);
|
||||
struct.add(new LongDataType(), "field4", null);
|
||||
struct.add(new ArrayDataType(LongDataType.dataType, 0, -1), "zarray2", null);
|
||||
|
||||
assertEquals(12, struct.getLength());
|
||||
|
||||
/**
|
||||
* /TestStruct
|
||||
* pack(disabled)
|
||||
* Structure TestStruct {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 1 word 2 null "Comment2"
|
||||
* 3 dword 4 field3 ""
|
||||
* 7 byte 1 field4 "Comment4"
|
||||
* 8 char[0] 0 zarray1 ""
|
||||
* 8 long 4 field4 ""
|
||||
* 12 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 12 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
dtc = struct.getComponentAt(8);
|
||||
assertEquals(" 5 8 long 4 field4 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentAt(9); // offcut
|
||||
assertNull(dtc);
|
||||
|
||||
dtc = struct.getComponentAt(12); // end-of-struct
|
||||
assertNull(dtc);
|
||||
|
||||
// force components to align
|
||||
struct.setPackingEnabled(true);
|
||||
|
||||
/**
|
||||
* /Test
|
||||
* pack(disabled)
|
||||
* Structure Test {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 2 word 2 null "Comment2"
|
||||
* 4 dword 4 field3 ""
|
||||
* 8 byte 1 field4 "Comment4"
|
||||
* 9 char[0] 0 zarray1 ""
|
||||
* 12 long 4 field4 ""
|
||||
* 16 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 16 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
assertEquals(16, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentAt(9); // offset of zero-length component
|
||||
assertNull(dtc);
|
||||
|
||||
struct.setPackingEnabled(false);
|
||||
|
||||
dtc = struct.getComponentAt(9); // undefined at offset of zero-length component
|
||||
assertEquals(" 5 9 undefined 1 null null", dtc.toString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentContaining() {
|
||||
DataTypeComponent dtc = struct.getComponentContaining(4);
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals(3, dtc.getOffset());
|
||||
assertEquals(" 2 3 dword 4 field3 null", dtc.toString());
|
||||
|
||||
assertEquals(8, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentContaining(8);
|
||||
assertNull(dtc);
|
||||
|
||||
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), "zarray1", null);
|
||||
struct.add(new LongDataType(), "field4", null);
|
||||
struct.add(new ArrayDataType(LongDataType.dataType, 0, -1), "zarray2", null);
|
||||
|
||||
assertEquals(12, struct.getLength());
|
||||
|
||||
/**
|
||||
* /TestStruct
|
||||
* pack(disabled)
|
||||
* Structure TestStruct {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 1 word 2 null "Comment2"
|
||||
* 3 dword 4 field3 ""
|
||||
* 7 byte 1 field4 "Comment4"
|
||||
* 8 char[0] 0 zarray1 ""
|
||||
* 8 long 4 field4 ""
|
||||
* 12 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 12 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
dtc = struct.getComponentContaining(8);
|
||||
assertEquals(" 5 8 long 4 field4 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentContaining(9); // offcut
|
||||
assertEquals(" 5 8 long 4 field4 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentContaining(12); // end-of-struct
|
||||
assertNull(dtc);
|
||||
|
||||
// force components to align
|
||||
struct.setPackingEnabled(true);
|
||||
|
||||
/**
|
||||
* /Test
|
||||
* pack(disabled)
|
||||
* Structure Test {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 2 word 2 null "Comment2"
|
||||
* 4 dword 4 field3 ""
|
||||
* 8 byte 1 field4 "Comment4"
|
||||
* 9 char[0] 0 zarray1 ""
|
||||
* 12 long 4 field4 ""
|
||||
* 16 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 16 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
assertEquals(16, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentContaining(9); // offset of zero-length component
|
||||
assertNull(dtc);
|
||||
|
||||
struct.setPackingEnabled(false);
|
||||
|
||||
dtc = struct.getComponentContaining(9); // undefined at offset of zero-length component
|
||||
assertEquals(" 5 9 undefined 1 null null", dtc.toString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -345,8 +345,7 @@ public class EditStructureUtils {
|
||||
while (index >= 0) {
|
||||
monitor.checkCanceled();
|
||||
DataTypeComponent component = structure.getComponentAt(index);
|
||||
if (component.getDataType().getName().equals("undefined") &&
|
||||
component.getLength() == 1) {
|
||||
if (component != null && component.getDataType() == DataType.DEFAULT) {
|
||||
index--;
|
||||
numUndefineds++;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package ghidra.app.plugin.core.decompile.actions;
|
||||
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
|
||||
import docking.action.KeyBindingData;
|
||||
import docking.action.MenuData;
|
||||
@ -67,21 +66,6 @@ public class RetypeFieldAction extends AbstractDecompilerAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
private DataTypeComponent getComponentContaining(Structure struct, int offset) {
|
||||
DataTypeComponent comp = null;
|
||||
List<DataTypeComponent> components = struct.getComponentsContaining(offset);
|
||||
if (components != null) {
|
||||
for (DataTypeComponent c : components) {
|
||||
// skip components not supported by decompiler
|
||||
if (c.getLength() != 0) {
|
||||
comp = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decompilerActionPerformed(DecompilerActionContext context) {
|
||||
Program program = context.getProgram();
|
||||
@ -102,8 +86,14 @@ public class RetypeFieldAction extends AbstractDecompilerAction {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get original component and datatype
|
||||
DataTypeComponent comp = getComponentContaining(struct, offset);
|
||||
// Get original component and datatype - structure may be packed so an offset which corresponds
|
||||
// to padding byte may return null
|
||||
DataTypeComponent comp = struct.getComponentContaining(offset);
|
||||
if (comp != null && comp.getOffset() != offset) {
|
||||
Msg.showError(this, tool.getToolFrame(), "Retype Failed",
|
||||
"Retype offset does not correspond to start of component");
|
||||
return;
|
||||
}
|
||||
DataType originalDataType = comp != null ? comp.getDataType() : DataType.DEFAULT;
|
||||
if (originalDataType instanceof BitFieldDataType) {
|
||||
Msg.showError(this, tool.getToolFrame(), "Retype Failed",
|
||||
|
@ -913,8 +913,8 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup from specified ordinal to the first component which contains the specified offset.
|
||||
* @param index defined component index
|
||||
* Backup from specified defined-component index to the first component which contains the specified offset.
|
||||
* @param index any defined component index which contains offset
|
||||
* @param offset offset within structure
|
||||
* @return index of first defined component containing specific offset.
|
||||
*/
|
||||
@ -933,8 +933,28 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance from specified ordinal to the last component which contains the specified offset.
|
||||
* @param index defined component index
|
||||
* Identify defined-component index of the first non-zero-length component which contains the specified offset.
|
||||
* If only zero-length components exist, the last zero-length component which contains the offset will be returned.
|
||||
* @param index any defined component index which contains offset
|
||||
* @param offset offset within structure
|
||||
* @return index of first defined component containing specific offset.
|
||||
*/
|
||||
private int indexOfFirstNonZeroLenComponentContainingOffset(int index, int offset) {
|
||||
index = backupToFirstComponentContainingOffset(index, offset);
|
||||
DataTypeComponentDB next = components.get(index);
|
||||
while (next.getLength() == 0 && index < (components.size() - 1)) {
|
||||
next = components.get(index + 1);
|
||||
if (!next.containsOffset(offset)) {
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance from specified defined-component index to the last component which contains the specified offset.
|
||||
* @param index any defined component index which contains offset
|
||||
* @param offset offset within structure
|
||||
* @return index of last defined component containing specific offset.
|
||||
*/
|
||||
@ -1070,9 +1090,12 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
if (index >= 0) {
|
||||
// return first matching defined component containing offset
|
||||
DataTypeComponent dtc = components.get(index);
|
||||
index = backupToFirstComponentContainingOffset(index, offset);
|
||||
index = indexOfFirstNonZeroLenComponentContainingOffset(index, offset);
|
||||
dtc = components.get(index);
|
||||
return dtc;
|
||||
if (dtc.getLength() != 0) {
|
||||
return dtc;
|
||||
}
|
||||
index = -index - 1;
|
||||
}
|
||||
|
||||
if (offset != structLength && !isPackingEnabled()) {
|
||||
|
@ -116,10 +116,11 @@ public abstract class DynamicDataType extends BuiltIn implements Dynamic {
|
||||
* to share the same offset.
|
||||
* @param offset the offset into the dataType
|
||||
* @param buf the memory buffer containing the bytes.
|
||||
* @return the component containing the byte at the given offset or null if no
|
||||
* component defined.
|
||||
* @return the first component containing the byte at the given offset or null if no
|
||||
* component defined. A zero-length component may be returned.
|
||||
*/
|
||||
public final DataTypeComponent getComponentAt(int offset, MemBuffer buf) {
|
||||
// TODO: This interface should be consistent with Structure
|
||||
DataTypeComponent[] comps = getComps(buf);
|
||||
if (comps == null) {
|
||||
return null;
|
||||
|
@ -44,48 +44,71 @@ public interface Structure extends Composite {
|
||||
public DataTypeComponent getComponent(int ordinal) throws IndexOutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Gets the first immediate child component located at or after the given offset.
|
||||
* Gets the first defined component located at or after the specified offset.
|
||||
* Note: The returned component may be a zero-length component.
|
||||
*
|
||||
* @param offset the byte offset into this structure
|
||||
* @return the immediate child component located at or after the given offset or null if not found.
|
||||
* @return the first defined component located at or after the specified offset or null if not found.
|
||||
*/
|
||||
public DataTypeComponent getDefinedComponentAtOrAfterOffset(int offset);
|
||||
|
||||
/**
|
||||
* Gets the first immediate child component that contains the byte at the given offset.
|
||||
* Gets the first non-zero-length component that contains the byte at the specified offset.
|
||||
* Note that one or more components may share the same offset when a bit-field or zero-length
|
||||
* component is present since these may share an offset.
|
||||
* component is present since these may share an offset. A null may be returned under one of
|
||||
* the following conditions:
|
||||
* <ul>
|
||||
* <li>offset only corresponds to a zero-length component</li>
|
||||
* <li>offset corresponds to a padding byte within a packed structure</li>
|
||||
* <li>offset is >= structure length.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param offset the byte offset into this structure
|
||||
* @return the first immediate child component containing offset or null if not found.
|
||||
* @return the first non-zero-length component that contains the byte at the specified offset
|
||||
* or null if not found.
|
||||
*/
|
||||
public DataTypeComponent getComponentContaining(int offset);
|
||||
|
||||
/**
|
||||
* Gets the first immediate defined child component that contains the byte at the given offset.
|
||||
* Gets the first non-zero-length child component that starts at the specified offset.
|
||||
* Note that one or more components may share the same offset when a bit-field or zero-length
|
||||
* component is present since these may share an offset.
|
||||
* component is present since these may share an offset. A null may be returned under one of
|
||||
* the following conditions:
|
||||
* <ul>
|
||||
* <li>offset only corresponds to a zero-length component</li>
|
||||
* <li>offset corresponds to a padding byte within a packed structure</li>
|
||||
* <li>offset corresponds to a component but is not the starting offset of that component</li>
|
||||
* <li>offset is >= structure length</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param offset the byte offset into this structure
|
||||
* @return the first immediate child component containing offset or null if not found.
|
||||
* @deprecated method name has been changed to better reflect behavior. The method
|
||||
* {@link #getComponentContaining(int)} should be used instead. When switching over
|
||||
* it may be a could time to verify that the caller can handle the possibility of multiple
|
||||
* components containing the specified offset due to the possible presence of zero-length
|
||||
* components, such as zero-element arrays, or bit-fields which can overlap at the
|
||||
* byte-level.
|
||||
* @return the first component that starts at specified offset or null if not found.
|
||||
*/
|
||||
public default DataTypeComponent getComponentAt(int offset) {
|
||||
return getComponentContaining(offset);
|
||||
DataTypeComponent dtc = getComponentContaining(offset);
|
||||
if (dtc != null && dtc.getOffset() == offset) {
|
||||
return dtc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an ordered list of immediate child components that contain the byte at the given offset.
|
||||
* Note that this will only return more than one component when a bit-field or zero-length
|
||||
* component is present since these may share an offset.
|
||||
* Get an ordered list of components that contain the byte at the specified offset.
|
||||
* Unlike {@link #getComponentAt(int)} and {@link #getComponentContaining(int)} this method will
|
||||
* include zero-length components if they exist at the specified offset. For this reason the
|
||||
* specified offset may equal the structure length to obtain and trailing zero-length components.
|
||||
* Note that this method will only return more than one component when a bit-fields and/or
|
||||
* zero-length components are present since these may share an offset. An empty list may be
|
||||
* returned under the following conditions:
|
||||
* <ul>
|
||||
* <li>offset corresponds to a padding byte within a packed structure</li>
|
||||
* <li>offset corresponds to a component but is not the starting offset of that component</li>
|
||||
* <li>offset is equal structure length and no trailing zero-length components exist</li>
|
||||
* <li>offset is > structure length</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param offset the byte offset into this structure
|
||||
* @return a list of zero or more child components containing the specified offset
|
||||
* @return a list of zero or more components containing the specified offset
|
||||
*/
|
||||
public List<DataTypeComponent> getComponentsContaining(int offset);
|
||||
|
||||
@ -256,7 +279,7 @@ public interface Structure extends Composite {
|
||||
* components may be cleared. This method will preserve the structure length and placement
|
||||
* of other components since freed space will appear as undefined components.
|
||||
* <p>
|
||||
* To avoid clearing zero-length components at a given offset within a non-packed structure,
|
||||
* To avoid clearing zero-length components at a specified offset within a non-packed structure,
|
||||
* the {@link #replaceAtOffset(int, DataType, int, String, String)} may be used with to clear
|
||||
* only the sized component at the offset by specified {@link DataType#DEFAULT} as the replacement
|
||||
* datatype.
|
||||
@ -266,7 +289,7 @@ public interface Structure extends Composite {
|
||||
public void clearAtOffset(int offset);
|
||||
|
||||
/**
|
||||
* Clears the defined component at the given component ordinal. Clearing a component within
|
||||
* Clears the defined component at the specified component ordinal. Clearing a component within
|
||||
* a non-packed structure causes a defined component to be replaced with a number of undefined
|
||||
* components. This may not the case when clearing a zero-length component or bit-field
|
||||
* which may not result in such undefined components. In the case of a packed structure
|
||||
@ -397,7 +420,7 @@ public interface Structure extends Composite {
|
||||
String comment) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Increases the size of the structure by the given amount by adding undefined filler at the
|
||||
* Increases the size of the structure by the specified 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.
|
||||
|
@ -179,9 +179,12 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
if (index >= 0) {
|
||||
// return first matching defined component containing offset
|
||||
DataTypeComponent dtc = components.get(index);
|
||||
index = backupToFirstComponentContainingOffset(index, offset);
|
||||
index = indexOfFirstNonZeroLenComponentContainingOffset(index, offset);
|
||||
dtc = components.get(index);
|
||||
return dtc;
|
||||
if (dtc.getLength() != 0) {
|
||||
return dtc;
|
||||
}
|
||||
index = -index - 1;
|
||||
}
|
||||
|
||||
if (offset != structLength && !isPackingEnabled()) {
|
||||
@ -828,8 +831,8 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
}
|
||||
|
||||
/**
|
||||
* Backup from specified ordinal to the first component which contains the specified offset.
|
||||
* @param index component ordinal
|
||||
* Backup from specified defined-component index to the first component which contains the specified offset.
|
||||
* @param index any defined component index which contains offset
|
||||
* @param offset offset within structure
|
||||
* @return index of first defined component containing specific offset.
|
||||
*/
|
||||
@ -848,8 +851,28 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance from specified ordinal to the last component which contains the specified offset.
|
||||
* @param index defined component index
|
||||
* Identify defined-component index of the first non-zero-length component which contains the specified offset.
|
||||
* If only zero-length components exist, the last zero-length component which contains the offset will be returned.
|
||||
* @param index any defined component index which contains offset
|
||||
* @param offset offset within structure
|
||||
* @return index of first defined component containing specific offset.
|
||||
*/
|
||||
private int indexOfFirstNonZeroLenComponentContainingOffset(int index, int offset) {
|
||||
index = backupToFirstComponentContainingOffset(index, offset);
|
||||
DataTypeComponentImpl next = components.get(index);
|
||||
while (next.getLength() == 0 && index < (components.size() - 1)) {
|
||||
next = components.get(index + 1);
|
||||
if (!next.containsOffset(offset)) {
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance from specified defined-component index to the last component which contains the specified offset.
|
||||
* @param index any defined component index which contains offset
|
||||
* @param offset offset within structure
|
||||
* @return index of last defined component containing specific offset.
|
||||
*/
|
||||
|
@ -1753,12 +1753,159 @@ public class StructureDBTest extends AbstractGTest {
|
||||
assertEquals(0, s.getNumComponents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentAt() {
|
||||
/**
|
||||
* /TestStruct
|
||||
* pack(disabled)
|
||||
* Structure TestStruct {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 1 word 2 null "Comment2"
|
||||
* 3 dword 4 field3 ""
|
||||
* 7 byte 1 field4 "Comment4"
|
||||
* }
|
||||
* Size = 8 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
DataTypeComponent dtc = struct.getComponentAt(3);
|
||||
assertEquals(" 2 3 dword 4 field3 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentAt(4); // offcut
|
||||
assertNull(dtc);
|
||||
|
||||
assertEquals(8, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentAt(8);
|
||||
assertNull(dtc);
|
||||
|
||||
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), "zarray1", null);
|
||||
struct.add(new LongDataType(), "field4", null);
|
||||
struct.add(new ArrayDataType(LongDataType.dataType, 0, -1), "zarray2", null);
|
||||
|
||||
assertEquals(12, struct.getLength());
|
||||
|
||||
/**
|
||||
* /TestStruct
|
||||
* pack(disabled)
|
||||
* Structure TestStruct {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 1 word 2 null "Comment2"
|
||||
* 3 dword 4 field3 ""
|
||||
* 7 byte 1 field4 "Comment4"
|
||||
* 8 char[0] 0 zarray1 ""
|
||||
* 8 long 4 field4 ""
|
||||
* 12 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 12 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
dtc = struct.getComponentAt(8);
|
||||
assertEquals(" 5 8 long 4 field4 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentAt(9); // offcut
|
||||
assertNull(dtc);
|
||||
|
||||
dtc = struct.getComponentAt(12); // end-of-struct
|
||||
assertNull(dtc);
|
||||
|
||||
// force components to align
|
||||
struct.setPackingEnabled(true);
|
||||
|
||||
/**
|
||||
* /Test
|
||||
* pack(disabled)
|
||||
* Structure Test {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 2 word 2 null "Comment2"
|
||||
* 4 dword 4 field3 ""
|
||||
* 8 byte 1 field4 "Comment4"
|
||||
* 9 char[0] 0 zarray1 ""
|
||||
* 12 long 4 field4 ""
|
||||
* 16 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 16 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
assertEquals(16, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentAt(9); // offset of zero-length component
|
||||
assertNull(dtc);
|
||||
|
||||
struct.setPackingEnabled(false);
|
||||
|
||||
dtc = struct.getComponentAt(9); // undefined at offset of zero-length component
|
||||
assertEquals(" 5 9 undefined 1 null null", dtc.toString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentContaining() {
|
||||
DataTypeComponent dtc = struct.getComponentContaining(4);
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals(3, dtc.getOffset());
|
||||
assertEquals(" 2 3 dword 4 field3 null", dtc.toString());
|
||||
|
||||
assertEquals(8, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentContaining(8);
|
||||
assertNull(dtc);
|
||||
|
||||
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), "zarray1", null);
|
||||
struct.add(new LongDataType(), "field4", null);
|
||||
struct.add(new ArrayDataType(LongDataType.dataType, 0, -1), "zarray2", null);
|
||||
|
||||
assertEquals(12, struct.getLength());
|
||||
|
||||
/**
|
||||
* /TestStruct
|
||||
* pack(disabled)
|
||||
* Structure TestStruct {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 1 word 2 null "Comment2"
|
||||
* 3 dword 4 field3 ""
|
||||
* 7 byte 1 field4 "Comment4"
|
||||
* 8 char[0] 0 zarray1 ""
|
||||
* 8 long 4 field4 ""
|
||||
* 12 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 12 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
dtc = struct.getComponentContaining(8);
|
||||
assertEquals(" 5 8 long 4 field4 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentContaining(9); // offcut
|
||||
assertEquals(" 5 8 long 4 field4 null", dtc.toString());
|
||||
|
||||
dtc = struct.getComponentContaining(12); // end-of-struct
|
||||
assertNull(dtc);
|
||||
|
||||
// force components to align
|
||||
struct.setPackingEnabled(true);
|
||||
|
||||
/**
|
||||
* /Test
|
||||
* pack(disabled)
|
||||
* Structure Test {
|
||||
* 0 byte 1 field1 "Comment1"
|
||||
* 2 word 2 null "Comment2"
|
||||
* 4 dword 4 field3 ""
|
||||
* 8 byte 1 field4 "Comment4"
|
||||
* 9 char[0] 0 zarray1 ""
|
||||
* 12 long 4 field4 ""
|
||||
* 16 long[0] 0 zarray2 ""
|
||||
* }
|
||||
* Size = 16 Actual Alignment = 1
|
||||
*/
|
||||
|
||||
assertEquals(16, struct.getLength());
|
||||
|
||||
dtc = struct.getComponentContaining(9); // offset of zero-length component
|
||||
assertNull(dtc);
|
||||
|
||||
struct.setPackingEnabled(false);
|
||||
|
||||
dtc = struct.getComponentContaining(9); // undefined at offset of zero-length component
|
||||
assertEquals(" 5 9 undefined 1 null null", dtc.toString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -142,9 +142,9 @@ public class DataDBTest extends AbstractGenericTest {
|
||||
assertNotNull(c);
|
||||
assertEquals("c1", c.getComponentPathName());
|
||||
|
||||
Data c2 = c.getComponentContaining(4);
|
||||
Data c2 = c.getComponentContaining(4); // zero-length component is ignored
|
||||
assertNotNull(c2);
|
||||
assertEquals("c1.", c2.getComponentPathName()); // zero-bitfield has no name
|
||||
assertEquals("c1.bf1", c2.getComponentPathName());
|
||||
|
||||
Data c3 = c.getComponentContaining(5);
|
||||
assertNotNull(c3);
|
||||
|
Loading…
Reference in New Issue
Block a user