Concating bit values will not work because there are no constructor
functions that accept a bit string. The dfdl:setBits() function can be
used, but only for only for bytes (i.e. 8 bits or less). You could
always just use math to construct an int, e.g.:
./bit1 * fn:pow(2,31) +
./bit2 * fn:pow(2,30) +
...
./bitN * fn:pow(2,0)
It would probably be more efficient to expand the fn:pow's to their
actual values, but this gives the idea.
That said, I think an approach that makes for a more descriptive schema
that is easier to understand is to use a choice where each branch of the
choice parses the 30 bits differently, and a discriminator is used to
ensure the correct branch is taken based on the lst bit. Something like:
<xs:choice>
<xs:sequence>
<xs:element name="OrdinalNumber" dfdl:length="16" ... />
<xs:element name="Zero" dfdl:length="15 ... />
<xs:element name="Flag" dfdl:length=1" ... >
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:discriminator test="{ . eq 1 }" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:sequence>
<xs:element name="HintNameTableRVA" dfdl:length="31" ... />
<xs:element name="Flag" dfdl:length=1" ... >
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:discriminator test="{ . eq 0 }" />
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:choice>
This is bit inefficient since it requires parsing the same 32 bits twice
if the last bit is a 0, but it's much easier to understand what data
looks like.
- Steve
On 2/11/19 6:43 AM, Costello, Roger L. wrote:
> Hello DFDL Community,
>
> My input file contains a 32-bit field (bit 0 to bit 31). Bit 31 determines
> how
> to interpret the other bits: if bit 31 = 1 then bits 0 to 15 is an unsigned
> int
> denoting an ordinal number and the other bits must be zero. If bit 30 = 0
> then
> bits 0 to 30 is an unsigned int denoting a hint/name table RVA. The following
> graphic illustrates the structure:
>
> How to express this in DFDL? I figured that I would create a hidden group
> that
> contains 32 1-bit elements. I would have a choice that expresses this: If
> hidden
> bit 31 = 1 then choose the ordinal_number element, otherwise (hidden bit 31 =
> 0)
> choose hint_name_table_RVA element.
>
> The value of ordinal_number is calculated by concatenating hidden bit 0 with
> hidden bit 1, …, hidden bit 15. Then, cast that to unsigned int.
>
> The value of hint_name_table_RVA is calculated by concatenating hidden bit 0
> with hidden bit 1, …, hidden bit 30. Then, cast that to unsigned int.
>
> You can see my schema below. Unfortunately, it fails. What is the right way
> to
> approach this problem, please? /Roger
>
> <xs:elementname="Ordinal_Number"type="unsignedint16"dfdl:inputValueCalc="{
> unsignedint16(
> fn:concat(./Hidden_Lookup_Table_bit0,
> ./Hidden_Lookup_Table_bit1,
> ./Hidden_Lookup_Table_bit2,
> ./Hidden_Lookup_Table_bit3,
> ./Hidden_Lookup_Table_bit4,
> ./Hidden_Lookup_Table_bit5,
> ./Hidden_Lookup_Table_bit6,
> ./Hidden_Lookup_Table_bit7,
> ./Hidden_Lookup_Table_bit8,
> ./Hidden_Lookup_Table_bit9,
> ./Hidden_Lookup_Table_bit10,
> ./Hidden_Lookup_Table_bit11,
> ./Hidden_Lookup_Table_bit12,
> ./Hidden_Lookup_Table_bit13,
> ./Hidden_Lookup_Table_bit14,
> ./Hidden_Lookup_Table_bit15))
> }"/>
>
> <xs:elementname="Hint_Name_Table_RVA"type="unsignedint31"dfdl:inputValueCalc="{
> unsignedint31(
> fn:concat(./Hidden_Lookup_Table_bit0,
> ./Hidden_Lookup_Table_bit1,
> ./Hidden_Lookup_Table_bit2,
> ./Hidden_Lookup_Table_bit3,
> ./Hidden_Lookup_Table_bit4,
> ./Hidden_Lookup_Table_bit5,
> ./Hidden_Lookup_Table_bit6,
> ./Hidden_Lookup_Table_bit7,
> ./Hidden_Lookup_Table_bit8,
> ./Hidden_Lookup_Table_bit9,
> ./Hidden_Lookup_Table_bit10,
> ./Hidden_Lookup_Table_bit11,
> ./Hidden_Lookup_Table_bit12,
> ./Hidden_Lookup_Table_bit13,
> ./Hidden_Lookup_Table_bit14,
> ./Hidden_Lookup_Table_bit15,
> ./Hidden_Lookup_Table_bit16,
> ./Hidden_Lookup_Table_bit17,
> ./Hidden_Lookup_Table_bit18,
> ./Hidden_Lookup_Table_bit19,
> ./Hidden_Lookup_Table_bit20,
> ./Hidden_Lookup_Table_bit21,
> ./Hidden_Lookup_Table_bit22,
> ./Hidden_Lookup_Table_bit23,
> ./Hidden_Lookup_Table_bit24,
> ./Hidden_Lookup_Table_bit25,
> ./Hidden_Lookup_Table_bit26,
> ./Hidden_Lookup_Table_bit27,
> ./Hidden_Lookup_Table_bit28,
> ./Hidden_Lookup_Table_bit29,
> ./Hidden_Lookup_Table_bit30
> ))
> }"/>
>
> <xs:groupname="hidden_Lookup_Table_Group">
> <xs:sequencedfdl:alignmentUnits="bits">
> <xs:elementname="Hidden_Lookup_Table_bit7"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit6"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit5"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit4"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit3"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit2"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit1"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit0"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit15"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit14"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit13"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit12"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit11"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit10"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit9"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit8"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit23"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit22"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit21"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit20"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit19"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit18"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit17"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit16"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit31"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit30"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit29"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit28"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit27"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit26"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit25"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> <xs:elementname="Hidden_Lookup_Table_bit24"type="unsignedint1"
> dfdl:outputValueCalc='{ . }'
> />
> </xs:sequence>
> </xs:group>
>