1 | /* | |
2 | * This file is part of the programmer editor demo | |
3 | * Copyright (C) 2001-2005 Stephen Ostermiller | |
4 | * http://ostermiller.org/contact.pl?regarding=Syntax+Highlighting | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * See COPYING.TXT for details. | |
17 | */ | |
18 | package com.jsql.view.swing.sql.lexer; | |
19 | ||
20 | import com.jsql.util.LogLevelUtil; | |
21 | import org.apache.logging.log4j.LogManager; | |
22 | import org.apache.logging.log4j.Logger; | |
23 | ||
24 | import javax.swing.text.AbstractDocument; | |
25 | import javax.swing.text.BadLocationException; | |
26 | import java.io.Reader; | |
27 | ||
28 | /** | |
29 | * A reader interface for an abstract document. Since | |
30 | * the syntax highlighting packages only accept Stings and | |
31 | * Readers, this must be used. | |
32 | * Since the close() method does nothing and a seek() method | |
33 | * has been added, this allows us to get some performance | |
34 | * improvements through reuse. It can be used even after the | |
35 | * lexer explicitly closes it by seeking to the place that | |
36 | * we want to read next, and reseting the lexer. | |
37 | */ | |
38 | class DocumentReader extends Reader { | |
39 | | |
40 | /** | |
41 | * Log4j logger sent to view. | |
42 | */ | |
43 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
44 | | |
45 | /** | |
46 | * Current position in the document. Incremented | |
47 | * whenever a character is read. | |
48 | */ | |
49 | private long position = 0; | |
50 | | |
51 | /** | |
52 | * Saved position used in the mark and reset methods. | |
53 | */ | |
54 | private long mark = -1; | |
55 | | |
56 | /** | |
57 | * The document that we are working with. | |
58 | */ | |
59 | private final AbstractDocument document; | |
60 | | |
61 | /** | |
62 | * Construct a reader on the given document. | |
63 | * | |
64 | * @param document the document to be read. | |
65 | */ | |
66 | public DocumentReader(AbstractDocument document) { | |
67 | this.document = document; | |
68 | } | |
69 | ||
70 | /** | |
71 | * Modifying the document while the reader is working is like | |
72 | * pulling the rug out from under the reader. Alerting the | |
73 | * reader with this method (in a nice thread safe way, this | |
74 | * should not be called at the same time as a read) allows | |
75 | * the reader to compensate. | |
76 | */ | |
77 | public void update(int position, int adjustment) { | |
78 |
2
1. update : changed conditional boundary → NO_COVERAGE 2. update : negated conditional → NO_COVERAGE |
if (position < this.position) { |
79 |
3
1. update : changed conditional boundary → NO_COVERAGE 2. update : Replaced integer subtraction with addition → NO_COVERAGE 3. update : negated conditional → NO_COVERAGE |
if (this.position < position - adjustment) { |
80 | this.position = position; | |
81 | } else { | |
82 |
1
1. update : Replaced long addition with subtraction → NO_COVERAGE |
this.position += adjustment; |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | /** | |
88 | * Has no effect. This reader can be used even after | |
89 | * it has been closed. | |
90 | */ | |
91 | @Override | |
92 | public void close() { | |
93 | // nothing | |
94 | } | |
95 | ||
96 | /** | |
97 | * Save a position for reset. | |
98 | * | |
99 | * @param readAheadLimit ignored. | |
100 | */ | |
101 | @Override | |
102 | public void mark(int readAheadLimit) { | |
103 | this.mark = this.position; | |
104 | } | |
105 | ||
106 | /** | |
107 | * This reader support mark and reset. | |
108 | * | |
109 | * @return true | |
110 | */ | |
111 | @Override | |
112 | public boolean markSupported() { | |
113 |
1
1. markSupported : replaced boolean return with false for com/jsql/view/swing/sql/lexer/DocumentReader::markSupported → NO_COVERAGE |
return true; |
114 | } | |
115 | ||
116 | /** | |
117 | * Read a single character. | |
118 | * | |
119 | * @return the character or -1 if the end of the document has been reached. | |
120 | */ | |
121 | @Override | |
122 | public int read() { | |
123 |
2
1. read : negated conditional → NO_COVERAGE 2. read : changed conditional boundary → NO_COVERAGE |
if (this.position < this.document.getLength()) { |
124 | try { | |
125 | char c = this.document.getText((int)this.position, 1).charAt(0); | |
126 |
1
1. read : Replaced long addition with subtraction → NO_COVERAGE |
this.position++; |
127 | | |
128 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return c; |
129 | | |
130 | } catch (BadLocationException e) { | |
131 | | |
132 | LOGGER.log(LogLevelUtil.IGNORE, e); | |
133 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return -1; |
134 | } | |
135 | } else { | |
136 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return -1; |
137 | } | |
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 | * @return the number of characters read or -1 if no more characters are available in the document. | |
146 | */ | |
147 | @Override | |
148 | public int read(char[] cbuf) { | |
149 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return this.read(cbuf, 0, cbuf.length); |
150 | } | |
151 | ||
152 | /** | |
153 | * Read and fill the buffer. | |
154 | * This method will always fill the buffer unless the end of the document is reached. | |
155 | * | |
156 | * @param cbuf the buffer to fill. | |
157 | * @param off offset into the buffer to begin the fill. | |
158 | * @param len maximum number of characters to put in the buffer. | |
159 | * @return the number of characters read or -1 if no more characters are available in the document. | |
160 | */ | |
161 | @Override | |
162 | public int read(char[] cbuf, int off, int len) { | |
163 | | |
164 |
2
1. read : negated conditional → NO_COVERAGE 2. read : changed conditional boundary → NO_COVERAGE |
if (this.position < this.document.getLength()) { |
165 | | |
166 | int length = len; | |
167 | | |
168 |
3
1. read : Replaced long addition with subtraction → NO_COVERAGE 2. read : changed conditional boundary → NO_COVERAGE 3. read : negated conditional → NO_COVERAGE |
if (this.position + length >= this.document.getLength()) { |
169 |
1
1. read : Replaced integer subtraction with addition → NO_COVERAGE |
length = this.document.getLength() - (int)this.position; |
170 | } | |
171 | | |
172 |
3
1. read : changed conditional boundary → NO_COVERAGE 2. read : negated conditional → NO_COVERAGE 3. read : Replaced integer addition with subtraction → NO_COVERAGE |
if (off + length >= cbuf.length) { |
173 |
1
1. read : Replaced integer subtraction with addition → NO_COVERAGE |
length = cbuf.length - off; |
174 | } | |
175 | | |
176 | try { | |
177 | String s = this.document.getText((int)this.position, length); | |
178 |
1
1. read : Replaced long addition with subtraction → NO_COVERAGE |
this.position += length; |
179 | | |
180 |
2
1. read : negated conditional → NO_COVERAGE 2. read : changed conditional boundary → NO_COVERAGE |
for (int i=0; i<length; i++) { |
181 |
1
1. read : Replaced integer addition with subtraction → NO_COVERAGE |
cbuf[off+i] = s.charAt(i); |
182 | } | |
183 | | |
184 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return length; |
185 | | |
186 | } catch (BadLocationException e) { | |
187 | | |
188 | LOGGER.log(LogLevelUtil.IGNORE, e); | |
189 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return -1; |
190 | } | |
191 | } else { | |
192 |
1
1. read : replaced int return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::read → NO_COVERAGE |
return -1; |
193 | } | |
194 | } | |
195 | ||
196 | /** | |
197 | * @return true | |
198 | */ | |
199 | @Override | |
200 | public boolean ready() { | |
201 |
1
1. ready : replaced boolean return with false for com/jsql/view/swing/sql/lexer/DocumentReader::ready → NO_COVERAGE |
return true; |
202 | } | |
203 | ||
204 | /** | |
205 | * Reset this reader to the last mark, or the beginning of the document if a mark has not been set. | |
206 | */ | |
207 | @Override | |
208 | public void reset() { | |
209 | | |
210 |
1
1. reset : negated conditional → NO_COVERAGE |
if (this.mark == -1) { |
211 | this.position = 0; | |
212 | } else { | |
213 | this.position = this.mark; | |
214 | } | |
215 | | |
216 | this.mark = -1; | |
217 | } | |
218 | ||
219 | /** | |
220 | * Skip characters of input. | |
221 | * This method will always skip the maximum number of characters unless | |
222 | * the end of the file is reached. | |
223 | * | |
224 | * @param n number of characters to skip. | |
225 | * @return the actual number of characters skipped. | |
226 | */ | |
227 | @Override | |
228 | public long skip(long n) { | |
229 | | |
230 |
3
1. skip : changed conditional boundary → NO_COVERAGE 2. skip : Replaced long addition with subtraction → NO_COVERAGE 3. skip : negated conditional → NO_COVERAGE |
if (this.position + n <= this.document.getLength()) { |
231 | | |
232 |
1
1. skip : Replaced long addition with subtraction → NO_COVERAGE |
this.position += n; |
233 |
1
1. skip : replaced long return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::skip → NO_COVERAGE |
return n; |
234 | | |
235 | } else { | |
236 | | |
237 | long oldPos = this.position; | |
238 | this.position = this.document.getLength(); | |
239 | | |
240 |
2
1. skip : Replaced long subtraction with addition → NO_COVERAGE 2. skip : replaced long return with 0 for com/jsql/view/swing/sql/lexer/DocumentReader::skip → NO_COVERAGE |
return this.document.getLength() - oldPos; |
241 | } | |
242 | } | |
243 | ||
244 | /** | |
245 | * Seek to the given position in the document. | |
246 | * | |
247 | * @param n the offset to which to seek. | |
248 | */ | |
249 | public void seek(long n) { | |
250 |
2
1. seek : negated conditional → NO_COVERAGE 2. seek : changed conditional boundary → NO_COVERAGE |
if (n <= this.document.getLength()) { |
251 | this.position = n; | |
252 | } else { | |
253 | this.position = this.document.getLength(); | |
254 | } | |
255 | } | |
256 | } | |
Mutations | ||
78 |
1.1 2.2 |
|
79 |
1.1 2.2 3.3 |
|
82 |
1.1 |
|
113 |
1.1 |
|
123 |
1.1 2.2 |
|
126 |
1.1 |
|
128 |
1.1 |
|
133 |
1.1 |
|
136 |
1.1 |
|
149 |
1.1 |
|
164 |
1.1 2.2 |
|
168 |
1.1 2.2 3.3 |
|
169 |
1.1 |
|
172 |
1.1 2.2 3.3 |
|
173 |
1.1 |
|
178 |
1.1 |
|
180 |
1.1 2.2 |
|
181 |
1.1 |
|
184 |
1.1 |
|
189 |
1.1 |
|
192 |
1.1 |
|
201 |
1.1 |
|
210 |
1.1 |
|
230 |
1.1 2.2 3.3 |
|
232 |
1.1 |
|
233 |
1.1 |
|
240 |
1.1 2.2 |
|
250 |
1.1 2.2 |