tuxji commented on a change in pull request #488:
URL: https://github.com/apache/incubator-daffodil/pull/488#discussion_r575692835



##########
File path: daffodil-runtime2/src/main/resources/c/libruntime/infoset.c
##########
@@ -160,10 +160,11 @@ walkInfosetNode(const VisitEventHandler *handler, const 
InfosetBase *infoNode)
                 handler->visitNumberElem(handler, childERD, numLocation);
             break;
         case CHOICE:
+            // Point next ERD to choice of alternative elements' ERDs
             if (!infoNode->erd->initChoice(infoNode, rootElement()))
             {
                 error_msg =
-                    "node's _choice field was not initialized during walk";
+                    "Walk error: no match between choice dispatch key and any 
branch key";

Review comment:
       Actually, daffodil_main.c calls walkInfoset() in two places (from both 
the parse and unparse use cases).  You're right that when we parse a binary 
data file, the parseSelf() function has already dealt with the choice 
(initChoice() is just re-initializing the _choice member field at this time).  
However, when we read an unparse XML file into an infoset in memory, we also 
walk the uninitialized infoset before we call unparseSelf() to write the 
unparsed binary data to the output file.  The walk validates each new XML 
element matches the schema's next infoset element and calls the correct number 
conversion function (float, integer, etc.).  The _choice member field is 
uninitialized at this time and I didn't know I could write a choice branch 
resolver which looks at the next XML element and figures out which branch does 
that element indicate exists inside the choice group.  I thought I would just 
call initChoice() from walkInfosetNode(), it would use the choice dispatch key 
to selec
 t the right branch, and then walkInfosetNode() would know what the next 
infoset element should be.  This behavior causes c-daffodil to behave more 
strictly than scala-daffodil; if the unparse XML file has no match between the 
choice dispatch key and any branch key, c-daffodil reports a no match 
processing error at this very place while scala-daffodil reports no error at 
all:
   
   ```shell
   $ emacs unparse.xml # change <tag>4</tag> to <tag>0</tag>
   $ make unparse-test
   ./daffodil unparse unparse.xml -o test_parse.dat
   ./daffodil: Walk error: no match between choice dispatch key and any branch 
key
   make: *** [Makefile:46: unparse-test] Error 1
   $ daffodil unparse -s nested.dfdl.xsd -r NestedUnion -o test_parse.dat 
unparse.xml # No errors
   $ diff parse.dat test_parse.dat # No errors, 4th byte is zero in both files
   ```
   
   Perhaps c-daffodil should load such an XML file without a no match 
processing error and unparse the infoset to a binary data file without a no 
match processing error.  We would have to code and call a choice branch 
resolver in C which peeks at the next XML element, figures out which branch 
does that element indicate exists inside the choice group, and initializes the 
choice and element runtime data (_choice and childNode->erd member fields) 
accordingly.  We probably would replace the initChoice() call in 
walkInfosetNode() with a call to that choice branch resolver and we might or 
might not call initChoice() in unparseSelf().  The reason I called initChoice() 
in all these places is that I thought we might want to remove the _choice 
member field and just call initChoice() to tell us the correct element to visit 
next in parse, walk, and unparse.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to