1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.qedeq.base.io;
17
18 import org.qedeq.base.utility.Splitter;
19 import org.qedeq.base.utility.StringUtility;
20
21
22
23
24
25
26
27 public abstract class AbstractOutput {
28
29
30 private StringBuffer spaces = new StringBuffer();
31
32
33 private int breakAt;
34
35
36
37
38
39 private String spacesForCurrentLine = "";
40
41
42 private int col;
43
44
45 private StringBuffer tokenBuffer = new StringBuffer();
46
47
48 private StringBuffer wsBuffer = new StringBuffer();
49
50
51
52
53 public AbstractOutput() {
54 }
55
56
57
58
59
60
61 public void addWs(final String ws) {
62 final String[] lines = StringUtility.split(ws, "\n");
63 for (int i = 0; i < lines.length; i++) {
64 if (i > 0) {
65 println();
66 }
67 addWsWithoutCR(lines[i]);
68 }
69 }
70
71
72
73
74
75
76 private void addWsWithoutCR(final String ws) {
77 if (tokenBuffer.length() > 0) {
78 if (fits(wsBuffer.length() + tokenBuffer.length())) {
79 if (col == 0) {
80 appendSpaces();
81 }
82 append(wsBuffer.toString());
83 col += wsBuffer.length();
84 append(tokenBuffer.toString());
85 col += tokenBuffer.length();
86 } else {
87
88 if (col != 0) {
89 appendFittingPart(wsBuffer.toString());
90 append("\n");
91 }
92 col = 0;
93 appendSpaces();
94 append(tokenBuffer.toString());
95 col += tokenBuffer.length();
96 }
97 wsBuffer.setLength(0);
98 tokenBuffer.setLength(0);
99 }
100 wsBuffer.append(ws);
101 }
102
103
104
105
106
107
108 public void addToken(final String part) {
109
110 if (col == 0 && part.length() > 0) {
111 setTabLevel();
112 }
113 tokenBuffer.append(part);
114 }
115
116
117
118
119 public void flush() {
120 addWsWithoutCR("");
121 appendFittingPart(wsBuffer.toString());
122 wsBuffer.setLength(0);
123 }
124
125
126
127
128
129
130
131 private int appendFittingPart(final String txt) {
132 final int columnsLeft = columnsLeft();
133 if (columnsLeft > 0) {
134 final String part = StringUtility.substring(txt, 0, columnsLeft);
135 append(part);
136 col += part.length();
137 return part.length();
138 } else if (columnsLeft < 0) {
139 append(txt);
140 col += txt.length();
141 return txt.length();
142 }
143 return 0;
144 }
145
146
147
148
149
150
151 public void print(final char c) {
152 print("" + c);
153 }
154
155
156
157
158
159
160
161 public void print(final String text) {
162 flush();
163 if (text == null) {
164 addToken("null");
165 } else {
166 final String[] lines = StringUtility.split(text, "\n");
167 for (int i = 0; i < lines.length; i++) {
168 final Splitter split = new Splitter(lines[i]);
169 while (split.hasNext()) {
170 final String token = split.nextToken();
171 final boolean isWhitespace = token.trim().length() == 0;
172 if (isWhitespace) {
173 addWsWithoutCR(token);
174 } else {
175 addToken(token);
176 }
177 }
178 if (i + 1 < lines.length) {
179 println();
180 }
181 }
182 }
183 flush();
184 }
185
186
187
188
189
190
191 public abstract void append(final String text);
192
193
194
195
196
197
198 public abstract long getPosition();
199
200
201
202
203
204
205 public void printWithoutSplit(final String text) {
206 flush();
207 if (text == null) {
208 return;
209 }
210 if (col == 0) {
211 if (text.length() > 0) {
212
213 setTabLevel();
214 appendSpaces();
215 }
216 } else if (!fits(text)) {
217 println();
218 appendSpaces();
219 }
220 append(text);
221 col += text.length();
222 }
223
224
225
226
227
228
229
230 private boolean fits(final String text) {
231 if (text == null) {
232 return true;
233 }
234 return fits(text.length());
235 }
236
237
238
239
240
241
242
243
244 private boolean fits(final int length) {
245 return breakAt <= 0 || col + length <= breakAt;
246 }
247
248
249
250
251
252
253 public int columnsLeft() {
254 if (breakAt <= 0) {
255 return -1;
256 } else {
257 return Math.max(0, breakAt - col);
258 }
259 }
260
261
262
263
264
265
266 public void print(final Object object) {
267 print(String.valueOf(object));
268 }
269
270
271
272
273
274
275 public final void println(final String token) {
276 print(token);
277 println();
278 }
279
280
281
282
283
284
285 public final void println(final Object object) {
286 println(String.valueOf(object));
287 }
288
289
290
291
292 public void println() {
293 flush();
294 if (col == 0 && spaces.toString().trim().length() > 0) {
295 setTabLevel();
296 appendSpaces();
297 }
298 append("\n");
299 col = 0;
300 }
301
302
303
304
305
306
307 public void skipToColumn(final int column) {
308 for (int i = col; i < column; i++) {
309 printWithoutSplit(" ");
310 }
311 }
312
313
314
315
316 public final void clearLevel() {
317
318 spaces.setLength(0);
319 }
320
321
322
323
324 public final void popLevel() {
325 if (spaces.length() > 0) {
326 spaces.setLength(spaces.length() - 2);
327 }
328 }
329
330
331
332
333
334
335 public final void popLevel(final int characters) {
336 if (spaces.length() > 0) {
337 spaces.setLength(Math.max(spaces.length() - characters, 0));
338 }
339 }
340
341
342
343
344
345
346 public final String getLevel() {
347 return spaces.toString();
348 }
349
350
351
352
353
354
355 public final void setLevel(final String level) {
356 spaces.setLength(0);
357 spaces.append(level);
358 }
359
360
361
362
363 public final void pushLevel() {
364 spaces.append(" ");
365 }
366
367
368
369
370
371
372 public final void pushLevel(final String symbols) {
373 spaces.append(symbols);
374 }
375
376
377
378
379 public final void setTabLevel() {
380 spacesForCurrentLine = spaces.toString();
381 }
382
383
384
385
386
387
388
389 public void setColumns(final int columns) {
390 if (columns < 0) {
391 breakAt = 0;
392 } else {
393 breakAt = columns;
394 }
395 }
396
397
398
399
400
401
402 public final int getColumns() {
403 return breakAt;
404 }
405
406
407
408
409 private void appendSpaces() {
410 append(spacesForCurrentLine.toString());
411 col += spacesForCurrentLine.length();
412 }
413
414 }