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