Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fix typos.

...

ContentHandlergetContentHandler()
Return the current content handler.
DTDHandlergetDTDHandler()
Return the current DTD handler.
EntityResolvergetEntityResolver()
Return the current entity resolver.
ErrorHandlergetErrorHandler()
Return the current error handler.
booleangetFeature(String name)
Look up the value of a feature flag. The only two features that are implemented are http://xml.org/sax/features/namespaces and http://xml.org/sax/features/namespace-prefixes as required by the XMLReader interface. All other features shall throw a SAXNotRecognizedException.
ObjectgetProperty(String name)
No propertyies are supported–this shall always throw a SAXNotRecognizedException.
voidparse(InputSource input)
Parse data from an InputSource. The InputSource must be backed by an InputStream. The getByteStream() method must return non-null or an IOException shall be thrown. This shall call the custom parse(InputStream)  method described below.
voidparse(String systemId)
This function is not supported. If called, this shall throw an IOException.
voidsetContentHandler(ContentHandler handler)
Store the parameter in local state. This handler will receive the SAX events created by Daffodil.
voidsetDTDHandler(DTDHandler handler)
Store the parameter in local state. Note that Daffodil will never use the DTDHandler except for when getDTDHandler()  is called.
voidsetEntityResolver(EntityResolver resolver)
Store the parameter in local state. Note that Daffodil will never use the DTDHandler EntityResolver except for when getEntityResolver()  is called.
voidsetErrorHandler(ErrorHandler handler)
Store the parmaeter in local state. The handler.fatalError()  callback is used for Schema Definition Errors. The handler.warning()  callback is used for Schema Definition Warnings.
voidsetFeature(String name, boolean value)
Set the value of a feature flag. The only two features that are implemented are http://xml.org/sax/features/namespaces and http://xml.org/sax/features/namespace-prefixes as required by the XMLReader interface. All other features shall throw a SAXNotRecognizedException.
voidsetProperty(String name, Object value)
No properties are supported–this shall always throw a SAXNotRecognizedException.

...

The Scala Coroutines library allows for pausing the execution of a subroutine to temporarily yeild yield to the caller, and allow the caller to resume the coroutine back to where it paused earlier. This library will be used to coordinate the interactions between the ContentHandler and the SAXInfosetInputter.

...

Code Block
scala
scala
class DaffodilContentHandler(dp: DataProcessor, output: OutputStream) extends ContentHandler {
  
  private val nextEvent = new EventState()

  private val inputter = new SAXInfosetInputter()

  private val unparseCoroutine = coroutine { (inputter, output) =>
    dp.unparse(inputter, output)
  }

  private def handleUpdatedEvent(....) {
    // currently trying to answer hasNext, trying to find a
    // complete InfosetInputter event before we can asnwer
    Assert(unparseCoroutine.value == HAS_NEXT)
    if (nextEvent.isComplete) {
      inputter.hasNext = true
      unparseCoroutine.resume
      while (unparseCoroutine.value == HAS_NEXT) {
        // keep resuming if unparse keeps asking hasNext, answer won't change
        unparseCoroutine.resume
      }
      Assert(unparseCoroutine.value == NEXT)
      nextEvent.copyToInputter(inputter)
      nextEvent.reset
      unparseCoroutine.resume
      Assert(unparseCoroutine.value == HAS_NEXT)
      // now looking for next complete event, keep handling SAX events
      // until we gather a complete event
    } else {
      // do not have a complete event yet, keep handling SAX events
      // until we gather a complete event
    }
  }

  def startDocument() {
    // Start the coroutine
    call(unparseCoroutine(inputter, output))
    unparseCoroutine.resume

    nextEvent.updateEvent(START_DOCUMENT)
    handleUpdatedEvent()
  }

  def endDocument() {
    nextEvent.updateEvent(END_DOCUMENT)
    handleUpdatedEvent()
    inputter.hasNext = false
    unparseCoroutine.resume
    val res = unaprseCoroutine.result
    ...
  }

  def someSaxEvent(...) {
    nextEvent.updateEvent(...)
    handleUpdatedEvent()
  }

}

class SAXInfosetInputter(event: Event) {

  // mutable infoset inputters state
  var hasNext: Boolean = false
  var eventType: InfosetInputterEventType = _
  var localName: String = _
  var simpleText: String = _
  ...

  def hasNext: Boolean = {
    yeildvalyieldval(HAS_NEXT)
    hasNext
  }

  def next(): Unit = {
    yeildvalyieldval(NEXT)
  }

  def getEventType: InfosetInputterEventType = eventType
  def getLocalName: String = localName
  ...
}

...