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