Class AsyncByteArrayScanner

All Implemented Interfaces:
AsyncByteArrayFeeder, AsyncInputFeeder, XmlConsts, NamespaceContext, XMLStreamConstants

public class AsyncByteArrayScanner extends AsyncByteScanner implements AsyncByteArrayFeeder
This is the base class for asynchronous (non-blocking) XML scanners. Due to basic complexity of async approach, character-based doesn't make much sense, so only byte-based input is supported.
  • Field Details

    • _inputBuffer

      protected byte[] _inputBuffer
      This buffer is actually provided by caller
    • _origBufferLen

      protected int _origBufferLen
      In addition to current buffer pointer, and end pointer, we will also need to know number of bytes originally contained. This is needed to correctly update location information when the block has been completed.
  • Constructor Details

    • AsyncByteArrayScanner

      public AsyncByteArrayScanner(ReaderConfig cfg)
  • Method Details

    • toString

      public String toString()
      Overrides:
      toString in class Object
    • _currentByte

      protected final byte _currentByte() throws XMLStreamException
      Specified by:
      _currentByte in class AsyncByteScanner
      Throws:
      XMLStreamException
    • _nextByte

      protected final byte _nextByte() throws XMLStreamException
      Specified by:
      _nextByte in class AsyncByteScanner
      Throws:
      XMLStreamException
    • _prevByte

      protected final byte _prevByte() throws XMLStreamException
      Specified by:
      _prevByte in class AsyncByteScanner
      Throws:
      XMLStreamException
    • parseCommentContents

      protected int parseCommentContents() throws XMLStreamException
      Throws:
      XMLStreamException
    • handleCommentPending

      protected int handleCommentPending() throws XMLStreamException
      Returns:
      EVENT_INCOMPLETE, if there's not enough input to handle pending char, COMMENT, if we handled complete "-->" end marker, or 0 to indicate something else was succesfully handled.
      Throws:
      XMLStreamException
    • parsePIData

      protected int parsePIData() throws XMLStreamException
      Throws:
      XMLStreamException
    • handlePIPending

      protected int handlePIPending() throws XMLStreamException
      Returns:
      EVENT_INCOMPLETE, if there's not enough input to handle pending char, PROCESSING_INSTRUCTION, if we handled complete "?>" end marker, or 0 to indicate something else was succesfully handled.
      Throws:
      XMLStreamException
    • handleDTDInternalSubset

      protected final boolean handleDTDInternalSubset(boolean init) throws XMLStreamException
      Specified by:
      handleDTDInternalSubset in class AsyncByteScanner
      Throws:
      XMLStreamException
    • parseCDataContents

      protected final int parseCDataContents() throws XMLStreamException
      Throws:
      XMLStreamException
    • handleCDataPending

      protected final int handleCDataPending() throws XMLStreamException
      Returns:
      EVENT_INCOMPLETE, if there's not enough input to handle pending char, CDATA, if we handled complete "]]>" end marker, or 0 to indicate something else was succesfully handled.
      Throws:
      XMLStreamException
    • startCharactersPending

      protected int startCharactersPending() throws XMLStreamException
      This method gets called, if the first character of a CHARACTERS event could not be fully read (multi-byte, split over buffer boundary). If so, there is some pending data to be handled.
      Throws:
      XMLStreamException
    • finishCharactersCoalescing

      protected final int finishCharactersCoalescing() throws XMLStreamException
      TODO: Method not yet implemented
      Throws:
      XMLStreamException
    • needMoreInput

      public final boolean needMoreInput()
      Description copied from interface: AsyncInputFeeder
      Method called to check whether it is ok to feed more data: parser returns true if it has no more content to parse (and it is ok to feed more); otherwise false (and no data should yet be fed).
      Specified by:
      needMoreInput in interface AsyncInputFeeder
    • feedInput

      public void feedInput(byte[] buf, int start, int len) throws XMLStreamException
      Description copied from interface: AsyncByteArrayFeeder
      Method that can be called to feed more data, if (and only if) AsyncInputFeeder.needMoreInput() returns true.
      Specified by:
      feedInput in interface AsyncByteArrayFeeder
      Parameters:
      buf - Byte array that containts data to feed: caller must ensure data remains stable until it is fully processed (which is true when AsyncInputFeeder.needMoreInput() returns true)
      start - Offset within array where input data to process starts
      len - Length of input data within array to process.
      Throws:
      XMLStreamException - if the state is such that this method should not be called (has not yet consumed existing input data, or has been marked as closed)
    • nextFromTree

      public int nextFromTree() throws XMLStreamException
      Specified by:
      nextFromTree in class XmlScanner
      Throws:
      XMLStreamException
    • handleCData

      private int handleCData() throws XMLStreamException
      Throws:
      XMLStreamException
    • handleCDataStartMarker

      private int handleCDataStartMarker(byte b) throws XMLStreamException
      Throws:
      XMLStreamException
    • handlePI

      protected int handlePI() throws XMLStreamException
      Specified by:
      handlePI in class AsyncByteScanner
      Throws:
      XMLStreamException
    • handleComment

      protected final int handleComment() throws XMLStreamException
      Specified by:
      handleComment in class AsyncByteScanner
      Throws:
      XMLStreamException
    • asyncSkipSpace

      protected boolean asyncSkipSpace() throws XMLStreamException
      Method to skip whatever space can be skipped.

      NOTE: if available content ends with a CR, method will set _pendingInput to PENDING_STATE_CR.

      Specified by:
      asyncSkipSpace in class AsyncByteScanner
      Returns:
      True, if was able to skip through the space and find a non-space byte; false if reached end-of-buffer
      Throws:
      XMLStreamException
    • handleEntityStartingToken

      protected int handleEntityStartingToken() throws XMLStreamException
      Method called when a new token (within tree) starts with an entity.
      Returns:
      Type of event to return
      Throws:
      XMLStreamException
    • handleNamedEntityStartingToken

      protected int handleNamedEntityStartingToken() throws XMLStreamException
      Method called when we see an entity that is starting a new token, and part of its name has been decoded (but not all)
      Throws:
      XMLStreamException
    • handleNumericEntityStartingToken

      protected int handleNumericEntityStartingToken() throws XMLStreamException
      Method called to handle cases where we find something other than a character entity (or one of 4 pre-defined general entities that act like character entities)
      Throws:
      XMLStreamException
    • decodeHexEntity

      protected final boolean decodeHexEntity() throws XMLStreamException
      Returns:
      True if entity was decoded (and value assigned to _entityValue; false otherwise
      Throws:
      XMLStreamException
    • decodeDecEntity

      protected final boolean decodeDecEntity() throws XMLStreamException
      Returns:
      True if entity was decoded (and value assigned to _entityValue; false otherwise
      Throws:
      XMLStreamException
    • decodeGeneralEntity

      protected final int decodeGeneralEntity(PName entityName) throws XMLStreamException
      Method that verifies that given named entity is followed by a semi-colon (meaning next byte must be available for reading); and if so, whether it is one of pre-defined general entities.
      Returns:
      Character of the expanded pre-defined general entity (if name matches one); zero if not.
      Throws:
      XMLStreamException
    • handleStartElementStart

      protected int handleStartElementStart(byte b) throws XMLStreamException
      Method called when '<' and (what appears to be) a name start character have been seen.
      Specified by:
      handleStartElementStart in class AsyncByteScanner
      Throws:
      XMLStreamException
    • handleStartElement

      protected int handleStartElement() throws XMLStreamException
      Specified by:
      handleStartElement in class AsyncByteScanner
      Throws:
      XMLStreamException
    • initStartElement

      private void initStartElement(PName elemName)
    • initAttribute

      private void initAttribute(byte quoteChar)
    • finishStartElement

      private int finishStartElement(boolean emptyTag) throws XMLStreamException
      Method called to wrap up settings when the whole start (or empty) element has been parsed.
      Throws:
      XMLStreamException
    • handleEndElementStart

      private int handleEndElementStart() throws XMLStreamException
      Throws:
      XMLStreamException
    • handleEndElement

      private int handleEndElement() throws XMLStreamException
      This method is "slow" version of above, used when name of the end element can split input buffer boundary
      Throws:
      XMLStreamException
    • startCharacters

      protected final int startCharacters(byte b) throws XMLStreamException
      Description copied from class: AsyncByteScanner
      Method called to initialize state for CHARACTERS event, after just a single byte has been seen. What needs to be done next depends on whether coalescing mode is set or not: if it is not set, just a single character needs to be decoded, after which current event will be incomplete, but defined as CHARACTERS. In coalescing mode, the whole content must be read before current event can be defined. The reason for difference is that when XMLStreamReader.next() returns, no blocking can occur when calling other methods.
      Specified by:
      startCharacters in class AsyncByteScanner
      Returns:
      Event type detected; either CHARACTERS, if at least one full character was decoded (and can be returned), EVENT_INCOMPLETE if not (part of a multi-byte character split across input buffer boundary)
      Throws:
      XMLStreamException
    • finishCharacters

      protected final void finishCharacters() throws XMLStreamException
      This method only gets called in non-coalescing mode; and if so, needs to parse as many characters of the current text segment from the current input block as possible.
      Specified by:
      finishCharacters in class AsyncByteScanner
      Throws:
      XMLStreamException
    • handleEntityInCharacters

      protected int handleEntityInCharacters() throws XMLStreamException
      Method called to handle entity encountered inside CHARACTERS segment, when trying to complete a non-coalescing text segment.

      NOTE: unlike with generic parsing of named entities, where trailing semicolon needs to be left in place, here we should just process it right away.

      Returns:
      Expanded (character) entity, if positive number; 0 if incomplete.
      Throws:
      XMLStreamException
    • handleDecEntityInCharacters

      protected int handleDecEntityInCharacters(int ptr) throws XMLStreamException
      Throws:
      XMLStreamException
    • handleHexEntityInCharacters

      protected int handleHexEntityInCharacters(int ptr) throws XMLStreamException
      Throws:
      XMLStreamException
    • handleAndAppendPending

      private final boolean handleAndAppendPending() throws XMLStreamException
      Method called to handle split multi-byte character, by decoding it and appending to the text buffer, if possible.
      Returns:
      True, if split character was completely handled; false if not
      Throws:
      XMLStreamException
    • skipCharacters

      protected boolean skipCharacters() throws XMLStreamException
      Method that will be called to skip all possible characters from the input buffer, but without blocking. Partial characters are not to be handled (not pending input is to be added).
      Specified by:
      skipCharacters in class AsyncByteScanner
      Returns:
      True, if skipping ending with an unexpanded entity; false if not
      Throws:
      XMLStreamException
    • skipPending

      private final boolean skipPending() throws XMLStreamException
      Throws:
      XMLStreamException
    • skipEntityInCharacters

      private int skipEntityInCharacters() throws XMLStreamException
      Method called to handle entity encountered inside CHARACTERS segment, when trying to complete a non-coalescing text segment.
      Returns:
      Expanded (character) entity, if positive number; 0 if incomplete.
      Throws:
      XMLStreamException
    • skipCoalescedText

      protected boolean skipCoalescedText() throws XMLStreamException
      Coalescing mode is (and will) not be implemented for non-blocking parsers, so this method should never get called.
      Specified by:
      skipCoalescedText in class XmlScanner
      Returns:
      True, if an unexpanded entity was encountered (and is now pending)
      Throws:
      XMLStreamException
    • handleAttrValue

      protected boolean handleAttrValue() throws XMLStreamException
      Specified by:
      handleAttrValue in class AsyncByteScanner
      Returns:
      True, if the whole value was read; false if only part (due to buffer ending)
      Throws:
      XMLStreamException
    • handleAttrValuePending

      private final boolean handleAttrValuePending() throws XMLStreamException
      Returns:
      True if the partial information was succesfully handled; false if not
      Throws:
      XMLStreamException
    • handleAttrValuePendingUTF8

      private final int handleAttrValuePendingUTF8() throws XMLStreamException
      Throws:
      XMLStreamException
    • handleDecEntityInAttribute

      private final int handleDecEntityInAttribute(boolean starting) throws XMLStreamException
      Throws:
      XMLStreamException
    • handleHexEntityInAttribute

      private final int handleHexEntityInAttribute(boolean starting) throws XMLStreamException
      Throws:
      XMLStreamException
    • handleEntityInAttributeValue

      protected int handleEntityInAttributeValue() throws XMLStreamException
      Method called to handle entity encountered inside attribute value.
      Returns:
      Value of expanded character entity, if processed (which must be 1 or above); 0 for general entity, or -1 for "not enough input"
      Throws:
      XMLStreamException
    • handleNsDecl

      protected boolean handleNsDecl() throws XMLStreamException
      Specified by:
      handleNsDecl in class AsyncByteScanner
      Throws:
      XMLStreamException
    • handleNsValuePending

      private final boolean handleNsValuePending() throws XMLStreamException
      Returns:
      True if the partial information was succesfully handled; false if not
      Throws:
      XMLStreamException
    • parseNewName

      protected final PName parseNewName(byte b) throws XMLStreamException
      Specified by:
      parseNewName in class AsyncByteScanner
      Throws:
      XMLStreamException
    • parsePName

      protected final PName parsePName() throws XMLStreamException
      This method can (for now?) be shared between all Ascii-based encodings, since it only does coarse validity checking -- real checks are done in different method.

      Some notes about assumption implementation makes:

      • Well-formed xml content can not end with a name: as such, end-of-input is an error and we can throw an exception
      Specified by:
      parsePName in class AsyncByteScanner
      Throws:
      XMLStreamException
    • parseNewEntityName

      protected final PName parseNewEntityName(byte b) throws XMLStreamException
      Throws:
      XMLStreamException
    • parseEntityName

      protected final PName parseEntityName() throws XMLStreamException
      Throws:
      XMLStreamException
    • handlePartialCR

      protected final boolean handlePartialCR()
      Method called when there is a pending \r (from past buffer), and we need to see
      Specified by:
      handlePartialCR in class AsyncByteScanner
      Returns:
      True if the linefeed was succesfully processed (had enough input data to do that); or false if there is no data available to check this
    • decodeUtf8_2

      protected final int decodeUtf8_2(int c) throws XMLStreamException

      Note: caller must guarantee enough data is available before calling the method

      Throws:
      XMLStreamException
    • skipUtf8_2

      protected final void skipUtf8_2(int c) throws XMLStreamException
      Throws:
      XMLStreamException
    • decodeUtf8_3

      protected final int decodeUtf8_3(int c1) throws XMLStreamException

      Note: caller must guarantee enough data is available before calling the method

      Throws:
      XMLStreamException
    • decodeUtf8_3

      protected final int decodeUtf8_3(int c1, int c2, int c3) throws XMLStreamException
      Throws:
      XMLStreamException
    • decodeUtf8_4

      protected final int decodeUtf8_4(int c) throws XMLStreamException
      Throws:
      XMLStreamException
    • decodeUtf8_4

      protected final int decodeUtf8_4(int c1, int c2, int c3, int c4) throws XMLStreamException
      Returns:
      Character value minus 0x10000; this so that caller can readily expand it to actual surrogates
      Throws:
      XMLStreamException