EMMA Coverage Report (generated Fri Feb 14 08:28:31 UTC 2014)
[all classes][org.qedeq.base.io]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractOutput.java]

nameclass, %method, %block, %line, %
AbstractOutput.java100% (1/1)96%  (27/28)96%  (469/487)95%  (125/132)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractOutput100% (1/1)96%  (27/28)96%  (469/487)95%  (125/132)
getColumns (): int 0%   (0/1)0%   (0/3)0%   (0/1)
setColumns (int): void 100% (1/1)60%  (6/10)75%  (3/4)
fits (String): boolean 100% (1/1)78%  (7/9)67%  (2/3)
printWithoutSplit (String): void 100% (1/1)86%  (30/35)77%  (10/13)
print (String): void 100% (1/1)94%  (58/62)94%  (16/17)
AbstractOutput (): void 100% (1/1)100% (21/21)100% (6/6)
addToken (String): void 100% (1/1)100% (14/14)100% (4/4)
addWs (String): void 100% (1/1)100% (22/22)100% (6/6)
addWsWithoutCR (String): void 100% (1/1)100% (90/90)100% (19/19)
appendFittingPart (String): int 100% (1/1)100% (40/40)100% (11/11)
appendSpaces (): void 100% (1/1)100% (14/14)100% (3/3)
clearLevel (): void 100% (1/1)100% (5/5)100% (2/2)
columnsLeft (): int 100% (1/1)100% (13/13)100% (3/3)
fits (int): boolean 100% (1/1)100% (14/14)100% (1/1)
flush (): void 100% (1/1)100% (14/14)100% (4/4)
getLevel (): String 100% (1/1)100% (4/4)100% (1/1)
popLevel (): void 100% (1/1)100% (13/13)100% (3/3)
popLevel (int): void 100% (1/1)100% (15/15)100% (3/3)
print (Object): void 100% (1/1)100% (5/5)100% (2/2)
print (char): void 100% (1/1)100% (11/11)100% (2/2)
println (): void 100% (1/1)100% (22/22)100% (7/7)
println (Object): void 100% (1/1)100% (5/5)100% (2/2)
println (String): void 100% (1/1)100% (6/6)100% (3/3)
pushLevel (): void 100% (1/1)100% (6/6)100% (2/2)
pushLevel (String): void 100% (1/1)100% (6/6)100% (2/2)
setLevel (String): void 100% (1/1)100% (10/10)100% (3/3)
setTabLevel (): void 100% (1/1)100% (6/6)100% (2/2)
skipToColumn (int): void 100% (1/1)100% (12/12)100% (3/3)

1/* This file is part of the project "Hilbert II" - http://www.qedeq.org
2 *
3 * Copyright 2000-2014,  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 
16package org.qedeq.base.io;
17 
18import org.qedeq.base.utility.Splitter;
19import org.qedeq.base.utility.StringUtility;
20 
21 
22/**
23 * Wraps a text output stream.
24 *
25 * @author  Michael Meyling
26 */
27public 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    public AbstractOutput() {
54    }
55 
56    /**
57     * Add whitespace to output.
58     *
59     * @param   ws  Add this whitespace.
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     * Add whitespace to output. Must not contain CRs.
73     *
74     * @param   ws  Add this whitespace.
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                // forget non fitting part of white space
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     * Append token to output.
105     *
106     * @param   part    Add this part.
107     */
108    public void addToken(final String part) {
109        // remember tabular spaces when we start writing
110        if (col == 0 && part.length() > 0) {
111            setTabLevel();
112        }
113        tokenBuffer.append(part);
114    }
115 
116    /**
117     * Flush output.
118     */
119    public void flush() {
120        addWsWithoutCR("");
121        appendFittingPart(wsBuffer.toString());
122        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    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     * Print character to output.
148     *
149     * @param   c   Append this.
150     */
151    public void print(final char c) {
152        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    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     * 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    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                // remember tabular spaces when we start writing
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     * 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    private boolean fits(final String text) {
231        if (text == null) {
232            return true;
233        }
234        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    private boolean fits(final int length) {
245        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    public int columnsLeft() {
254        if (breakAt <= 0) {
255            return -1;
256        } else {
257            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    public void print(final Object object) {
267        print(String.valueOf(object));
268    }
269 
270    /**
271     * Print spaces text and new line to output.
272     *
273     * @param   token   Append this.
274     */
275    public final void println(final String token) {
276        print(token);
277        println();
278    }
279 
280    /**
281     * Print object and new line to output.
282     *
283     * @param   object  Append text representation of this.
284     */
285    public final void println(final Object object) {
286        println(String.valueOf(object));
287    }
288 
289    /**
290     * Print new line to output.
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     * Skip until given column. To do this we append spaces.
304     *
305     * @param   column  Skip to this column.
306     */
307    public void skipToColumn(final int column) {
308        for (int i = col; i < column; i++) {
309            printWithoutSplit(" ");
310        }
311    }
312 
313    /**
314     * Reset tab level to zero.
315     */
316    public final void clearLevel() {
317        // flush();
318        spaces.setLength(0);
319    }
320 
321    /**
322     * Decrement tab level.
323     */
324    public final void popLevel() {
325        if (spaces.length() > 0) {
326            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    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     * Return current tab string.
343     *
344     * @return  Current tab string.
345     */
346    public final String getLevel() {
347        return spaces.toString();
348    }
349 
350    /**
351     * Set current tab string.
352     *
353     * @param   level   Tab string.
354     */
355    public final void setLevel(final String level) {
356        spaces.setLength(0);
357        spaces.append(level);
358    }
359 
360    /**
361     * Increment tab level (this are two spaces).
362     */
363    public final void pushLevel() {
364        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    public final void pushLevel(final String symbols) {
373        spaces.append(symbols);
374    }
375 
376    /**
377     * Set current tab level to current level. Might change unwritten lines.
378     */
379    public final void setTabLevel() {
380        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    public void setColumns(final int columns) {
390        if (columns < 0) {
391            breakAt = 0;
392        } else {
393            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    public final int getColumns() {
403        return breakAt;
404    }
405 
406    /**
407     * Append tabulation and increase current column.
408     */
409    private void appendSpaces() {
410        append(spacesForCurrentLine.toString());
411        col += spacesForCurrentLine.length();
412    }
413 
414}

[all classes][org.qedeq.base.io]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov