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.dp
>> .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