Clover Coverage Report
Coverage timestamp: Fri May 24 2013 13:47:27 UTC
../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
104   414   55   3.71
50   201   0.53   28
28     1.96  
1    
 
  AbstractOutput       Line # 27 104 55 92.3% 0.9230769
 
  (96)
 
1    /* This file is part of the project "Hilbert II" - http://www.qedeq.org
2    *
3    * Copyright 2000-2013, Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10    * This program is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    * GNU General Public License for more details.
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    * Wraps a text output stream.
24    *
25    * @author Michael Meyling
26    */
 
27    public abstract class AbstractOutput {
28   
29    /** Tab level. */
30    private StringBuffer spaces = new StringBuffer();
31   
32    /** Break at this column if greater zero. */
33    private int breakAt;
34   
35    /** Tab level of current line. This is equal to spaces before any character is
36    * written. After writing to the current line this value is fixed and doesn't change even
37    * if the tab level is changed.
38    */
39    private String spacesForCurrentLine = "";
40   
41    /** Current column. */
42    private int col;
43   
44    /** Token buffer. */
45    private StringBuffer tokenBuffer = new StringBuffer();
46   
47    /** Whitespace buffer. */
48    private StringBuffer wsBuffer = new StringBuffer();
49   
50    /**
51    * Constructor.
52    */
 
53  4156 toggle public AbstractOutput() {
54    }
55   
56    /**
57    * Add whitespace to output.
58    *
59    * @param ws Add this whitespace.
60    */
 
61  53443 toggle public void addWs(final String ws) {
62  53443 final String[] lines = StringUtility.split(ws, "\n");
63  106896 for (int i = 0; i < lines.length; i++) {
64  53453 if (i > 0) {
65  10 println();
66    }
67  53453 addWsWithoutCR(lines[i]);
68    }
69    }
70   
71    /**
72    * Add whitespace to output. Must not contain CRs.
73    *
74    * @param ws Add this whitespace.
75    */
 
76  953856 toggle private void addWsWithoutCR(final String ws) {
77  953856 if (tokenBuffer.length() > 0) {
78  540985 if (fits(wsBuffer.length() + tokenBuffer.length())) {
79  538778 if (col == 0) {
80  120409 appendSpaces();
81    }
82  538778 append(wsBuffer.toString());
83  538778 col += wsBuffer.length();
84  538778 append(tokenBuffer.toString());
85  538778 col += tokenBuffer.length();
86    } else {
87    // forget non fitting part of white space
88  2207 if (col != 0) {
89  2199 appendFittingPart(wsBuffer.toString());
90  2199 append("\n");
91    }
92  2207 col = 0;
93  2207 appendSpaces();
94  2207 append(tokenBuffer.toString());
95  2207 col += tokenBuffer.length();
96    }
97  540985 wsBuffer.setLength(0);
98  540985 tokenBuffer.setLength(0);
99    }
100  953856 wsBuffer.append(ws);
101    }
102   
103    /**
104    * Append token to output.
105    *
106    * @param part Add this part.
107    */
 
108  559071 toggle public void addToken(final String part) {
109    // remember tabular spaces when we start writing
110  559071 if (col == 0 && part.length() > 0) {
111  121961 setTabLevel();
112    }
113  559071 tokenBuffer.append(part);
114    }
115   
116    /**
117    * Flush output.
118    */
 
119  571478 toggle public void flush() {
120  571478 addWsWithoutCR("");
121  571478 appendFittingPart(wsBuffer.toString());
122  571478 wsBuffer.setLength(0);
123    }
124   
125    /**
126    * Append a part of given text so that the current maximum column is not exceeded.
127    *
128    * @param txt Write this text.
129    * @return Length of written characters.
130    */
 
131  573677 toggle private int appendFittingPart(final String txt) {
132  573677 final int columnsLeft = columnsLeft();
133  573677 if (columnsLeft > 0) {
134  66407 final String part = StringUtility.substring(txt, 0, columnsLeft);
135  66407 append(part);
136  66407 col += part.length();
137  66407 return part.length();
138  507270 } else if (columnsLeft < 0) {
139  506776 append(txt);
140  506776 col += txt.length();
141  506776 return txt.length();
142    }
143  494 return 0;
144    }
145   
146    /**
147    * Print character to output.
148    *
149    * @param c Append this.
150    */
 
151  8 toggle public void print(final char c) {
152  8 print("" + c);
153    }
154   
155    /**
156    * Print text and split at white space if text doesn't fit within maximum column size.
157    * Also flushes output.
158    *
159    * @param text Append this.
160    */
 
161  205877 toggle public void print(final String text) {
162  205877 flush();
163  205877 if (text == null) {
164  0 addToken("null");
165    } else {
166  205877 final String[] lines = StringUtility.split(text, "\n");
167  423776 for (int i = 0; i < lines.length; i++) {
168  217899 final Splitter split = new Splitter(lines[i]);
169  1027690 while (split.hasNext()) {
170  809791 final String token = split.nextToken();
171  809791 final boolean isWhitespace = token.trim().length() == 0;
172  809791 if (isWhitespace) {
173  328925 addWsWithoutCR(token);
174    } else {
175  480866 addToken(token);
176    }
177    }
178  217899 if (i + 1 < lines.length) {
179  12022 println();
180    }
181    }
182    }
183  205877 flush();
184    }
185   
186    /**
187    * Append text directly to output device.
188    *
189    * @param text Append this text.
190    */
191    public abstract void append(final String text);
192   
193    /**
194    * Get writing position.
195    *
196    * @return Writing position.
197    */
198    public abstract long getPosition();
199   
200    /**
201    * Print spaces and text to output.
202    *
203    * @param text Append this.
204    */
 
205  21758 toggle public void printWithoutSplit(final String text) {
206  21758 flush();
207  21758 if (text == null) {
208  0 return;
209    }
210  21758 if (col == 0) {
211  420 if (text.length() > 0) {
212    // remember tabular spaces when we start writing
213  420 setTabLevel();
214  420 appendSpaces();
215    }
216  21338 } else if (!fits(text)) {
217  0 println();
218  0 appendSpaces();
219    }
220  21758 append(text);
221  21758 col += text.length();
222    }
223   
224    /**
225    * Does the text fit to current line?
226    *
227    * @param text Check if this text could be appended without line break.
228    * @return Does it fit?
229    */
 
230  21338 toggle private boolean fits(final String text) {
231  21338 if (text == null) {
232  0 return true;
233    }
234  21338 return fits(text.length());
235    }
236   
237    /**
238    * Does a text with given length fit to current line?
239    * TODO 20110104 m31: should't we use spacesForCurrentLine also?
240    *
241    * @param length Check if a text of this length could be appended without line break.
242    * @return Does it fit?
243    */
 
244  562323 toggle private boolean fits(final int length) {
245  562323 return breakAt <= 0 || col + length <= breakAt;
246    }
247   
248    /**
249    * How many columns have we left?
250    *
251    * @return Columns left. Returns -1 if there is no limit.
252    */
 
253  573677 toggle public int columnsLeft() {
254  573677 if (breakAt <= 0) {
255  506776 return -1;
256    } else {
257  66901 return Math.max(0, breakAt - col);
258    }
259    }
260   
261    /**
262    * Print object to output.
263    *
264    * @param object Append text representation of this.
265    */
 
266  3 toggle public void print(final Object object) {
267  3 print(String.valueOf(object));
268    }
269   
270    /**
271    * Print spaces text and new line to output.
272    *
273    * @param token Append this.
274    */
 
275  104886 toggle public final void println(final String token) {
276  104886 print(token);
277  104886 println();
278    }
279   
280    /**
281    * Print object and new line to output.
282    *
283    * @param object Append text representation of this.
284    */
 
285  66 toggle public final void println(final Object object) {
286  66 println(String.valueOf(object));
287    }
288   
289    /**
290    * Print new line to output.
291    */
 
292  130206 toggle public void println() {
293  130206 flush();
294  130206 if (col == 0 && spaces.toString().trim().length() > 0) {
295  2 setTabLevel();
296  2 appendSpaces();
297    }
298  130206 append("\n");
299  130206 col = 0;
300    }
301   
302    /**
303    * Skip until given column. To do this we append spaces.
304    *
305    * @param column Skip to this column.
306    */
 
307  2298 toggle public void skipToColumn(final int column) {
308  23858 for (int i = col; i < column; i++) {
309  21560 printWithoutSplit(" ");
310    }
311    }
312   
313    /**
314    * Reset tab level to zero.
315    */
 
316  5312 toggle public final void clearLevel() {
317    // flush();
318  5312 spaces.setLength(0);
319    }
320   
321    /**
322    * Decrement tab level.
323    */
 
324  39818 toggle public final void popLevel() {
325  39818 if (spaces.length() > 0) {
326  39812 spaces.setLength(spaces.length() - 2);
327    }
328    }
329   
330    /**
331    * Decrement tab level.
332    *
333    * @param characters Number of characters to reduce from tab level.
334    */
 
335  108 toggle public final void popLevel(final int characters) {
336  108 if (spaces.length() > 0) {
337  86 spaces.setLength(Math.max(spaces.length() - characters, 0));
338    }
339    }
340   
341    /**
342    * Return current tab string.
343    *
344    * @return Current tab string.
345    */
 
346  5313 toggle public final String getLevel() {
347  5313 return spaces.toString();
348    }
349   
350    /**
351    * Set current tab string.
352    *
353    * @param level Tab string.
354    */
 
355  10 toggle public final void setLevel(final String level) {
356  10 spaces.setLength(0);
357  10 spaces.append(level);
358    }
359   
360    /**
361    * Increment tab level (this are two spaces).
362    */
 
363  39742 toggle public final void pushLevel() {
364  39742 spaces.append(" ");
365    }
366   
367    /**
368    * Increment tab level with following symbols.
369    *
370    * @param symbols Symbols to tab width. Length should be exactly 2 characters!
371    */
 
372  5521 toggle public final void pushLevel(final String symbols) {
373  5521 spaces.append(symbols);
374    }
375   
376    /**
377    * Set current tab level to current level. Might change unwritten lines.
378    */
 
379  122480 toggle public final void setTabLevel() {
380  122480 spacesForCurrentLine = spaces.toString();
381    }
382   
383    /**
384    * Set number of maximum columns. If possible we break before we reach this column number.
385    * If less or equal to zero no line breaking is done automatically.
386    *
387    * @param columns Maximum column size.
388    */
 
389  3958 toggle public void setColumns(final int columns) {
390  3958 if (columns < 0) {
391  0 breakAt = 0;
392    } else {
393  3958 breakAt = columns;
394    }
395    }
396   
397    /**
398    * Return number of maximum columns. If equal to zero no line breaking is done automatically.
399    *
400    * @return Maximum column size.
401    */
 
402  0 toggle public final int getColumns() {
403  0 return breakAt;
404    }
405   
406    /**
407    * Append tabulation and increase current column.
408    */
 
409  123038 toggle private void appendSpaces() {
410  123038 append(spacesForCurrentLine.toString());
411  123038 col += spacesForCurrentLine.length();
412    }
413   
414    }