Class AsyncByteBufferScanner

  • All Implemented Interfaces:
    AsyncByteBufferFeeder, AsyncInputFeeder, XmlConsts, javax.xml.namespace.NamespaceContext, javax.xml.stream.XMLStreamConstants

    public class AsyncByteBufferScanner
    extends AsyncByteScanner
    implements AsyncByteBufferFeeder
    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 Detail

      • _inputBuffer

        protected java.nio.ByteBuffer _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 Detail

      • AsyncByteBufferScanner

        public AsyncByteBufferScanner​(ReaderConfig cfg)
    • Method Detail

      • toString

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

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

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

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

        protected int parseCommentContents()
                                    throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleCommentPending

        protected int handleCommentPending()
                                    throws javax.xml.stream.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 successfully handled.
        Throws:
        javax.xml.stream.XMLStreamException
      • parsePIData

        protected int parsePIData()
                           throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handlePIPending

        protected int handlePIPending()
                               throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleDTDInternalSubset

        protected final boolean handleDTDInternalSubset​(boolean init)
                                                 throws javax.xml.stream.XMLStreamException
        Specified by:
        handleDTDInternalSubset in class AsyncByteScanner
        Throws:
        javax.xml.stream.XMLStreamException
      • parseCDataContents

        protected final int parseCDataContents()
                                        throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleCDataPending

        protected final int handleCDataPending()
                                        throws javax.xml.stream.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 successfully handled.
        Throws:
        javax.xml.stream.XMLStreamException
      • startCharactersPending

        protected int startCharactersPending()
                                      throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • finishCharactersCoalescing

        protected final int finishCharactersCoalescing()
                                                throws javax.xml.stream.XMLStreamException
        TODO: Method not yet implemented
        Throws:
        javax.xml.stream.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​(java.nio.ByteBuffer buffer)
                       throws javax.xml.stream.XMLStreamException
        Description copied from interface: AsyncByteBufferFeeder
        Method that can be called to feed more data, if (and only if) AsyncInputFeeder.needMoreInput() returns true.
        Specified by:
        feedInput in interface AsyncByteBufferFeeder
        Parameters:
        buffer - Buffer that contains additional input to read
        Throws:
        javax.xml.stream.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 javax.xml.stream.XMLStreamException
        Specified by:
        nextFromTree in class XmlScanner
        Throws:
        javax.xml.stream.XMLStreamException
      • handleCData

        private int handleCData()
                         throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleCDataStartMarker

        private int handleCDataStartMarker​(byte b)
                                    throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handlePI

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

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

        protected boolean asyncSkipSpace()
                                  throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleEntityStartingToken

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

        protected int handleNamedEntityStartingToken()
                                              throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleNumericEntityStartingToken

        protected int handleNumericEntityStartingToken()
                                                throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • decodeHexEntity

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

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

        protected final int decodeGeneralEntity​(PName entityName)
                                         throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleStartElementStart

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

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

        private void initStartElement​(PName elemName)
      • initAttribute

        private void initAttribute​(byte quoteChar)
      • finishStartElement

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

        private int handleEndElementStart()
                                   throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleEndElement

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

        protected final int startCharacters​(byte b)
                                     throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • finishCharacters

        protected final void finishCharacters()
                                       throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleEntityInCharacters

        protected int handleEntityInCharacters()
                                        throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleDecEntityInCharacters

        protected int handleDecEntityInCharacters​(int ptr)
                                           throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleHexEntityInCharacters

        protected int handleHexEntityInCharacters​(int ptr)
                                           throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleAndAppendPending

        private final boolean handleAndAppendPending()
                                              throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • skipCharacters

        protected boolean skipCharacters()
                                  throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • skipPending

        private final boolean skipPending()
                                   throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • skipEntityInCharacters

        private int skipEntityInCharacters()
                                    throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • skipCoalescedText

        protected boolean skipCoalescedText()
                                     throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleAttrValue

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

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

        private final int handleAttrValuePendingUTF8()
                                              throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleDecEntityInAttribute

        private final int handleDecEntityInAttribute​(boolean starting)
                                              throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleHexEntityInAttribute

        private final int handleHexEntityInAttribute​(boolean starting)
                                              throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • handleEntityInAttributeValue

        protected int handleEntityInAttributeValue()
                                            throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • handleNsDecl

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

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

        protected final PName parseNewName​(byte b)
                                    throws javax.xml.stream.XMLStreamException
        Specified by:
        parseNewName in class AsyncByteScanner
        Throws:
        javax.xml.stream.XMLStreamException
      • parsePName

        protected final PName parsePName()
                                  throws javax.xml.stream.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:
        javax.xml.stream.XMLStreamException
      • parseNewEntityName

        protected final PName parseNewEntityName​(byte b)
                                          throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • parseEntityName

        protected final PName parseEntityName()
                                       throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.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 javax.xml.stream.XMLStreamException

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

        Throws:
        javax.xml.stream.XMLStreamException
      • skipUtf8_2

        protected final void skipUtf8_2​(int c)
                                 throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • decodeUtf8_3

        protected final int decodeUtf8_3​(int c1)
                                  throws javax.xml.stream.XMLStreamException

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

        Throws:
        javax.xml.stream.XMLStreamException
      • decodeUtf8_3

        protected final int decodeUtf8_3​(int c1,
                                         int c2,
                                         int c3)
                                  throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • decodeUtf8_4

        protected final int decodeUtf8_4​(int c)
                                  throws javax.xml.stream.XMLStreamException
        Throws:
        javax.xml.stream.XMLStreamException
      • decodeUtf8_4

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