|
Extension SDK 10.1.2 | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
The ReadTextBuffer
interface provides a subset of the TextBuffer
methods for read-only access to text data. The parser package is written to use this interface for accessing the text data of a document instead of a flat char[]
to give flexibility to parser clients in the design of their text data model.
Note that getChar()
, getChars()
, getString()
and getText()
are declared to throw an IndexOutOfBoundsException
for invalid offset/length parameters. This means that TextBuffer
implementations are not required to provide range checking on offset or length parameters (and are actually encouraged not to.)
This also means that TextBuffer
clients must either do their own range checking, or be prepared to catch the IndexOutOfBoundsException
(which is a RuntimeException
.) All clients in the parser package must catch the IndexOutOfBoundsException
.
Design Decisions:
The answer to this question actually depends on the use scenario. Since this interface is being used for the parser, we examined the length of buffers that will be parsed. The average Java file in JDK 1.3 is around 10k, while the average Java file in the oracle.jdeveloper
package is around 4k. Considering that the exception when we encounter the end of the buffer while parsing, is throwing and catching the exception more expensive than 10,000 range checks?
Again, we did some informal measurements of the cost of throwing and catching an exception versus performing a range check (which generally does not expect to encounter an error), the cost of the exception was comparable to 400 if checks.
Since most of the files we expect to parse will be reasonably long (>1k), it makes sense to dispense with the range checks in this TextBuffer
interface.
TextBuffer
interface instead of a flat char[]
?
It turns out that the overhead of using a TextBuffer
interface to access the buffer data is not very great, provided no range checking is done. If you compare the running time of the following loop:
int bufferSize = buffer.length; // buffer is char[] for ( int i = 0; i < bufferSize; i++ ) { if ( buffer[i] == '\n' ) { // do something } }
versus the running time of:
int bufferSize = buffer.getLength(); // buffer is TextBuffer for ( int i = 0; i < bufferSize; i++ ) { if ( buffer.getChar( i ) == '\n' ) { // do something } }
it turns out that using the TextBuffer
interface is not too much slower than using the char[]
directly. With some informal measurements (System.currentTimeMillis()
using a large buffer), using the TextBuffer
interface takes about 10-25% longer than a straight char[]
depending on the VM (10% for Hotspot, 25% for OJVM.)
Note that this interface contains read locking routines though it is not strictly necessary for a read-only interface. In fact, the readLock()
and readUnlock()
implementations for a ReadTextBuffer
backed by a char[]
or String
are NOP implementations. These two methods are here (instead of in TextBuffer
) to support clients that must work with both ReadTextBuffers
and TextBuffer
instances in a uniform way, such as JOT in JDeveloper.
If you know that the underlying text buffer is backed by a char[]
or String
, and was created using TextBufferFactory.createReadTextBuffer()
, then locking is not needed. If you are not sure, use the readLock()
and readUnlock()
calls to be safe.
Method Summary | |
char |
getChar(int offset) Fetches the character from the given offset. |
char[] |
getChars(int offset, int length) Fetches a number of characters from the indicated offset in the buffer. |
int |
getLength() Fetches the number of characters in this buffer. |
java.lang.String |
getString(int offset, int length) Fetches a number of characters from the indicated offset in the buffer and returns it as a String. |
void |
getText(int offset, int length, javax.swing.text.Segment segment) Fetches the text contained within the given section of the TextBuffer The Segment object is provided by the caller. |
void |
readLock() Attempts to acquire a read lock on this text buffer for the purposes of reading the buffer - this is a blocking call. |
void |
readUnlock() Releases a held read lock on this text buffer. |
Method Detail |
public int getLength()
public char getChar(int offset) throws java.lang.IndexOutOfBoundsException
offset
- the offset in the buffer to get the character fromjava.lang.IndexOutOfBoundsException
- if offset is invalidpublic char[] getChars(int offset, int length) throws java.lang.IndexOutOfBoundsException
offset
- the offset in the buffer to start fromlength
- number of characters to fetchjava.lang.IndexOutOfBoundsException
- if offset or length are invalidpublic java.lang.String getString(int offset, int length) throws java.lang.IndexOutOfBoundsException
offset
- the offset in the buffer to start fromlength
- number of characters to fetchjava.lang.IndexOutOfBoundsException
- if offset or length are invalidpublic void getText(int offset, int length, javax.swing.text.Segment segment) throws java.lang.IndexOutOfBoundsException
TextBuffer
The Segment
object is provided by the caller.offset
- the offset into the buffer representing the desired start of the data >= 0length
- the length of the desired data >= 0segment
- the caller's Segment object to return the data injava.lang.IndexOutOfBoundsException
Document.getText(int, int)
public void readLock()
Note that for TextBuffer
objects, a call to readLock() must be matched by a call to readUnlock() even if nested within a writeLock()/writeUnlock(). This is to help guarantee correctness.
TextBuffer.getLineMap()
, TextBuffer.writeLock()
public void readUnlock()
|
Extension SDK | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Copyright © 1997, 2004, Oracle. All rights reserved.