Looks like this is a bug in Daffodil. When the argument is an
xs:integer, you will either get 1, 2, or 8 bytes, depending on the value
being converted to hexBinary. Doesn't look like it's possible to get 4
bytes due to the bug. I've opened DAFFODIL-2075 to track this issue.

If you really want 4 bytes, you could use the fn:substring function to
chop off the extra 4 bytes, e.g.:

  xs:hexBinary(fn:substring(dfdl:hexBinary(../Integer_Value), 9)))

Should result in something like:

  <Integer_Value>57920</Integer_Value>
  <Hex_Value>0000E240</Hex_Value>

- Steve

On 2/25/19 4:17 AM, Costello, Roger L. wrote:
>> 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
>>>>
>>>
>>
> 

Reply via email to