• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 package org.jf.util;
30 
31 import java.io.IOException;
32 import java.io.Writer;
33 
34 public class IndentingWriter extends Writer {
35     protected final Writer writer;
36     protected final char[] buffer = new char[24];
37     protected int indentLevel = 0;
38     private boolean beginningOfLine = true;
39     private static final String newLine = System.getProperty("line.separator");
40 
IndentingWriter(Writer writer)41     public IndentingWriter(Writer writer) {
42         this.writer = writer;
43     }
44 
writeIndent()45     protected void writeIndent() throws IOException {
46         for (int i=0; i<indentLevel; i++) {
47             writer.write(' ');
48         }
49     }
50 
51     @Override
write(int chr)52     public void write(int chr) throws IOException {
53         if (chr == '\n') {
54             writer.write(newLine);
55             beginningOfLine = true;
56         } else {
57             if (beginningOfLine) {
58                 writeIndent();
59             }
60             beginningOfLine = false;
61             writer.write(chr);
62         }
63     }
64 
65     /**
66      * Writes out a block of text that contains no newlines
67      */
writeLine(char[] chars, int start, int len)68     private void writeLine(char[] chars, int start, int len) throws IOException {
69         if (beginningOfLine && len > 0) {
70             writeIndent();
71             beginningOfLine = false;
72         }
73         writer.write(chars, start, len);
74     }
75 
76 
77     /**
78      * Writes out a block of text that contains no newlines
79      */
writeLine(String str, int start, int len)80     private void writeLine(String str, int start, int len) throws IOException {
81         if (beginningOfLine && len > 0) {
82             writeIndent();
83             beginningOfLine = false;
84         }
85         writer.write(str, start, len);
86     }
87 
88     @Override
write(char[] chars)89     public void write(char[] chars) throws IOException {
90         write(chars, 0, chars.length);
91     }
92 
93     @Override
write(char[] chars, int start, int len)94     public void write(char[] chars, int start, int len) throws IOException {
95         final int end = start+len;
96         int pos = start;
97         while (pos < end) {
98             if (chars[pos] == '\n') {
99                 writeLine(chars, start, pos-start);
100 
101                 writer.write(newLine);
102                 beginningOfLine = true;
103                 pos++;
104                 start = pos;
105             } else {
106                 pos++;
107             }
108         }
109         writeLine(chars, start, pos-start);
110     }
111 
112     @Override
write(String s)113     public void write(String s) throws IOException {
114         write(s, 0, s.length());
115     }
116 
117     @Override
write(String str, int start, int len)118     public void write(String str, int start, int len) throws IOException {
119         final int end = start+len;
120         int pos = start;
121         while (pos < end) {
122             pos = str.indexOf('\n', start);
123             if (pos == -1 || pos >= end) {
124                 writeLine(str, start, end-start);
125                 return;
126             } else {
127                 writeLine(str, start, pos-start);
128                 writer.write(newLine);
129                 beginningOfLine = true;
130                 start = pos+1;
131             }
132         }
133     }
134 
135     @Override
append(CharSequence charSequence)136     public Writer append(CharSequence charSequence) throws IOException {
137         write(charSequence.toString());
138         return this;
139     }
140 
141     @Override
append(CharSequence charSequence, int start, int len)142     public Writer append(CharSequence charSequence, int start, int len) throws IOException {
143         write(charSequence.subSequence(start, len).toString());
144         return this;
145     }
146 
147     @Override
append(char c)148     public Writer append(char c) throws IOException {
149         write(c);
150         return this;
151     }
152 
153     @Override
flush()154     public void flush() throws IOException {
155         writer.flush();
156     }
157 
158     @Override
close()159     public void close() throws IOException {
160         writer.close();
161     }
162 
indent(int indentAmount)163     public void indent(int indentAmount) {
164         this.indentLevel += indentAmount;
165         if (indentLevel < 0) {
166             indentLevel = 0;
167         }
168     }
169 
deindent(int indentAmount)170     public void deindent(int indentAmount) {
171         this.indentLevel -= indentAmount;
172         if (indentLevel < 0) {
173             indentLevel = 0;
174         }
175     }
176 
printUnsignedLongAsHex(long value)177     public void printUnsignedLongAsHex(long value) throws IOException {
178         int bufferIndex = 23;
179         do {
180             int digit = (int)(value & 15);
181             if (digit < 10) {
182                 buffer[bufferIndex--] = (char)(digit + '0');
183             } else {
184                 buffer[bufferIndex--] = (char)((digit - 10) + 'a');
185             }
186 
187             value >>>= 4;
188         } while (value != 0);
189 
190         bufferIndex++;
191 
192         writeLine(buffer, bufferIndex, 24-bufferIndex);
193     }
194 
printSignedLongAsDec(long value)195     public void printSignedLongAsDec(long value) throws IOException {
196         int bufferIndex = 23;
197 
198         if (value < 0) {
199             value *= -1;
200             write('-');
201         }
202 
203         do {
204             long digit = value % 10;
205             buffer[bufferIndex--] = (char)(digit + '0');
206 
207             value = value / 10;
208         } while (value != 0);
209 
210         bufferIndex++;
211 
212         writeLine(buffer, bufferIndex, 24-bufferIndex);
213     }
214 
printSignedIntAsDec(int value)215     public void printSignedIntAsDec(int value) throws IOException {
216         int bufferIndex = 15;
217 
218         if (value < 0) {
219             value *= -1;
220             write('-');
221         }
222 
223         do {
224             int digit = value % 10;
225             buffer[bufferIndex--] = (char)(digit + '0');
226 
227             value = value / 10;
228         } while (value != 0);
229 
230         bufferIndex++;
231 
232         writeLine(buffer, bufferIndex, 16-bufferIndex);
233     }
234 
printUnsignedIntAsDec(int value)235     public void printUnsignedIntAsDec(int value) throws IOException {
236         int bufferIndex = 15;
237 
238         if (value < 0) {
239             printSignedLongAsDec(value & 0xFFFFFFFFL);
240         } else {
241             printSignedIntAsDec(value);
242         }
243     }
244 }
245