I've been working on DAFFODIL-2429, which is adding a "direction" property to 
defineVariable. I believe I have most of the implementation in place. It is 
primarily implemented as follows:

dfdl:defineVariable has a property "dfdlx:direction" which is an enumeration 
with the following values: "parseOnly", "unparseOnly", or "both" which is the 
default value.

When we are compiling the schema and are about to generate a SetVariabler or 
NewVariableInstance parser/unparser, we check the "direction" property and if 
the direction does not match (ie. Creating a SetVariable parser when the 
variable in question is "unparseOnly") we instead create a NadaParser.

I'm not 100% sure that this is necessarily the correct approach, but it doesn't 
break any existing tests. Speaking of tests, I am attempting to create a test 
to demonstrate this feature based off the pull request mentioned in the bug 
ticket: https://github.com/DFDLSchemas/PCAP/pull/10

The schema for my test is as follows:

    <dfdl:defineVariable name="remainingAddr" type="xs:string" 
dfdlx:direction="unparseOnly" />
    <xs:element name="root">
      <xs:complexType>
        <xs:sequence>
          <xs:annotation>
            <xs:appinfo source="http://www.ogf.org/dfdl/";>
              <dfdl:newVariableInstance ref="ex:remainingAddr" defaultValue="{ 
ex:IPsrc }" />
            </xs:appinfo>
          </xs:annotation>
          <xs:element name="byte1" type="xs:unsignedByte" 
dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, 
'.')) }" />
          <xs:sequence>
            <xs:annotation>
              <xs:appinfo source="http://www.ogf.org/dfdl/";>
                <dfdl:newVariableInstance ref="ex:remainingAddr" 
defaultValue="{ fn:substring-after($ex:remainingAddr, '.') }" />
              </xs:appinfo>
            </xs:annotation>
            <xs:element name="byte2" type="xs:unsignedByte" 
dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, 
'.')) }" />
            <xs:sequence>
              <xs:annotation>
                <xs:appinfo source="http://www.ogf.org/dfdl/";>
                  <dfdl:newVariableInstance ref="ex:remainingAddr" 
defaultValue="{ fn:substring-after($ex:remainingAddr, '.') }" />
                </xs:appinfo>
              </xs:annotation>
              <xs:element name="byte3" type="xs:unsignedByte" 
dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, 
'.')) }" />
              <xs:sequence>
                <xs:annotation>
                  <xs:appinfo source="http://www.ogf.org/dfdl/";>
                    <dfdl:newVariableInstance ref="ex:remainingAddr" 
defaultValue="{ fn:substring-after($ex:remainingAddr, '.') }" />
                  </xs:appinfo>
                </xs:annotation>
                <xs:element name="byte4" type="xs:unsignedByte" 
dfdl:outputValueCalc="{ xs:unsignedByte(fn:substring-before($ex:remainingAddr, 
'.')) }" />
              </xs:sequence>
            </xs:sequence>
          </xs:sequence>
          <xs:element name="IPsrc" type="xs:string" dfdl:lengthKind="explicit" 
dfdl:length="7"
            dfdl:inputValueCalc="{ fn:concat(../ex:byte1, '.', ../ex:byte2, 
'.', ../ex:byte3, '.', ../ex:byte4) }" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

This is pretty much a direct copy of the schema in the pull request that on 
parse will parse 4 bytes and then use an inputValueCalc to combine the 4 bytes 
into an IP address. On unparse outputValueCalc's is used to pull apart the 
combined address back into the individual bytes. During unparse, the byte* 
elements do a forward reference to IPsrc and this seems to be causing a problem 
in my test. I'm getting a "Unparse Error: Expression Evaluation Error: Child 
element {http://example.com}IPsrc does not exist".

So, my question regarding the test is should this work or am I missing 
something that is preventing this forward reference from working during 
unparsing?

Josh Adams

Reply via email to