IndentingWriter.java revision 4b72225e9d81201838f387171a68a832486903f9
1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2010 Ben Gruver
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29package org.jf.util;
30
31import java.io.IOException;
32import java.io.Writer;
33
34public class IndentingWriter extends Writer {
35    private final Writer writer;
36    private final char[] buffer = new char[16];
37    private int indentLevel = 0;
38    private boolean beginningOfLine;
39    private static final String newLine = System.getProperty("line.separator");
40
41    public IndentingWriter(Writer writer) {
42        this.writer = writer;
43    }
44
45    @Override
46    public void write(int chr) throws IOException {
47        //synchronized(lock) {
48            if (chr == '\n') {
49                writer.write(newLine);
50                beginningOfLine = true;
51            } else {
52                if (beginningOfLine) {
53                    for (int i=0; i<indentLevel; i++) {
54                       writer.write(' ');
55                    }
56                }
57                beginningOfLine = false;
58                writer.write(chr);
59            }
60        //}
61    }
62
63    @Override
64    public void write(char[] chars) throws IOException {
65        //synchronized(lock) {
66            for (char chr: chars) {
67                write(chr);
68            }
69        //}
70    }
71
72    @Override
73    public void write(char[] chars, int start, int len) throws IOException {
74        //synchronized(lock) {
75            len = start+len;
76            while (start < len) {
77                write(chars[start++]);
78            }
79        //}
80    }
81
82    @Override
83    public void write(String s) throws IOException {
84        //synchronized (lock) {
85            for (int i=0; i<s.length(); i++) {
86                write(s.charAt(i));
87            }
88        //}
89    }
90
91    @Override
92    public void write(String str, int start, int len) throws IOException {
93        //synchronized(lock) {
94            len = start+len;
95            while (start < len) {
96                write(str.charAt(start++));
97            }
98        //}
99    }
100
101    @Override
102    public Writer append(CharSequence charSequence) throws IOException {
103        write(charSequence.toString());
104        return this;
105    }
106
107    @Override
108    public Writer append(CharSequence charSequence, int start, int len) throws IOException {
109        write(charSequence.subSequence(start, len).toString());
110        return this;
111    }
112
113    @Override
114    public Writer append(char c) throws IOException {
115        write(c);
116        return this;
117    }
118
119    @Override
120    public void flush() throws IOException {
121        //synchronized(lock) {
122            writer.flush();
123        //}
124    }
125
126    @Override
127    public void close() throws IOException {
128        //synchronized(lock) {
129            writer.close();
130        //}
131    }
132
133    public void indent(int indentAmount) {
134        //synchronized(lock) {
135            this.indentLevel += indentAmount;
136            if (indentLevel < 0) {
137                indentLevel = 0;
138            }
139        //}
140    }
141
142    public void deindent(int indentAmount) {
143        //synchronized(lock) {
144            this.indentLevel -= indentAmount;
145            if (indentLevel < 0) {
146                indentLevel = 0;
147            }
148        //}
149    }
150
151    public void printLongAsHex(long value) throws IOException {
152        int bufferIndex = 0;
153        do {
154            int digit = (int)(value & 15);
155            if (digit < 10) {
156                buffer[bufferIndex++] = (char)(digit + '0');
157            } else {
158                buffer[bufferIndex++] = (char)((digit - 10) + 'a');
159            }
160
161            value >>>= 4;
162        } while (value != 0);
163
164        while (bufferIndex>0) {
165            write(buffer[--bufferIndex]);
166        }
167    }
168
169    public void printIntAsDec(int value) throws IOException {
170        int bufferIndex = 0;
171        boolean negative = value < 0;
172
173        do {
174            int digit = value % 10;
175            buffer[bufferIndex++] = (char)(digit + '0');
176
177            value = value / 10;
178        } while (value != 0);
179
180        if (negative) {
181            write('-');
182        }
183
184        while (bufferIndex>0) {
185            write(buffer[--bufferIndex]);
186        }
187    }
188}
189