mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
c87707cc4e
9 changed files with 250 additions and 28 deletions
|
@ -2323,14 +2323,7 @@ void ProtoModel::decode(Decoder &decoder)
|
||||||
if (attribId == ATTRIB_NAME)
|
if (attribId == ATTRIB_NAME)
|
||||||
name = decoder.readString();
|
name = decoder.readString();
|
||||||
else if (attribId == ATTRIB_EXTRAPOP) {
|
else if (attribId == ATTRIB_EXTRAPOP) {
|
||||||
string extrapopString = decoder.readString();
|
extrapop = decoder.readSignedIntegerExpectString("unknown", extrapop_unknown);
|
||||||
if (extrapopString == "unknown")
|
|
||||||
extrapop = extrapop_unknown;
|
|
||||||
else {
|
|
||||||
istringstream s(extrapopString);
|
|
||||||
s.unsetf(ios::dec | ios::hex | ios::oct);
|
|
||||||
s >> extrapop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (attribId == ATTRIB_STACKSHIFT) {
|
else if (attribId == ATTRIB_STACKSHIFT) {
|
||||||
// Allow this attribute for backward compatibility
|
// Allow this attribute for backward compatibility
|
||||||
|
@ -4415,11 +4408,7 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb)
|
||||||
}
|
}
|
||||||
else if (attribId == ATTRIB_EXTRAPOP) {
|
else if (attribId == ATTRIB_EXTRAPOP) {
|
||||||
seenextrapop = true;
|
seenextrapop = true;
|
||||||
try {
|
readextrapop = decoder.readSignedIntegerExpectString("unknown", ProtoModel::extrapop_unknown);
|
||||||
readextrapop = decoder.readSignedInteger();
|
|
||||||
} catch(DecoderError &err) {
|
|
||||||
readextrapop = ProtoModel::extrapop_unknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (attribId == ATTRIB_MODELLOCK) {
|
else if (attribId == ATTRIB_MODELLOCK) {
|
||||||
if (decoder.readBool())
|
if (decoder.readBool())
|
||||||
|
|
|
@ -295,6 +295,33 @@ intb XmlDecode::readSignedInteger(const AttributeId &attribId)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intb XmlDecode::readSignedIntegerExpectString(const string &expect,intb expectval)
|
||||||
|
|
||||||
|
{
|
||||||
|
const Element *el = elStack.back();
|
||||||
|
const string &value( el->getAttributeValue(attributeIndex) );
|
||||||
|
if (value == expect)
|
||||||
|
return expectval;
|
||||||
|
istringstream s2(value);
|
||||||
|
s2.unsetf(ios::dec | ios::hex | ios::oct);
|
||||||
|
intb res = 0;
|
||||||
|
s2 >> res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
intb XmlDecode::readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval)
|
||||||
|
|
||||||
|
{
|
||||||
|
string value = readString(attribId);
|
||||||
|
if (value == expect)
|
||||||
|
return expectval;
|
||||||
|
istringstream s2(value);
|
||||||
|
s2.unsetf(ios::dec | ios::hex | ios::oct);
|
||||||
|
intb res = 0;
|
||||||
|
s2 >> res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
uintb XmlDecode::readUnsignedInteger(void)
|
uintb XmlDecode::readUnsignedInteger(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -691,9 +718,9 @@ bool PackedDecode::readBool(void)
|
||||||
if ((header1 & HEADEREXTEND_MASK)!=0)
|
if ((header1 & HEADEREXTEND_MASK)!=0)
|
||||||
getNextByte(curPos);
|
getNextByte(curPos);
|
||||||
uint1 typeByte = getNextByte(curPos);
|
uint1 typeByte = getNextByte(curPos);
|
||||||
|
attributeRead = true;
|
||||||
if ((typeByte >> TYPECODE_SHIFT) != TYPECODE_BOOLEAN)
|
if ((typeByte >> TYPECODE_SHIFT) != TYPECODE_BOOLEAN)
|
||||||
throw DecoderError("Expecting boolean attribute");
|
throw DecoderError("Expecting boolean attribute");
|
||||||
attributeRead = true;
|
|
||||||
return ((typeByte & LENGTHCODE_MASK) != 0);
|
return ((typeByte & LENGTHCODE_MASK) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,6 +751,7 @@ intb PackedDecode::readSignedInteger(void)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipAttributeRemaining(typeByte);
|
skipAttributeRemaining(typeByte);
|
||||||
|
attributeRead = true;
|
||||||
throw DecoderError("Expecting signed integer attribute");
|
throw DecoderError("Expecting signed integer attribute");
|
||||||
}
|
}
|
||||||
attributeRead = true;
|
attributeRead = true;
|
||||||
|
@ -739,6 +767,40 @@ intb PackedDecode::readSignedInteger(const AttributeId &attribId)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intb PackedDecode::readSignedIntegerExpectString(const string &expect,intb expectval)
|
||||||
|
|
||||||
|
{
|
||||||
|
intb res;
|
||||||
|
Position tmpPos = curPos;
|
||||||
|
uint1 header1 = getNextByte(tmpPos);
|
||||||
|
if ((header1 & HEADEREXTEND_MASK)!=0)
|
||||||
|
getNextByte(tmpPos);
|
||||||
|
uint1 typeByte = getNextByte(tmpPos);
|
||||||
|
uint4 typeCode = typeByte >> TYPECODE_SHIFT;
|
||||||
|
if (typeCode == TYPECODE_STRING) {
|
||||||
|
string val = readString();
|
||||||
|
if (val != expect) {
|
||||||
|
ostringstream s;
|
||||||
|
s << "Expecting string \"" << expect << "\" but read \"" << val << "\"";
|
||||||
|
throw DecoderError(s.str());
|
||||||
|
}
|
||||||
|
res = expectval;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = readSignedInteger();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
intb PackedDecode::readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval)
|
||||||
|
|
||||||
|
{
|
||||||
|
findMatchingAttribute(attribId);
|
||||||
|
intb res = readSignedIntegerExpectString(expect,expectval);
|
||||||
|
curPos = startPos;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
uintb PackedDecode::readUnsignedInteger(void)
|
uintb PackedDecode::readUnsignedInteger(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -753,6 +815,7 @@ uintb PackedDecode::readUnsignedInteger(void)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipAttributeRemaining(typeByte);
|
skipAttributeRemaining(typeByte);
|
||||||
|
attributeRead = true;
|
||||||
throw DecoderError("Expecting unsigned integer attribute");
|
throw DecoderError("Expecting unsigned integer attribute");
|
||||||
}
|
}
|
||||||
attributeRead = true;
|
attributeRead = true;
|
||||||
|
@ -778,6 +841,7 @@ string PackedDecode::readString(void)
|
||||||
uint4 typeCode = typeByte >> TYPECODE_SHIFT;
|
uint4 typeCode = typeByte >> TYPECODE_SHIFT;
|
||||||
if (typeCode != TYPECODE_STRING) {
|
if (typeCode != TYPECODE_STRING) {
|
||||||
skipAttributeRemaining(typeByte);
|
skipAttributeRemaining(typeByte);
|
||||||
|
attributeRead = true;
|
||||||
throw DecoderError("Expecting string attribute");
|
throw DecoderError("Expecting string attribute");
|
||||||
}
|
}
|
||||||
int4 length = readLengthCode(typeByte);
|
int4 length = readLengthCode(typeByte);
|
||||||
|
@ -842,6 +906,7 @@ AddrSpace *PackedDecode::readSpace(void)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipAttributeRemaining(typeByte);
|
skipAttributeRemaining(typeByte);
|
||||||
|
attributeRead = true;
|
||||||
throw DecoderError("Expecting space attribute");
|
throw DecoderError("Expecting space attribute");
|
||||||
}
|
}
|
||||||
attributeRead = true;
|
attributeRead = true;
|
||||||
|
|
|
@ -189,6 +189,29 @@ public:
|
||||||
/// \return the signed integer value
|
/// \return the signed integer value
|
||||||
virtual intb readSignedInteger(const AttributeId &attribId)=0;
|
virtual intb readSignedInteger(const AttributeId &attribId)=0;
|
||||||
|
|
||||||
|
/// \brief Parse the current attribute as either a signed integer value or a string.
|
||||||
|
///
|
||||||
|
/// If the attribute is an integer, its value is returned. If the attribute is a string, it must match an
|
||||||
|
/// expected string passed to the method, and a predetermined integer value associated with the string is returned.
|
||||||
|
/// If the attribute neither matches the expected string nor is an integer, the return value is undefined.
|
||||||
|
/// \param expect is the string value to expect if the attribute is encoded as a string
|
||||||
|
/// \param expectval is the integer value to return if the attribute matches the expected string
|
||||||
|
/// \return the encoded integer or the integer value associated with the expected string
|
||||||
|
virtual intb readSignedIntegerExpectString(const string &expect,intb expectval)=0;
|
||||||
|
|
||||||
|
/// \brief Find and parse a specific attribute in the current element as either a signed integer or a string.
|
||||||
|
///
|
||||||
|
/// If the attribute is an integer, its value is parsed and returned.
|
||||||
|
/// If the attribute is encoded as a string, it must match an expected string passed to this method.
|
||||||
|
/// In this case, a predetermined integer value is passed back, indicating a matching string was parsed.
|
||||||
|
/// If the attribute neither matches the expected string nor is an integer, the return value is undefined.
|
||||||
|
/// If there is no attribute matching the id, an exception is thrown.
|
||||||
|
/// \param attribId is the specific attribute id to match
|
||||||
|
/// \param expect is the string to expect, if the attribute is not encoded as an integer
|
||||||
|
/// \param expectval is the integer value to return if the attribute matches the expected string
|
||||||
|
/// \return the encoded integer or the integer value associated with the expected string
|
||||||
|
virtual intb readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval)=0;
|
||||||
|
|
||||||
/// \brief Parse the current attribute as an unsigned integer value
|
/// \brief Parse the current attribute as an unsigned integer value
|
||||||
///
|
///
|
||||||
/// The last attribute, as returned by getNextAttributeId, is treated as an unsigned integer, and its value is returned.
|
/// The last attribute, as returned by getNextAttributeId, is treated as an unsigned integer, and its value is returned.
|
||||||
|
@ -338,6 +361,8 @@ public:
|
||||||
virtual bool readBool(const AttributeId &attribId);
|
virtual bool readBool(const AttributeId &attribId);
|
||||||
virtual intb readSignedInteger(void);
|
virtual intb readSignedInteger(void);
|
||||||
virtual intb readSignedInteger(const AttributeId &attribId);
|
virtual intb readSignedInteger(const AttributeId &attribId);
|
||||||
|
virtual intb readSignedIntegerExpectString(const string &expect,intb expectval);
|
||||||
|
virtual intb readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval);
|
||||||
virtual uintb readUnsignedInteger(void);
|
virtual uintb readUnsignedInteger(void);
|
||||||
virtual uintb readUnsignedInteger(const AttributeId &attribId);
|
virtual uintb readUnsignedInteger(const AttributeId &attribId);
|
||||||
virtual string readString(void);
|
virtual string readString(void);
|
||||||
|
@ -471,6 +496,8 @@ public:
|
||||||
virtual bool readBool(const AttributeId &attribId);
|
virtual bool readBool(const AttributeId &attribId);
|
||||||
virtual intb readSignedInteger(void);
|
virtual intb readSignedInteger(void);
|
||||||
virtual intb readSignedInteger(const AttributeId &attribId);
|
virtual intb readSignedInteger(const AttributeId &attribId);
|
||||||
|
virtual intb readSignedIntegerExpectString(const string &expect,intb expectval);
|
||||||
|
virtual intb readSignedIntegerExpectString(const AttributeId &attribId,const string &expect,intb expectval);
|
||||||
virtual uintb readUnsignedInteger(void);
|
virtual uintb readUnsignedInteger(void);
|
||||||
virtual uintb readUnsignedInteger(const AttributeId &attribId);
|
virtual uintb readUnsignedInteger(const AttributeId &attribId);
|
||||||
virtual string readString(void);
|
virtual string readString(void);
|
||||||
|
|
|
@ -210,6 +210,50 @@ TEST(marshal_unsigned_xml) {
|
||||||
test_unsigned_attributes(outStream, encoder, decoder);
|
test_unsigned_attributes(outStream, encoder, decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_mixed_attributes(ostringstream &outStream,Encoder &encoder,Decoder &decoder)
|
||||||
|
|
||||||
|
{
|
||||||
|
encoder.openElement(ELEM_ADDR);
|
||||||
|
encoder.writeSignedInteger(ATTRIB_ALIGN, 456);
|
||||||
|
encoder.writeString(ATTRIB_EXTRAPOP, "unknown");
|
||||||
|
encoder.closeElement(ELEM_ADDR);
|
||||||
|
istringstream inStream(outStream.str());
|
||||||
|
decoder.ingestStream(inStream);
|
||||||
|
int4 alignVal = -1;
|
||||||
|
int4 extrapopVal = -1;
|
||||||
|
uint4 el = decoder.openElement(ELEM_ADDR);
|
||||||
|
for(;;) {
|
||||||
|
uint4 attribId = decoder.getNextAttributeId();
|
||||||
|
if (attribId == 0) break;
|
||||||
|
if (attribId == ATTRIB_ALIGN)
|
||||||
|
alignVal = decoder.readSignedIntegerExpectString("00blah", 700);
|
||||||
|
else if (attribId == ATTRIB_EXTRAPOP)
|
||||||
|
extrapopVal = decoder.readSignedIntegerExpectString("unknown", 800);
|
||||||
|
}
|
||||||
|
decoder.closeElement(el);
|
||||||
|
ASSERT_EQUALS(alignVal, 456);
|
||||||
|
ASSERT_EQUALS(extrapopVal, 800);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(marshal_mixed_packed) {
|
||||||
|
ostringstream outStream;
|
||||||
|
|
||||||
|
theEnviron.build();
|
||||||
|
PackedEncode encoder(outStream);
|
||||||
|
PackedDecode decoder(spcManager);
|
||||||
|
test_mixed_attributes(outStream, encoder, decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(marshal_mixed_xml) {
|
||||||
|
ostringstream outStream;
|
||||||
|
|
||||||
|
theEnviron.build();
|
||||||
|
XmlEncode encoder(outStream);
|
||||||
|
XmlDecode decoder(spcManager);
|
||||||
|
test_mixed_attributes(outStream, encoder, decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_attributes(ostringstream &outStream,Encoder &encoder,Decoder &decoder)
|
void test_attributes(ostringstream &outStream,Encoder &encoder,Decoder &decoder)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -141,6 +141,38 @@ public interface Decoder extends ByteIngest {
|
||||||
*/
|
*/
|
||||||
public long readSignedInteger(AttributeId attribId) throws DecoderException;
|
public long readSignedInteger(AttributeId attribId) throws DecoderException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the current attribute as either a signed integer value or a string.
|
||||||
|
* If the attribute is an integer, its value is returned.
|
||||||
|
* If the attribute is a string, it must match an expected string passed to the method,
|
||||||
|
* and a predetermined integer value associated with the string is returned.
|
||||||
|
* If the attribute string does not match, or the attribute is encoded as anything other than
|
||||||
|
* a string or signed integer, an exception is thrown.
|
||||||
|
* @param expect is the string value to expect if the attribute is encoded as a string
|
||||||
|
* @param expectval is the integer value to return if the attribute matches the expected string
|
||||||
|
* @return the encoded integer or the integer value associated with the expected string
|
||||||
|
* @throws DecoderException is an integer value or expected string cannot be parsed
|
||||||
|
*/
|
||||||
|
public long readSignedIntegerExpectString(String expect, long expectval)
|
||||||
|
throws DecoderException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find and parse a specific attribute in the current element as either a signed integer
|
||||||
|
* or a string. If the attribute is an integer, its value is returned.
|
||||||
|
* If the attribute is encoded as a string, it must match an expected string
|
||||||
|
* passed to this method. In this case, a predetermined integer value is passed back,
|
||||||
|
* indicating a matching string was parsed. If the attribute string does not match, or
|
||||||
|
* the attribute is encoded as anything other than a string or signed integer, an exception
|
||||||
|
* is thrown.
|
||||||
|
* @param attribId is the specific attribute id to match
|
||||||
|
* @param expect is the string to expect, if the attribute is not encoded as an integer
|
||||||
|
* @param expectval is the integer value to return if the attribute matches the expected string
|
||||||
|
* @return the encoded integer or the integer value associated with the expected string
|
||||||
|
* @throws DecoderException if an integer value or expected string cannot be parsed
|
||||||
|
*/
|
||||||
|
public long readSignedIntegerExpectString(AttributeId attribId, String expect, long expectval)
|
||||||
|
throws DecoderException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the current attribute as an unsigned integer value
|
* Parse the current attribute as an unsigned integer value
|
||||||
* The last attribute, as returned by getNextAttributeId, is treated as an unsigned integer,
|
* The last attribute, as returned by getNextAttributeId, is treated as an unsigned integer,
|
||||||
|
|
|
@ -427,12 +427,8 @@ public class FunctionPrototype {
|
||||||
PrototypeModel protoModel =
|
PrototypeModel protoModel =
|
||||||
dtmanage.getProgram().getCompilerSpec().getCallingConvention(modelname);
|
dtmanage.getProgram().getCompilerSpec().getCallingConvention(modelname);
|
||||||
hasThis = (protoModel == null) ? false : protoModel.hasThisPointer();
|
hasThis = (protoModel == null) ? false : protoModel.hasThisPointer();
|
||||||
try {
|
extrapop = (int) decoder.readSignedIntegerExpectString(ATTRIB_EXTRAPOP, "unknown",
|
||||||
extrapop = (int) decoder.readSignedInteger(ATTRIB_EXTRAPOP);
|
PrototypeModel.UNKNOWN_EXTRAPOP);
|
||||||
}
|
|
||||||
catch (DecoderException e) {
|
|
||||||
extrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
|
||||||
}
|
|
||||||
modellock = false;
|
modellock = false;
|
||||||
dotdotdot = false;
|
dotdotdot = false;
|
||||||
voidinputlock = false;
|
voidinputlock = false;
|
||||||
|
|
|
@ -32,7 +32,6 @@ import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
import ghidra.util.exception.InvalidInputException;
|
||||||
import ghidra.util.xml.SpecXmlUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -155,13 +154,8 @@ public class HighParamID extends PcodeSyntaxTree {
|
||||||
else if (subel == ELEM_PROTO.id()) {
|
else if (subel == ELEM_PROTO.id()) {
|
||||||
decoder.openElement();
|
decoder.openElement();
|
||||||
modelname = decoder.readString(ATTRIB_MODEL);
|
modelname = decoder.readString(ATTRIB_MODEL);
|
||||||
String val = decoder.readString(ATTRIB_EXTRAPOP);
|
protoextrapop = (int) decoder.readSignedIntegerExpectString(ATTRIB_EXTRAPOP,
|
||||||
if (val.equals("unknown")) {
|
"unknown", PrototypeModel.UNKNOWN_EXTRAPOP);
|
||||||
protoextrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
protoextrapop = SpecXmlUtils.decodeInt(val);
|
|
||||||
}
|
|
||||||
decoder.closeElement(subel);
|
decoder.closeElement(subel);
|
||||||
}
|
}
|
||||||
else if (subel == ELEM_INPUT.id()) {
|
else if (subel == ELEM_INPUT.id()) {
|
||||||
|
|
|
@ -370,6 +370,41 @@ public class PackedDecode implements Decoder {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long readSignedIntegerExpectString(String expect, long expectval)
|
||||||
|
throws DecoderException {
|
||||||
|
long res;
|
||||||
|
LinkedByteBuffer.Position tmpPos = new LinkedByteBuffer.Position();
|
||||||
|
tmpPos.copy(curPos);
|
||||||
|
byte header1 = tmpPos.getNextByte();
|
||||||
|
if ((header1 & HEADEREXTEND_MASK) != 0) {
|
||||||
|
tmpPos.getNextByte();
|
||||||
|
}
|
||||||
|
byte typeByte = tmpPos.getNextByte();
|
||||||
|
int typeCode = typeByte >> TYPECODE_SHIFT;
|
||||||
|
if (typeCode == TYPECODE_STRING) {
|
||||||
|
String val = readString();
|
||||||
|
if (!val.equals(expect)) {
|
||||||
|
throw new DecoderException(
|
||||||
|
"Expecting string \"" + expect + "\" but read \"" + val + "\"");
|
||||||
|
}
|
||||||
|
res = expectval;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = readSignedInteger();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long readSignedIntegerExpectString(AttributeId attribId, String expect, long expectval)
|
||||||
|
throws DecoderException {
|
||||||
|
findMatchingAttribute(attribId);
|
||||||
|
long res = readSignedIntegerExpectString(expect, expectval);
|
||||||
|
curPos.copy(startPos);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long readUnsignedInteger() throws DecoderException {
|
public long readUnsignedInteger() throws DecoderException {
|
||||||
byte header1 = curPos.getNextByte();
|
byte header1 = curPos.getNextByte();
|
||||||
|
|
|
@ -155,6 +155,38 @@ public class EncodeDecodeTest extends AbstractGenericTest {
|
||||||
decoder.closeElement(el);
|
decoder.closeElement(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void testMixedAttributes(Encoder encoder, Decoder decoder)
|
||||||
|
throws DecoderException, IOException {
|
||||||
|
encoder.openElement(ELEM_ADDR);
|
||||||
|
encoder.writeSignedInteger(ATTRIB_ALIGN, 456);
|
||||||
|
encoder.writeString(ATTRIB_EXTRAPOP, "unknown");
|
||||||
|
encoder.closeElement(ELEM_ADDR);
|
||||||
|
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||||
|
encoder.writeTo(outStream);
|
||||||
|
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
|
||||||
|
decoder.open(1 << 20, "testMixedAttributes");
|
||||||
|
decoder.ingestStream(inStream);
|
||||||
|
decoder.endIngest();
|
||||||
|
int alignVal = -1;
|
||||||
|
int extrapopVal = -1;
|
||||||
|
int el = decoder.openElement(ELEM_ADDR);
|
||||||
|
for (;;) {
|
||||||
|
int attribId = decoder.getNextAttributeId();
|
||||||
|
if (attribId == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (attribId == ATTRIB_ALIGN.id()) {
|
||||||
|
alignVal = (int) decoder.readSignedIntegerExpectString("00blah", 700);
|
||||||
|
}
|
||||||
|
else if (attribId == ATTRIB_EXTRAPOP.id()) {
|
||||||
|
extrapopVal = (int) decoder.readSignedIntegerExpectString("unknown", 800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decoder.closeElement(el);
|
||||||
|
assertEquals(alignVal, 456);
|
||||||
|
assertEquals(extrapopVal, 800);
|
||||||
|
}
|
||||||
|
|
||||||
private void testAttributes(Encoder encoder, Decoder decoder)
|
private void testAttributes(Encoder encoder, Decoder decoder)
|
||||||
throws DecoderException, IOException
|
throws DecoderException, IOException
|
||||||
|
|
||||||
|
@ -401,6 +433,14 @@ public class EncodeDecodeTest extends AbstractGenericTest {
|
||||||
testUnsignedAttributes(encoder, decoder);
|
testUnsignedAttributes(encoder, decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void marshalMixedPacked() throws DecoderException, IOException {
|
||||||
|
PackedEncode encoder = new PackedEncode();
|
||||||
|
encoder.clear();
|
||||||
|
PackedDecode decoder = new PackedDecode(addrFactory);
|
||||||
|
testMixedAttributes(encoder, decoder);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void marshalAttribsPacked() throws DecoderException, IOException {
|
public void marshalAttribsPacked() throws DecoderException, IOException {
|
||||||
PackedEncode encoder = new PackedEncode();
|
PackedEncode encoder = new PackedEncode();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue