Corrected test issues and refined datatype conflict handling

This commit is contained in:
ghidra1 2020-06-04 11:33:33 -04:00
parent 76925e6342
commit 7f09488133
12 changed files with 202 additions and 183 deletions

View file

@ -626,7 +626,7 @@ public class DataTypesXmlMgr {
attrs.addAttribute("SIZE", struct.isNotYetDefined() ? 0 : struct.getLength(), true); attrs.addAttribute("SIZE", struct.isNotYetDefined() ? 0 : struct.getLength(), true);
writer.startElement("STRUCTURE", attrs); writer.startElement("STRUCTURE", attrs);
writeRegularComment(writer, struct.getDescription()); writeRegularComment(writer, struct.getDescription());
DataTypeComponent[] members = struct.getDefinedComponents(); DataTypeComponent[] members = struct.getComponents();
for (DataTypeComponent member : members) { for (DataTypeComponent member : members) {
writerMember(writer, member); writerMember(writer, member);
} }

View file

@ -701,17 +701,17 @@ public class CategoryTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue(dt.isEquivalent(ev.dt)); assertTrue(dt.isEquivalent(ev.dt));
assertEquals(null, ev.parent); assertEquals(null, ev.parent);
ev = getEvent(4); // ev = getEvent(4); // eliminated size change event during creation
assertEquals("DT Changed", ev.evName); // assertEquals("DT Changed", ev.evName);
assertTrue(dt.isEquivalent(ev.dt)); // assertTrue(dt.isEquivalent(ev.dt));
assertEquals(null, ev.parent); // assertEquals(null, ev.parent);
ev = getEvent(5); ev = getEvent(4);
assertEquals("DT Added", ev.evName); assertEquals("DT Added", ev.evName);
assertTrue(dt.isEquivalent(ev.dt)); assertTrue(dt.isEquivalent(ev.dt));
assertEquals(sub1.getCategoryPath(), ev.parent); assertEquals(sub1.getCategoryPath(), ev.parent);
assertEquals(6, getEventCount()); assertEquals(5, getEventCount());
} }
@ -803,8 +803,8 @@ public class CategoryTest extends AbstractGhidraHeadedIntegrationTest {
struct2 = (Structure) newDt.insert(3, struct2).getDataType(); struct2 = (Structure) newDt.insert(3, struct2).getDataType();
assertEquals(5, getEventCount()); assertEquals(4, getEventCount());
Event ev = getEvent(4); Event ev = getEvent(3);
assertEquals("DT Changed", ev.evName); assertEquals("DT Changed", ev.evName);
assertEquals(newDt, ev.dt); assertEquals(newDt, ev.dt);
} }

View file

@ -129,19 +129,19 @@ public class DataTypeTest extends AbstractGhidraHeadedIntegrationTest {
Structure struct2 = createStruct("abc", resolvedStruct1, 1); Structure struct2 = createStruct("abc", resolvedStruct1, 1);
// ideally, this would throw some kind of cyclic dependency exception, but would be // Replacement type refers to existing type preventing existing type from being removed
// a lot of work to do that because by the time it detects the cycle, it may have // Resolve reverts to default add behavior producing a conflict name
// already performed some replacements. So the entire resolve would have to be done // Uncertain if a dependency exception should be thrown instead
// in some kind of "dry run" mode first. For now, it just replaces the cyclic reference with
// an undefined datatype.
DataType resolvedStruct2 = dtm.resolve(struct2, DataTypeConflictHandler.REPLACE_HANDLER); DataType resolvedStruct2 = dtm.resolve(struct2, DataTypeConflictHandler.REPLACE_HANDLER);
assertEquals("abc", struct1.getName()); assertEquals("abc", struct1.getName());
assertEquals("abc", struct2.getName()); assertEquals("abc", struct2.getName());
assertEquals("abc", resolvedStruct2.getName()); assertEquals("abc.conflict", resolvedStruct2.getName());
assertEquals(DataType.DEFAULT,
((Structure) resolvedStruct2).getDataTypeAt(0).getDataType()); assertTrue(
resolvedStruct1.equals(((Structure) resolvedStruct2).getComponentAt(0).getDataType()));
program.endTransaction(txId, true); program.endTransaction(txId, true);

View file

@ -674,7 +674,7 @@ public class HTMLDataTypeRepresentationTest extends AbstractGenericTest {
HTMLDataTypeRepresentation[] diff = r1.diff(r2); HTMLDataTypeRepresentation[] diff = r1.diff(r2);
showDiffs(diff[0], diff[1]); showDiffs(diff[0], diff[1]);
assertOnlyTypeDefBodiesDifferent(diff); assertTypeDefHeaderAndBodiesDifferent(diff);
} }
@Test @Test
@ -695,7 +695,7 @@ public class HTMLDataTypeRepresentationTest extends AbstractGenericTest {
HTMLDataTypeRepresentation[] diff = r1.diff(r2); HTMLDataTypeRepresentation[] diff = r1.diff(r2);
showDiffs(diff[0], diff[1]); showDiffs(diff[0], diff[1]);
assertOnlyTypeDefBodySizeDifferent(diff); assertOnlyHeaderAndTypeDefBodySizeDifferent(diff);
} }
@Test @Test
@ -807,13 +807,13 @@ public class HTMLDataTypeRepresentationTest extends AbstractGenericTest {
// Private Methods // Private Methods
//================================================================================================== //==================================================================================================
private void assertOnlyTypeDefBodySizeDifferent(HTMLDataTypeRepresentation[] diff) { private void assertOnlyHeaderAndTypeDefBodySizeDifferent(HTMLDataTypeRepresentation[] diff) {
TypeDefDataTypeHTMLRepresentation td1 = (TypeDefDataTypeHTMLRepresentation) diff[0]; TypeDefDataTypeHTMLRepresentation td1 = (TypeDefDataTypeHTMLRepresentation) diff[0];
TypeDefDataTypeHTMLRepresentation td2 = (TypeDefDataTypeHTMLRepresentation) diff[1]; TypeDefDataTypeHTMLRepresentation td2 = (TypeDefDataTypeHTMLRepresentation) diff[1];
List<ValidatableLine> h1 = td1.headerContent; List<ValidatableLine> h1 = td1.headerContent;
List<ValidatableLine> h2 = td2.headerContent; List<ValidatableLine> h2 = td2.headerContent;
assertEquals("TypeDef diff should have same headers", h1, h2); Assert.assertNotEquals("TypeDef diff should have different headers", h1, h2);
List<ValidatableLine> b1 = td1.bodyContent; List<ValidatableLine> b1 = td1.bodyContent;
List<ValidatableLine> b2 = td2.bodyContent; List<ValidatableLine> b2 = td2.bodyContent;
@ -861,11 +861,24 @@ public class HTMLDataTypeRepresentationTest extends AbstractGenericTest {
List<ValidatableLine> h1 = td1.headerContent; List<ValidatableLine> h1 = td1.headerContent;
List<ValidatableLine> h2 = td2.headerContent; List<ValidatableLine> h2 = td2.headerContent;
assertEquals("TypeDef diff should not have different headers", h1, h2); assertEquals("TypeDef diff should have same headers", h1, h2);
List<ValidatableLine> b1 = td1.bodyContent; List<ValidatableLine> b1 = td1.bodyContent;
List<ValidatableLine> b2 = td2.bodyContent; List<ValidatableLine> b2 = td2.bodyContent;
Assert.assertNotEquals("TypeDef diff should not have the same bodies", b1, b2); Assert.assertNotEquals("TypeDef diff should have different bodies", b1, b2);
}
private void assertTypeDefHeaderAndBodiesDifferent(HTMLDataTypeRepresentation[] diff) {
TypeDefDataTypeHTMLRepresentation td1 = (TypeDefDataTypeHTMLRepresentation) diff[0];
TypeDefDataTypeHTMLRepresentation td2 = (TypeDefDataTypeHTMLRepresentation) diff[1];
List<ValidatableLine> h1 = td1.headerContent;
List<ValidatableLine> h2 = td2.headerContent;
Assert.assertNotEquals("TypeDef diff should have different headers", h1, h2);
List<ValidatableLine> b1 = td1.bodyContent;
List<ValidatableLine> b2 = td2.bodyContent;
Assert.assertNotEquals("TypeDef diff should have different bodies", b1, b2);
} }
private void assertCompositeHeaderDiffers_AtIndex( private void assertCompositeHeaderDiffers_AtIndex(

View file

@ -427,9 +427,9 @@ public class StructureDataTypeTest extends AbstractGTest {
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 8 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 undefined 1 null \"\"\n" + // " 10 undefined 1 null \"\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -446,9 +446,9 @@ public class StructureDataTypeTest extends AbstractGTest {
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 8 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 8 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 8 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 undefined 1 null \"\"\n" + // " 10 undefined 1 null \"\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -467,12 +467,12 @@ public class StructureDataTypeTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 10 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" 12 undefined 1 null \"\"\n" + // " 12 undefined 1 null \"\"\n" +
" 13 undefined 1 null \"\"\n" + // " 13 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 14 Actual Alignment = 1", struct); "Size = 14 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -487,13 +487,13 @@ public class StructureDataTypeTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 10 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 10 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 10 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" 12 undefined 1 null \"\"\n" + // " 12 undefined 1 null \"\"\n" +
" 13 undefined 1 null \"\"\n" + // " 13 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 14 Actual Alignment = 1", struct); "Size = 14 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -509,11 +509,11 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -528,12 +528,12 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -548,11 +548,11 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -576,7 +576,7 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
@ -610,11 +610,11 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -629,12 +629,12 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -649,11 +649,11 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(3) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(3) 3 bf3 \"bf3Comment\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -668,7 +668,7 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(3) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(3) 3 bf3 \"bf3Comment\"\n" +
@ -696,7 +696,7 @@ public class StructureDataTypeTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure TestStruct {\n" + "Structure TestStruct {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 float 4 null \"\"\n" + " 2 float 4 null \"\"\n" +
" 6 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 6 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 6 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 6 int:3(3) 1 bf2 \"bf2Comment\"\n" +
@ -1150,11 +1150,11 @@ public class StructureDataTypeTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" + " 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" +
" 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" + " 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" +
" 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" + " 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" Foo[0] 0 myFlex \"flexComment\"\n" + " Foo[0] 0 myFlex \"flexComment\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
@ -1175,11 +1175,11 @@ public class StructureDataTypeTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" + " 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" +
" 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" + " 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" +
" 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" + " 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" Foo[0] 0 myFlex \"flexComment\"\n" + " Foo[0] 0 myFlex \"flexComment\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", newStruct); "Size = 12 Actual Alignment = 1", newStruct);

View file

@ -268,7 +268,7 @@ abstract class DataTypeDB extends DatabaseObject implements DataType, ChangeList
} }
protected DataType resolve(DataType dt) { protected DataType resolve(DataType dt) {
return resolve(dt, dataMgr.getCurrentConflictHandler()); return resolve(dt, dataMgr.getDependencyConflictHandler());
} }
protected DataType resolve(DataType dt, DataTypeConflictHandler handler) { protected DataType resolve(DataType dt, DataTypeConflictHandler handler) {

View file

@ -812,7 +812,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
finally { finally {
if (isResolveCacheOwner) { if (isResolveCacheOwner) {
flushResolveCacheAndClearQueue(handler); flushResolveCacheAndClearQueue();
} }
if (isEquivalenceCacheOwner) { if (isEquivalenceCacheOwner) {
clearEquivalenceCache(); clearEquivalenceCache();
@ -909,7 +909,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
case REPLACE_EXISTING: // new type replaces old conflicted type case REPLACE_EXISTING: // new type replaces old conflicted type
try { try {
if (updateExistingDataType(existingDataType, dataType, handler)) { if (updateExistingDataType(existingDataType, dataType)) {
return existingDataType; return existingDataType;
} }
renameToUnusedConflictName(existingDataType); renameToUnusedConflictName(existingDataType);
@ -919,12 +919,14 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
replace(existingDataType, newDataType); replace(existingDataType, newDataType);
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
throw new AssertException(e); throw new IllegalArgumentException(
"Invalid datatype replacement: " + newDataType.getName(), e);
} }
return newDataType; return newDataType;
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
// fallthrough to RENAME_AND_ADD // new type refers to old type - fallthrough to RENAME_AND_ADD
// TODO: alternatively we could throw an exception
} }
case RENAME_AND_ADD: // default handler behavior case RENAME_AND_ADD: // default handler behavior
@ -970,13 +972,12 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
* *
* @param existingDataType existing datatype * @param existingDataType existing datatype
* @param dataType new datatype * @param dataType new datatype
* @param handler conflict handler
* @return true if replacment approach was successful, else false * @return true if replacment approach was successful, else false
* @throws DataTypeDependencyException if datatype contains dependency issues * @throws DataTypeDependencyException if datatype contains dependency issues
* during resolve process * during resolve process
*/ */
private boolean updateExistingDataType(DataType existingDataType, DataType dataType, private boolean updateExistingDataType(DataType existingDataType, DataType dataType)
DataTypeConflictHandler handler) throws DataTypeDependencyException { throws DataTypeDependencyException {
// TODO: this approach could be added to other DB datatypes to avoid // TODO: this approach could be added to other DB datatypes to avoid
// unnececesary creation and removal. // unnececesary creation and removal.
@ -987,7 +988,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
return false; return false;
} }
StructureDB existingStruct = (StructureDB) existingDataType; StructureDB existingStruct = (StructureDB) existingDataType;
existingStruct.doReplaceWith((Structure) dataType, true, handler); existingStruct.doReplaceWith((Structure) dataType, true);
return true; return true;
} }
else if (existingDataType instanceof UnionDB) { else if (existingDataType instanceof UnionDB) {
@ -995,7 +996,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
return false; return false;
} }
UnionDB existingUnion = (UnionDB) existingDataType; UnionDB existingUnion = (UnionDB) existingDataType;
existingUnion.doReplaceWith((Union) dataType, true, handler); existingUnion.doReplaceWith((Union) dataType, true);
return true; return true;
} }
} }
@ -1149,7 +1150,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
finally { finally {
if (isResolveCacheOwner) { if (isResolveCacheOwner) {
flushResolveCacheAndClearQueue(handler); flushResolveCacheAndClearQueue();
} }
if (isEquivalenceCacheOwner) { if (isEquivalenceCacheOwner) {
clearEquivalenceCache(); clearEquivalenceCache();
@ -1504,12 +1505,16 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
/** /**
* Get the current active datatype conflict handler * Get the datatype conflict handler to be used when resolving
* datatype dependencies
* *
* @return current active datatype conflict handler * @return dependency datatype conflict handler
*/ */
DataTypeConflictHandler getCurrentConflictHandler() { DataTypeConflictHandler getDependencyConflictHandler() {
return currentHandler; if (currentHandler == null) {
return DataTypeConflictHandler.DEFAULT_HANDLER;
}
return currentHandler.getSubsequentHandler();
} }
@Override @Override
@ -2273,17 +2278,17 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
else if (dt instanceof Structure) { else if (dt instanceof Structure) {
Structure structure = (Structure) dt; Structure structure = (Structure) dt;
newDataType = createStructure(structure, name, cat, sourceArchiveIdValue, newDataType = createStructure(structure, name, cat, sourceArchiveIdValue,
id.getValue(), handler); id.getValue());
} }
else if (dt instanceof TypeDef) { else if (dt instanceof TypeDef) {
TypeDef typedef = (TypeDef) dt; TypeDef typedef = (TypeDef) dt;
newDataType = newDataType =
createTypeDef(typedef, name, cat, sourceArchiveIdValue, id.getValue(), handler); createTypeDef(typedef, name, cat, sourceArchiveIdValue, id.getValue());
} }
else if (dt instanceof Union) { else if (dt instanceof Union) {
Union union = (Union) dt; Union union = (Union) dt;
newDataType = newDataType =
createUnion(union, name, cat, sourceArchiveIdValue, id.getValue(), handler); createUnion(union, name, cat, sourceArchiveIdValue, id.getValue());
} }
else if (dt instanceof Enum) { else if (dt instanceof Enum) {
Enum enumm = (Enum) dt; Enum enumm = (Enum) dt;
@ -2292,7 +2297,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
else if (dt instanceof FunctionDefinition) { else if (dt instanceof FunctionDefinition) {
FunctionDefinition funDef = (FunctionDefinition) dt; FunctionDefinition funDef = (FunctionDefinition) dt;
newDataType = createFunctionDefinition(funDef, name, cat, sourceArchiveIdValue, newDataType = createFunctionDefinition(funDef, name, cat, sourceArchiveIdValue,
id.getValue(), handler); id.getValue());
} }
else if (dt instanceof BuiltInDataType) { else if (dt instanceof BuiltInDataType) {
BuiltInDataType builtInDataType = (BuiltInDataType) dt; BuiltInDataType builtInDataType = (BuiltInDataType) dt;
@ -2316,7 +2321,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
private Structure createStructure(Structure struct, String name, CategoryDB category, private Structure createStructure(Structure struct, String name, CategoryDB category,
long sourceArchiveIdValue, long universalIdValue, DataTypeConflictHandler handler) long sourceArchiveIdValue, long universalIdValue)
throws IOException { throws IOException {
try { try {
if (name == null || name.length() == 0) { if (name == null || name.length() == 0) {
@ -2338,7 +2343,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
// Make sure category knows about structure before replace is performed // Make sure category knows about structure before replace is performed
category.dataTypeAdded(structDB); category.dataTypeAdded(structDB);
structDB.doReplaceWith(struct, false, handler); structDB.doReplaceWith(struct, false);
structDB.setDescription(struct.getDescription()); structDB.setDescription(struct.getDescription());
// structDB.notifySizeChanged(); // structDB.notifySizeChanged();
// doReplaceWith updated the last change time so set it back to what we want. // doReplaceWith updated the last change time so set it back to what we want.
@ -2347,7 +2352,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
return structDB; return structDB;
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
throw new AssertException(e); // unexpected for new type throw new IllegalArgumentException("Invalid structure: " + struct.getName(), e);
} }
finally { finally {
creatingDataType--; creatingDataType--;
@ -2386,12 +2391,12 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
private TypeDef createTypeDef(TypeDef typedef, String name, Category cat, private TypeDef createTypeDef(TypeDef typedef, String name, Category cat,
long sourceArchiveIdValue, long universalIdValue, DataTypeConflictHandler handler) long sourceArchiveIdValue, long universalIdValue)
throws IOException { throws IOException {
if (name == null || name.length() == 0) { if (name == null || name.length() == 0) {
throw new IllegalArgumentException("Data type must have a valid name"); throw new IllegalArgumentException("Data type must have a valid name");
} }
DataType dataType = resolve(typedef.getDataType(), handler); DataType dataType = resolve(typedef.getDataType(), getDependencyConflictHandler());
Record record = typedefAdapter.createRecord(getID(dataType), name, cat.getID(), Record record = typedefAdapter.createRecord(getID(dataType), name, cat.getID(),
sourceArchiveIdValue, universalIdValue, typedef.getLastChangeTime()); sourceArchiveIdValue, universalIdValue, typedef.getLastChangeTime());
TypedefDB typedefDB = new TypedefDB(this, dtCache, typedefAdapter, record); TypedefDB typedefDB = new TypedefDB(this, dtCache, typedefAdapter, record);
@ -2401,7 +2406,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
private Union createUnion(Union union, String name, CategoryDB category, private Union createUnion(Union union, String name, CategoryDB category,
long sourceArchiveIdValue, long universalIdValue, DataTypeConflictHandler handler) long sourceArchiveIdValue, long universalIdValue)
throws IOException { throws IOException {
if (name == null || name.length() == 0) { if (name == null || name.length() == 0) {
throw new IllegalArgumentException("Data type must have a valid name"); throw new IllegalArgumentException("Data type must have a valid name");
@ -2417,7 +2422,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
// Make sure category knows about union before replace is performed // Make sure category knows about union before replace is performed
category.dataTypeAdded(unionDB); category.dataTypeAdded(unionDB);
unionDB.doReplaceWith(union, false, handler); unionDB.doReplaceWith(union, false);
unionDB.setDescription(union.getDescription()); unionDB.setDescription(union.getDescription());
// unionDB.notifySizeChanged(); // unionDB.notifySizeChanged();
// doReplaceWith updated the last change time so set it back to what we want. // doReplaceWith updated the last change time so set it back to what we want.
@ -2426,7 +2431,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
return unionDB; return unionDB;
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
throw new AssertException(e); // unexpected for new type throw new IllegalArgumentException("Invalid union: " + union.getName(), e);
} }
finally { finally {
creatingDataType--; creatingDataType--;
@ -2658,8 +2663,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
private FunctionDefinition createFunctionDefinition(FunctionDefinition funDef, String name, private FunctionDefinition createFunctionDefinition(FunctionDefinition funDef, String name,
CategoryDB cat, long sourceArchiveIdValue, long universalIdValue, CategoryDB cat, long sourceArchiveIdValue, long universalIdValue) throws IOException {
DataTypeConflictHandler handler) throws IOException {
if (name == null || name.length() == 0) { if (name == null || name.length() == 0) {
throw new IllegalArgumentException("Data type must have a valid name"); throw new IllegalArgumentException("Data type must have a valid name");
} }
@ -3750,7 +3754,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
replace(dataType, resolve(builtIn, null)); replace(dataType, resolve(builtIn, null));
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
throw new AssertException("Got DataTypeDependencyException on built in"); throw new AssertException("Got DataTypeDependencyException on built in", e);
} }
} }
} }
@ -3787,7 +3791,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
resolveQueue.add(new ResolvePair(resolvedDt, definitionDt)); resolveQueue.add(new ResolvePair(resolvedDt, definitionDt));
} }
void flushResolveCacheAndClearQueue(DataTypeConflictHandler handler) { void flushResolveCacheAndClearQueue() {
DataTypeConflictHandler handler = getDependencyConflictHandler();
while (!resolveQueue.isEmpty()) { while (!resolveQueue.isEmpty()) {
ResolvePair resolvePair = resolveQueue.pollFirst(); ResolvePair resolvePair = resolveQueue.pollFirst();
DataTypeDB resolvedDt = resolvePair.resolvedDt; DataTypeDB resolvedDt = resolvePair.resolvedDt;

View file

@ -260,7 +260,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
DataType type = DataType type =
ParameterDefinitionImpl.validateDataType(args[i].getDataType(), dataMgr, false); ParameterDefinitionImpl.validateDataType(args[i].getDataType(), dataMgr, false);
DataType resolvedDt = resolve(type, dataMgr.getCurrentConflictHandler()); DataType resolvedDt = resolve(type, dataMgr.getDependencyConflictHandler());
paramAdapter.createRecord(dataMgr.getID(resolvedDt), key, i, args[i].getName(), paramAdapter.createRecord(dataMgr.getID(resolvedDt), key, i, args[i].getName(),
args[i].getComment(), args[i].getLength()); args[i].getComment(), args[i].getLength());
resolvedDt.addParent(this); resolvedDt.addParent(this);
@ -287,7 +287,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
if (type == null) { if (type == null) {
type = DataType.DEFAULT; type = DataType.DEFAULT;
} }
DataType resolvedDt = resolve(type, dataMgr.getCurrentConflictHandler()); DataType resolvedDt = resolve(type, dataMgr.getDependencyConflictHandler());
record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL, record.setLongValue(FunctionDefinitionDBAdapter.FUNCTION_DEF_RETURN_ID_COL,
dataMgr.getID(resolvedDt)); dataMgr.getID(resolvedDt));
funDefAdapter.updateRecord(record, true); funDefAdapter.updateRecord(record, true);
@ -472,7 +472,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
param.getDataType().removeParent(this); param.getDataType().removeParent(this);
paramAdapter.removeRecord(param.getKey()); paramAdapter.removeRecord(param.getKey());
} }
DataType rdt = resolve(dt, dataMgr.getCurrentConflictHandler()); DataType rdt = resolve(dt, dataMgr.getDependencyConflictHandler());
rdt.addParent(this); rdt.addParent(this);
paramAdapter.createRecord(dataMgr.getID(rdt), key, ordinal, name, comment, paramAdapter.createRecord(dataMgr.getID(rdt), key, ordinal, name, comment,
dt.getLength()); dt.getLength());

View file

@ -1158,7 +1158,7 @@ class StructureDB extends CompositeDB implements Structure {
boolean isResolveCacheOwner = dataMgr.activateResolveCache(); boolean isResolveCacheOwner = dataMgr.activateResolveCache();
try { try {
checkDeleted(); checkDeleted();
doReplaceWith((Structure) dataType, true, dataMgr.getCurrentConflictHandler()); doReplaceWith((Structure) dataType, true);
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
throw new IllegalArgumentException(e.getMessage(), e); throw new IllegalArgumentException(e.getMessage(), e);
@ -1168,7 +1168,7 @@ class StructureDB extends CompositeDB implements Structure {
} }
finally { finally {
if (isResolveCacheOwner) { if (isResolveCacheOwner) {
dataMgr.flushResolveCacheAndClearQueue(null); dataMgr.flushResolveCacheAndClearQueue();
} }
lock.release(); lock.release();
} }
@ -1179,15 +1179,16 @@ class StructureDB extends CompositeDB implements Structure {
* *
* @param struct * @param struct
* @param notify * @param notify
* @param handler
* @return true if fully completed else false if pointer component post resolve * @return true if fully completed else false if pointer component post resolve
* required * required
* @throws DataTypeDependencyException * @throws DataTypeDependencyException
* @throws IOException * @throws IOException
*/ */
void doReplaceWith(Structure struct, boolean notify, DataTypeConflictHandler handler) void doReplaceWith(Structure struct, boolean notify)
throws DataTypeDependencyException, IOException { throws DataTypeDependencyException, IOException {
DataTypeConflictHandler handler = dataMgr.getDependencyConflictHandler();
// pre-resolved component types to catch dependency issues early // pre-resolved component types to catch dependency issues early
DataTypeComponent flexComponent = struct.getFlexibleArrayComponent(); DataTypeComponent flexComponent = struct.getFlexibleArrayComponent();
DataTypeComponent[] otherComponents = struct.getDefinedComponents(); DataTypeComponent[] otherComponents = struct.getDefinedComponents();

View file

@ -250,22 +250,24 @@ class UnionDB extends CompositeDB implements Union {
boolean isResolveCacheOwner = dataMgr.activateResolveCache(); boolean isResolveCacheOwner = dataMgr.activateResolveCache();
try { try {
checkDeleted(); checkDeleted();
doReplaceWith((Union) dataType, true, dataMgr.getCurrentConflictHandler()); doReplaceWith((Union) dataType, true);
} }
catch (DataTypeDependencyException e) { catch (DataTypeDependencyException e) {
throw new IllegalArgumentException(e.getMessage(), e); throw new IllegalArgumentException(e.getMessage(), e);
} }
finally { finally {
if (isResolveCacheOwner) { if (isResolveCacheOwner) {
dataMgr.flushResolveCacheAndClearQueue(null); dataMgr.flushResolveCacheAndClearQueue();
} }
lock.release(); lock.release();
} }
} }
void doReplaceWith(Union union, boolean notify, DataTypeConflictHandler handler) void doReplaceWith(Union union, boolean notify)
throws DataTypeDependencyException { throws DataTypeDependencyException {
DataTypeConflictHandler handler = dataMgr.getDependencyConflictHandler();
// pre-resolved component types to catch dependency issues early // pre-resolved component types to catch dependency issues early
DataTypeComponent[] otherComponents = union.getComponents(); DataTypeComponent[] otherComponents = union.getComponents();
DataType[] resolvedDts = new DataType[otherComponents.length]; DataType[] resolvedDts = new DataType[otherComponents.length];

View file

@ -15,8 +15,6 @@
*/ */
package ghidra.program.model.data; package ghidra.program.model.data;
import ghidra.util.Msg;
public abstract class DataTypeConflictHandler { public abstract class DataTypeConflictHandler {
/** /**
@ -62,10 +60,10 @@ public abstract class DataTypeConflictHandler {
public final static DataTypeConflictHandler DEFAULT_HANDLER = new DataTypeConflictHandler() { public final static DataTypeConflictHandler DEFAULT_HANDLER = new DataTypeConflictHandler() {
@Override @Override
public ConflictResult resolveConflict(DataType addedDataType, DataType existingDataType) { public ConflictResult resolveConflict(DataType addedDataType, DataType existingDataType) {
Msg.info(this, // Msg.info(this,
"Conflict with existing type " + existingDataType.getName() + "(" + // "Conflict with existing type " + existingDataType.getName() + "(" +
existingDataType.getDescription() + // existingDataType.getDescription() +
"), new type will be renamed with .conflict suffix"); // "), new type will be renamed with .conflict suffix");
return ConflictResult.RENAME_AND_ADD; return ConflictResult.RENAME_AND_ADD;
} }
@ -142,8 +140,8 @@ public abstract class DataTypeConflictHandler {
public final static DataTypeConflictHandler KEEP_HANDLER = new DataTypeConflictHandler() { public final static DataTypeConflictHandler KEEP_HANDLER = new DataTypeConflictHandler() {
@Override @Override
public ConflictResult resolveConflict(DataType addedDataType, DataType existingDataType) { public ConflictResult resolveConflict(DataType addedDataType, DataType existingDataType) {
Msg.info(this, "New type not added in favor of existing type " + // Msg.info(this, "New type not added in favor of existing type " +
existingDataType.getName() + "(" + existingDataType.getDescription() + ")"); // existingDataType.getName() + "(" + existingDataType.getDescription() + ")");
return ConflictResult.USE_EXISTING; return ConflictResult.USE_EXISTING;
} }

View file

@ -508,9 +508,9 @@ public class StructureDBTest extends AbstractGTest {
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 8 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 undefined 1 null \"\"\n" + // " 10 undefined 1 null \"\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -527,9 +527,9 @@ public class StructureDBTest extends AbstractGTest {
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 8 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 8 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 8 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 undefined 1 null \"\"\n" + // " 10 undefined 1 null \"\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -547,8 +547,8 @@ public class StructureDBTest extends AbstractGTest {
" 8 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 8 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 8 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 8 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 9 byte:3(0) 1 bf3 \"bf3Comment\"\n" + " 9 byte:3(0) 1 bf3 \"bf3Comment\"\n" +
" 10 undefined 1 null \"\"\n" + // " 10 undefined 1 null \"\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -567,12 +567,12 @@ public class StructureDBTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 10 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" 12 undefined 1 null \"\"\n" + // " 12 undefined 1 null \"\"\n" +
" 13 undefined 1 null \"\"\n" + // " 13 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 14 Actual Alignment = 1", struct); "Size = 14 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -587,13 +587,13 @@ public class StructureDBTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 10 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 10 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 10 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" 12 undefined 1 null \"\"\n" + // " 12 undefined 1 null \"\"\n" +
" 13 undefined 1 null \"\"\n" + // " 13 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 14 Actual Alignment = 1", struct); "Size = 14 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -609,11 +609,11 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -628,12 +628,12 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -648,11 +648,11 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -676,7 +676,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
@ -695,7 +695,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:0(0) 1 \"zero bitfield\"\n" + // field name discarded " 2 int:0(0) 1 \"zero bitfield\"\n" + // field name discarded
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
@ -730,11 +730,11 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -749,12 +749,12 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -769,11 +769,11 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(3) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(3) 3 bf3 \"bf3Comment\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 word 2 null \"Comment2\"\n" + " 6 word 2 null \"Comment2\"\n" +
" 8 dword 4 field3 \"\"\n" + " 8 dword 4 field3 \"\"\n" +
" 12 byte 1 field4 \"Comment4\"\n" + " 12 byte 1 field4 \"Comment4\"\n" +
@ -788,7 +788,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(3) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(3) 3 bf3 \"bf3Comment\"\n" +
@ -807,7 +807,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:0(7) 1 \"zero bitfield\"\n" + // field name discarded " 2 int:0(7) 1 \"zero bitfield\"\n" + // field name discarded
" 2 int:3(5) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(5) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(2) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(2) 1 bf2 \"bf2Comment\"\n" +
@ -838,7 +838,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 float 4 null \"\"\n" + " 2 float 4 null \"\"\n" +
" 6 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 6 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 6 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 6 int:3(3) 1 bf2 \"bf2Comment\"\n" +
@ -1083,9 +1083,9 @@ public class StructureDBTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 undefined 1 null \"\"\n" + // " 9 undefined 1 null \"\"\n" +
" 10 undefined 1 null \"\"\n" + // " 10 undefined 1 null \"\"\n" +
"}\n" + "}\n" +
"Size = 11 Actual Alignment = 1", struct); "Size = 11 Actual Alignment = 1", struct);
//@formatter:on //@formatter:on
@ -1204,11 +1204,11 @@ public class StructureDBTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" + " 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" +
" 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" + " 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" +
" 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" + " 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" Foo[0] 0 myFlex \"flexComment\"\n" + " Foo[0] 0 myFlex \"flexComment\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", struct); "Size = 12 Actual Alignment = 1", struct);
@ -1228,11 +1228,11 @@ public class StructureDBTest extends AbstractGTest {
" 1 word 2 null \"Comment2\"\n" + " 1 word 2 null \"Comment2\"\n" +
" 3 dword 4 field3 \"\"\n" + " 3 dword 4 field3 \"\"\n" +
" 7 byte 1 field4 \"Comment4\"\n" + " 7 byte 1 field4 \"Comment4\"\n" +
" 8 undefined 1 null \"\"\n" + // " 8 undefined 1 null \"\"\n" +
" 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" + " 9 Foo:4(0) 1 MyBit1 \"bitComment1\"\n" +
" 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" + " 9 Foo:3(4) 1 MyBit2 \"bitComment2\"\n" +
" 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" + " 9 Foo:2(7) 2 MyBit3 \"bitComment3\"\n" +
" 11 undefined 1 null \"\"\n" + // " 11 undefined 1 null \"\"\n" +
" Foo[0] 0 myFlex \"flexComment\"\n" + " Foo[0] 0 myFlex \"flexComment\"\n" +
"}\n" + "}\n" +
"Size = 12 Actual Alignment = 1", newStruct); "Size = 12 Actual Alignment = 1", newStruct);
@ -1252,7 +1252,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
@ -1271,7 +1271,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:3(3) 1 bf2 \"bf2Comment\"\n" + " 2 int:3(3) 1 bf2 \"bf2Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
@ -1289,7 +1289,7 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 2 int:15(6) 3 bf3 \"bf3Comment\"\n" + " 2 int:15(6) 3 bf3 \"bf3Comment\"\n" +
" 4 int:11(5) 2 bf4 \"bf4Comment\"\n" + " 4 int:11(5) 2 bf4 \"bf4Comment\"\n" +
@ -1306,9 +1306,9 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 int:11(5) 2 bf4 \"bf4Comment\"\n" + " 4 int:11(5) 2 bf4 \"bf4Comment\"\n" +
" 6 dword 4 field3 \"\"\n" + " 6 dword 4 field3 \"\"\n" +
" 10 byte 1 field4 \"Comment4\"\n" + " 10 byte 1 field4 \"Comment4\"\n" +
@ -1323,11 +1323,11 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 int:3(0) 1 bf1 \"bf1Comment\"\n" + " 2 int:3(0) 1 bf1 \"bf1Comment\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 dword 4 field3 \"\"\n" + " 6 dword 4 field3 \"\"\n" +
" 10 byte 1 field4 \"Comment4\"\n" + " 10 byte 1 field4 \"Comment4\"\n" +
"}\n" + "}\n" +
@ -1341,11 +1341,11 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 undefined 1 null \"\"\n" + // " 2 undefined 1 null \"\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 undefined 1 null \"\"\n" + // " 5 undefined 1 null \"\"\n" +
" 6 dword 4 field3 \"\"\n" + " 6 dword 4 field3 \"\"\n" +
" 10 byte 1 field4 \"Comment4\"\n" + " 10 byte 1 field4 \"Comment4\"\n" +
"}\n" + "}\n" +
@ -1359,10 +1359,10 @@ public class StructureDBTest extends AbstractGTest {
"Unaligned\n" + "Unaligned\n" +
"Structure Test {\n" + "Structure Test {\n" +
" 0 byte 1 field1 \"Comment1\"\n" + " 0 byte 1 field1 \"Comment1\"\n" +
" 1 undefined 1 null \"\"\n" + // " 1 undefined 1 null \"\"\n" +
" 2 undefined 1 null \"\"\n" + // " 2 undefined 1 null \"\"\n" +
" 3 undefined 1 null \"\"\n" + // " 3 undefined 1 null \"\"\n" +
" 4 undefined 1 null \"\"\n" + // " 4 undefined 1 null \"\"\n" +
" 5 dword 4 field3 \"\"\n" + " 5 dword 4 field3 \"\"\n" +
" 9 byte 1 field4 \"Comment4\"\n" + " 9 byte 1 field4 \"Comment4\"\n" +
"}\n" + "}\n" +