|
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 from
java.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 fetch
java.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 fetch
java.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 in
java.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.