> If you just want the least number of bytes
> that can represent the number then you
> can cast to xs:integer.
Okay, I gave that a try:
<xs:element name="Integer_Value" type="unsignedint31"
dfdl:bitOrder="leastSignificantBitFirst"
dfdl:lengthUnits="bits"
dfdl:alignment="1"
dfdl:alignmentUnits="bits"
dfdl:representation="binary"
dfdl:binaryNumberRep="binary" />
<xs:element name="Hex_Value" type="xs:hexBinary"
dfdl:inputValueCalc="{ dfdl:hexBinary(xs:integer(../Integer_Value)) }" />
Unfortunately, that produced the same result:
<Integer_Value>57920</Integer_Value>
<Hex_Value>000000000000E240</Hex_Value>
Thoughts?
/Roger
-----Original Message-----
From: Steve Lawrence <[email protected]>
Sent: Sunday, February 24, 2019 9:27 AM
To: [email protected]; Costello, Roger L. <[email protected]>
Subject: [EXT] Re: Can type="hexBinary" be used on a 31-bit field?
The number of bytes created by dfdl:hexBinary depends on the type. So a type of
byte, short, int, and long will create 1, 2, 4, and 8 bytes respectively. So if
you want a certain number of bytes, cast it to the right type before passing it
to the dfdl:hexBinary constructor. If you just want the least number of bytes
that can represent the number then you can cast to xs:integer.
On 2/24/19 4:24 AM, Costello, Roger L. wrote:
> Steve, thanks for pointing me to dfdl:hexBinary. I gave it a try. I am
> getting odd results. I am getting a bunch of zeroes prepended to the hex
> value:
>
> <Hint_Name_Table_RVA>
> <Integer_Value>57920</Integer_Value>
> <Hex_Value>000000000000E240</Hex_Value>
> </Hint_Name_Table_RVA>
>
> How do I get rid of all those extraneous zeroes?
>
> /Roger
>
> -----Original Message-----
> From: Steve Lawrence <[email protected]>
> Sent: Wednesday, February 13, 2019 8:08 AM
> To: [email protected]; Costello, Roger L. <[email protected]>
> Subject: [EXT] Re: Can type="hexBinary" be used on a 31-bit field?
>
> Actually, we do have a function that will work: dfdl:hexBinary(). This
> function takes in an numeric value and converts it to hexBinary. So
> first parse your 31 bit field as an int (which will take into account
> byteOrder) then use inputValueCalc to convert that int value to a hex binary
> value for display. So something like:
>
> <xs:element name="Int" type="xs:int"
> dfdl:lengthKind="explicit"
> dfdl:length="31"
> dfdl:lengthUnits="bits"
> dfdl:byteOrder="littleEndian"
> dfdl:bitOrder="leastSignificantBitFirst" />
> <xs:element name="HB" type="xs:hexBinary"
> dfdl:inputValueCalc="{ dfdl:hexBinary(../Int) }" />
>
> A new function that can convert a number to a string of any base might still
> potentially be useful, but it shouldn't be needed to support what you're
> tying to do.
>
> - Steve
>
>
> On 2/12/19 8:22 PM, Steve Lawrence wrote:
>> Sortof. Daffodil does support non-byte size hexBinary. The resulting
>> hexBinary in the infoset is padded with zeros to reach a full byte.
>>
>> However, I don't think it would behave the way you would like it to
>> work since you're working in byteOrder="littleEndian" and
>> bitOrder="leastSignificantBitFirst".
>>
>> As an example, let's say we have the following data and 0-based bit
>> positions:
>>
>> Pos: 7 0 15 8 23 16 31 24
>> Bin: 11011010 11111111 00001101 11000001
>> Hex: D A F F 0 D C 1
>>
>> And assume we have the following schema to parse the first 31 bits of
>> that data.
>>
>> <xs:element name="HB" type="xs:hexBinary"
>> dfdl:lengthKind="explicit"
>> dfdl:length="31"
>> dfdl:lengthUnits="bits"
>> dfdl:byteOrder="littleEndian"
>> dfdl:bitOrder="leastSignificantBitFirst" />
>>
>> Since this is littleEndian/leastSignificantBitFirst, one might expect
>> the following infoset, which is probably the memory address you would want:
>>
>> <HB>410DFFDA</HB>
>>
>> So the order of the bytes are flipped and only the 7 least
>> significant bits of the 4th byte are included. The most significant
>> bit of the last byte becomes a 0 resulting in 0x41.
>>
>> However, that isn't the case (at least in the next version of
>> Daffodil where a bug is fixed). What actually happens is that since
>> the type is hexBinary, byteOrder is completely ignored and the
>> resulting infoset
>> becomes:
>>
>> <HB>DAFF0D41</HB>
>>
>> So the most significant bit of last byte is still not included due to
>> the bitOrder, but the bytes aren't flipped because byteOrder is ignored.
>> So this doesn't really represent the memory address you want.
>>
>> However, it sounds to me like maybe you don't actually want hexBinary
>> in the infoset. The data isn't an array of bytes, which is what
>> hexBinary is usually used to represent. The data is really just an
>> integer (which does obey byteOrder) that you just so happen to want
>> to represent in
>> base-16 in the infoset, because that integer represents a memory
>> address and that's how memory addresses are most often displayed.
>>
>> And I can imagine cases (and I think I've come across some) where one
>> would prefer on octal, trinary, or binary representation too. So even
>> if we did support a mode where hexBinary does obey byteOrder, it
>> wouldn't solve those other cases.
>>
>> So maybe the right way to support this is via dfdl:inputValueCalc and
>> an XPath function that could convert between bases. Unfortunately, no
>> functions in the DFDL spec allow for such a conversion. One might be
>> able to come up with an ugly DFDL expression that could convert a
>> fixed length number to base-16, but something like the
>> dp:radix-convert() [1] seems like something that might be worth adding to
>> DFDL/Daffodil.
>>
>> - Steve
>>
>> [1]
>> https://www.ibm.com/support/knowledgecenter/en/SS9H2Y_7.7.0/com.ibm.d
>> p .doc/radix-convert_cryptographicfunction.html
>>
>>
>>
>> On 2/12/19 4:27 PM, Costello, Roger L. wrote:
>>> Hello DFDL community,
>>>
>>> My input contains a field that is 32 bits. The last bit indicates the type
>>> of the field. If the last bit is 1, then the prior 31 bits represents an
>>> address. I could declare that 31-bit field like this:
>>>
>>> <xs:element name="Hint_Name_Table_RVA" type="unsignedint31" />
>>>
>>> The will produce XML such as this:
>>>
>>> <Hint_Name_Table_RVA>58222</Hint_Name_Table_RVA>
>>>
>>> Ugh!
>>>
>>> I don't like showing an address as an unsigned integer. I prefer showing
>>> addresses as hex. Is there anyway to show a 31-bit field as a hex value?
>>>
>>> /Roger
>>>
>>
>