@Override protected boolean atEndOfStream() { return streamedText.atEndOfStream(); } }
/** * Returns the character at the specified index. * @param index the index of the character. * @return the character at the specified index, or END_OF_STREAM if the end of stream has been reached. */ public char charAt(final int pos) { if (pos>=readerPos) readToPosition(pos); if (!checkPos(pos)) { atEndOfStream=true; return END_OF_STREAM; } return buffer[pos-bufferBegin]; }
/** * Returns the current size of the internal character buffer. * <p> * This information is generally useful only for investigating memory and performance issues. * * @return the current size of the internal character buffer. */ public int getBufferSize() { return streamedText.getBuffer().length; }
? nextParsedSegment.getEnd() : nextParsedSegment.getBegin()+1; final int searchEnd=coalescing ? streamedText.getEnd() : streamedText.getBufferOverflowPosition(); while (i<searchEnd) { final char ch=streamedText.charAt(i); if (ch==StreamedText.END_OF_STREAM && streamedText.atEndOfStream()) break; // checking ch==StreamedText.END_OF_STREAM first is superfluous but is probably faster than calling atEndOfStream() in the normal case. if (ch=='&') { if (i>=source.fullSequentialParseData[0]) { // do not handle character references inside tags or script elements if (i<streamedText.getEnd()) {
private void readToPosition(final int pos) { try { if (pos>=bufferBegin+buffer.length) { if (pos>=minRequiredBufferBegin+buffer.length) { if (!expandableBuffer) throw new BufferOverflowException(); // unfortunately BufferOverflowException doesn't accept a message argument, otherwise it would include the message "StreamedText buffer too small to keep positions "+minRequiredBufferBegin+" and "+pos+" simultaneously" expandBuffer(pos-minRequiredBufferBegin+1); } discardUsedText(); if (pos>=end) return; // don't continue on to throw IndexOutOfBoundsException } while (readerPos<=pos) { final int charCount=reader.read(buffer,readerPos-bufferBegin,bufferBegin+buffer.length-readerPos); if (charCount==-1) { end=readerPos; return; } readerPos+=charCount; } } catch (IOException ex) { throw new RuntimeException(ex); } }
/** * Constructs a new <code>StreamedSource</code> object from the specified text. * <p> * Although the <code>CharSequence</code> argument of this constructor apparently contradicts the notion of streaming in the source text, * it can still benefits over the equivalent use of the standard {@link Source} class. * <p> * Firstly, using the <code>StreamedSource</code> class to iterate the nodes of an in-memory <code>CharSequence</code> source document still requires much less memory * than the equivalent operation using the standard {@link Source} class. * <p> * Secondly, the specified <code>CharSequence</code> object could possibly implement its own paging mechanism to minimise memory usage. * <p> * If the specified <code>CharSequence</code> is mutable, its state must not be modified while the <code>StreamedSource</code> is in use. * * @param text the source text. */ public StreamedSource(final CharSequence text) { reader=null; streamedText=new StreamedText(text); streamedParseText=new StreamedParseText(streamedText); source=new Source(text,streamedParseText,null,"Document specified encoding can not be determined automatically from a streamed source",null); }
/** * Returns a new character sequence that is a subsequence of this sequence. * <p> * The returned <code>CharSequence</code> is only guaranteed to be valid as long as no futher operations are performed on this <code>StreamedText</code> object. * Any subsequent method call could invalidate the underlying buffer used by the <code>CharSequence</code>. * * @param begin the begin position, inclusive. * @param end the end position, exclusive. * @return a new character sequence that is a subsequence of this sequence. */ public CharSequence subSequence(final int begin, final int end) { // This has not been benchmarked. It is possible that returning substring(begin,end) results in faster code even though it requires more memory allocation. return getCharBuffer(begin,end); }
@Override protected int getEnd() { return streamedText.getEnd(); }
private StreamedSource(final Reader reader, final boolean isInternallyCreatedReader, final String encoding, final String encodingSpecificationInfo, final String preliminaryEncodingInfo) throws IOException { this.reader=reader; if (isInternallyCreatedReader) internallyCreatedReaderFinalizer=new InternallyCreatedReaderFinalizer(reader); streamedText=new StreamedText(reader); streamedParseText=new StreamedParseText(streamedText); source=new Source(streamedText,streamedParseText,encoding,encodingSpecificationInfo,preliminaryEncodingInfo); }
/** * Returns a <code>CharBuffer</code> containing the source text of the {@linkplain #getCurrentSegment() current segment}. * <p> * The returned <code>CharBuffer</code> provides a window into the internal <code>char[]</code> buffer including the position and length that spans the * {@linkplain #getCurrentSegment() current segment}. * <p> * For example, the following code writes the source text of the current segment to <code>writer</code>: * <p> * <code>CharBuffer charBuffer=streamedSource.getCurrentSegmentCharBuffer();</code><br /> * <code>writer.write(charBuffer.array(),charBuffer.position(),charBuffer.length());</code> * <p> * This may provide a performance benefit over the standard way of accessing the source text of the current segment, * which is to use the <code>CharSequence</code> interface of the segment directly, or to call {@link Segment#toString()}. * <p> * Because this <code>CharBuffer</code> is a direct window into the internal buffer of the <code>StreamedSource</code>, the contents of the * <code>CharBuffer.array()</code> must not be modified, and the array is only guaranteed to hold the segment source text until the * iterator's <code>hasNext()</code> or <code>next()</code> method is next called. * * @return a <code>CharBuffer</code> containing the source text of the {@linkplain #getCurrentSegment() current segment}. */ public CharBuffer getCurrentSegmentCharBuffer() { return streamedText.getCharBuffer(currentSegment.getBegin(),currentSegment.end); }
private boolean prepareBufferRange(final int begin, final int end) { final int lastRequiredPos=end-1; if (lastRequiredPos>readerPos) readToPosition(lastRequiredPos); return checkPos(begin) && end<=this.end; // false if end of stream reached before end position }