001: /*
002: * This is based on the text editor demonstration class that comes with
003: * the Ostermiller Syntax Highlighter Copyright (C) 2001 Stephen Ostermiller
004: * http://ostermiller.org/contact.pl?regarding=Syntax+Highlighting
005:
006: * Modifications copyright (C) 2003 Colin Bell
007: * colbell@users.sourceforge.net
008: *
009: *
010: * This program is free software; you can redistribute it and/or
011: * modify it under the terms of the GNU General Public License
012: * as published by the Free Software Foundation; either version 2
013: * of the License, or any later version.
014: *
015: * This program is distributed in the hope that it will be useful,
016: * but WITHOUT ANY WARRANTY; without even the implied warranty of
017: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: * GNU General Public License for more details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with this program; if not, write to the Free Software
022: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
023: */
024: package net.sourceforge.squirrel_sql.plugins.syntax.oster;
025:
026: import java.io.Reader;
027:
028: import javax.swing.text.AbstractDocument;
029: import javax.swing.text.BadLocationException;
030:
031: /**
032: * A reader interface for an abstract document. Since
033: * the syntax highlighting packages only accept Stings and
034: * Readers, this must be used.
035: * Since the close() method does nothing and a seek() method
036: * has been added, this allows us to get some performance
037: * improvements through reuse. It can be used even after the
038: * lexer explicitly closes it by seeking to the place that
039: * we want to read next, and reseting the lexer.
040: */
041: class DocumentReader extends Reader {
042:
043: /**
044: * Modifying the document while the reader is working is like
045: * pulling the rug out from under the reader. Alerting the
046: * reader with this method (in a nice thread safe way, this
047: * should not be called at the same time as a read) allows
048: * the reader to compensate.
049: */
050: public void update(int position, int adjustment) {
051: if (position < this .position) {
052: if (this .position < position - adjustment) {
053: this .position = position;
054: } else {
055: this .position += adjustment;
056: }
057: }
058: }
059:
060: /**
061: * Current position in the document. Incremented
062: * whenever a character is read.
063: */
064: private long position = 0;
065:
066: /**
067: * Saved position used in the mark and reset methods.
068: */
069: private long mark = -1;
070:
071: /**
072: * The document that we are working with.
073: */
074: private AbstractDocument document;
075:
076: /**
077: * Construct a reader on the given document.
078: *
079: * @param document the document to be read.
080: */
081: public DocumentReader(AbstractDocument document) {
082: this .document = document;
083: }
084:
085: /**
086: * Has no effect. This reader can be used even after
087: * it has been closed.
088: */
089: public void close() {
090: }
091:
092: /**
093: * Save a position for reset.
094: *
095: * @param readAheadLimit ignored.
096: */
097: public void mark(int readAheadLimit) {
098: mark = position;
099: }
100:
101: /**
102: * This reader support mark and reset.
103: *
104: * @return true
105: */
106: public boolean markSupported() {
107: return true;
108: }
109:
110: /**
111: * Read a single character.
112: *
113: * @return the character or -1 if the end of the document has been reached.
114: */
115: public int read() {
116: if (position < document.getLength()) {
117: try {
118: char c = document.getText((int) position, 1).charAt(0);
119: position++;
120: return c;
121: } catch (BadLocationException x) {
122: return -1;
123: }
124: } else {
125: return -1;
126: }
127: }
128:
129: /**
130: * Read and fill the buffer.
131: * This method will always fill the buffer unless the end of the document is reached.
132: *
133: * @param cbuf the buffer to fill.
134: * @return the number of characters read or -1 if no more characters are available in the document.
135: */
136: public int read(char[] cbuf) {
137: return read(cbuf, 0, cbuf.length);
138: }
139:
140: /**
141: * Read and fill the buffer.
142: * This method will always fill the buffer unless the end of the document is reached.
143: *
144: * @param cbuf the buffer to fill.
145: * @param off offset into the buffer to begin the fill.
146: * @param len maximum number of characters to put in the buffer.
147: * @return the number of characters read or -1 if no more characters are available in the document.
148: */
149: public int read(char[] cbuf, int off, int len) {
150: if (position < document.getLength()) {
151: int length = len;
152: if (position + length >= document.getLength()) {
153: length = document.getLength() - (int) position;
154: }
155: if (off + length >= cbuf.length) {
156: length = cbuf.length - off;
157: }
158: try {
159: String s = document.getText((int) position, length);
160: position += length;
161: for (int i = 0; i < length; i++) {
162: cbuf[off + i] = s.charAt(i);
163: }
164: return length;
165: } catch (BadLocationException x) {
166: return -1;
167: }
168: } else {
169: return -1;
170: }
171: }
172:
173: /**
174: * @return true
175: */
176: public boolean ready() {
177: return true;
178: }
179:
180: /**
181: * Reset this reader to the last mark, or the beginning of the document if a mark has not been set.
182: */
183: public void reset() {
184: if (mark == -1) {
185: position = 0;
186: } else {
187: position = mark;
188: }
189: mark = -1;
190: }
191:
192: /**
193: * Skip characters of input.
194: * This method will always skip the maximum number of characters unless
195: * the end of the file is reached.
196: *
197: * @param n number of characters to skip.
198: * @return the actual number of characters skipped.
199: */
200: public long skip(long n) {
201: if (position + n <= document.getLength()) {
202: position += n;
203: return n;
204: } else {
205: long oldPos = position;
206: position = document.getLength();
207: return (document.getLength() - oldPos);
208: }
209: }
210:
211: /**
212: * Seek to the given position in the document.
213: *
214: * @param n the offset to which to seek.
215: */
216: public void seek(long n) {
217: if (n <= document.getLength()) {
218: position = n;
219: } else {
220: position = document.getLength();
221: }
222: }
223: }
|