/Users/lyon/j4p/src/classUtils/pack/util/IndentedPrintWriter.java
|
1 /* Generated by Together */
2
3 package classUtils.pack.util;
4
5 import java.io.*;
6 import java.util.*;
7
8 /**
9 * A PrintWriter which indents each line of text with a given character.
10 *
11 * @author Cris Sadun
12 * @version 1.2
13 */
14 public class IndentedPrintWriter extends PrintWriter {
15
16 private static char [] ls=System.getProperty("line.separator").toCharArray();
17 private int truncatedNL;
18 private char []spc;
19 private boolean start=true;
20 private char indentationChar;
21 private boolean autoFlush;
22
23 /**
24 * Create a new writer over the given one, with the given indentation value.
25 * The indentation charachter defaults to blank - use {@link
26 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
27 * if required.
28 * @param w the writer wrapped by this IndentationPrintWriter
29 * @param indent the indentation level
30 */
31 public IndentedPrintWriter(Writer w, int indent) {
32 this(w, indent, false);
33 }
34
35 /**
36 * Create a new writer over the given stream, with the given indentation value.
37 * The indentation charachter defaults to blank - use {@link
38 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
39 * if required.
40 * @param out the stream wrapped by this IndentationPrintWriter
41 * @param indent the indentation level
42 * @param autoFlush if true, the println() methods will flush the output buffer
43 */
44 public IndentedPrintWriter(OutputStream out, int indent, boolean autoFlush) {
45 this(new BufferedWriter(new OutputStreamWriter(out)), indent, autoFlush);
46 }
47
48 /**
49 * Create a new writer over the given stream, with the given indentation value,
50 * and no autoflush.
51 * The indentation charachter defaults to blank - use {@link
52 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
53 * if required.
54 * @param out the stream wrapped by this IndentationPrintWriter
55 * @param indent the indentation level
56 */
57 public IndentedPrintWriter(OutputStream out, int indent) {
58 this(out, indent, false);
59 }
60
61 /**
62 * Create a new writer over the given one, with the given indentation value.
63 * The indentation charachter defaults to blank - use {@link
64 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
65 * if required.
66 * @param w the writer wrapped by this IndentationPrintWriter
67 * @param indent the indentation level
68 * @param autoFlush if true, the println() methods will flush the output buffer
69 */
70 public IndentedPrintWriter(Writer w, int indent, boolean autoFlush) {
71 super(w, autoFlush);
72 this.truncatedNL=0;
73 this.indentationChar=' ';
74 this.autoFlush=autoFlush;
75 setIndentation(indent);
76 }
77
78 /**
79 * Create a new writer over the given one, with the default indentation value,
80 * and no autoflush.
81 * The indentation charachter defaults to blank - use {@link
82 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
83 * if required.
84 * @param w the writer wrapped by this IndentationPrintWriter
85 */
86 public IndentedPrintWriter(Writer w) {
87 this(w, 0);
88 }
89
90 /**
91 * Create a new writer over the given stream, with the default indentation value.
92 * The indentation charachter defaults to blank - use {@link
93 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
94 * if required.
95 * @param out the stream wrapped by this IndentationPrintWriter
96 * @param autoFlush if true, the println() methods will flush the output buffer
97 */
98 public IndentedPrintWriter(OutputStream out, boolean autoFlush) {
99 this(out, 0, autoFlush);
100 }
101
102
103 /**
104 * Create a new writer over the given stream, with the default indentation value
105 * and no autoflush.
106 * The indentation charachter defaults to blank - use {@link
107 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
108 * if required.
109 * @param out the stream wrapped by this IndentationPrintWriter
110 */
111 public IndentedPrintWriter(OutputStream out) {
112 this(out, 0);
113 }
114
115 /**
116 * Create a new writer over the given one, with the defaukt indentation value.
117 * The indentation charachter defaults to blank - use {@link
118 * IndentedPrintWriter#setIndentationChar(char) setIndentationChar()} to set it differently
119 * if required.
120 * @param w the writer wrapped by this IndentationPrintWriter
121 * @param autoFlush if true, the println() methods will flush the output buffer
122 */
123 public IndentedPrintWriter(Writer w, boolean autoFlush) {
124 this(w, 0, autoFlush);
125 }
126
127 /**
128 * Return the current indentation level
129 * @return the current indentation level
130 */
131 public int getIndentation(){ return spc.length; }
132
133 /**
134 * Sets the current indentation level
135 * @param indent the desired indentation level
136 */
137 public synchronized void setIndentation(int indent){
138 if (indent < 0) throw new RuntimeException("Attmpting to set negative indentation");
139 spc = new char[indent];
140 Arrays.fill(spc, indentationChar);
141 }
142
143 /**
144 * Increment the current indentation level of the given level.
145 * @param level the indentation level to be incremented
146 */
147 public void incIndentation(int level) { setIndentation(getIndentation()+level); }
148
149 /**
150 * Decrement the current indentation level of the given level.
151 * 0 is the minimum level.
152 * @param level the indentation level to be reduced
153 */
154 public void decIndentation(int level) { setIndentation(getIndentation()-level); }
155
156 /**
157 * Increment the current indentation level.
158 * <p>
159 */
160 public void incIndentation() { incIndentation(1); }
161
162 /**
163 * Decrement the current indentation level. 0 is the minimum level.
164 * <p>
165 */
166 public void decIndentation() { decIndentation(1); }
167
168 /**
169 * Set the charachter used to indent to the given character
170 * @param c the charachter to use for indentation
171 */
172 public synchronized void setIndentationChar(char c) {
173 this.indentationChar=c;
174 setIndentation(getIndentation());
175 }
176
177 /**
178 * Return the charachter used to indent to the given character
179 * @return the charachter to use for indentation
180 */
181 public char getIndentationChar() { return indentationChar; }
182
183 /**
184 * Write a substring of a string, of given length from a given offset
185 */
186 public void write(String s, int off, int len) {
187 write(s.toCharArray(), off, len);
188 }
189
190 /**
191 * Write a character
192 */
193 public void write(int c) {
194 write(new char[] { (char)c }, 0, 1);
195 }
196
197 /**
198 * Write a portion of character array, of given length from a given offset
199 */
200 public void write(char buf[], int off, int len) {
201 synchronized(out) {
202
203 if (start) {
204 super.write(spc, 0, spc.length);
205 start=false;
206 }
207
208 List pos = new ArrayList();
209 int truncated=truncatedNL; // Remember if we start in a truncated-newline situation
210 for(int i=off;i<off+len;i++) {
211 if (isNL(buf, i, off+len)) pos.add(new Integer(i));
212 }
213 int p1 = 0;
214 String s;
215 for(Iterator i=pos.iterator();i.hasNext(); ) {
216 int p2 = ((Integer)i.next()).intValue();
217 super.write(buf, p1, p2-p1);
218 super.write(ls, 0, ls.length);
219 super.write(spc, 0, spc.length);
220 p1=p2+ls.length-truncated;
221 if (truncated!=0) truncated=0; // Just the first time
222 }
223 super.write(buf, p1, off+len-p1);
224 if (autoFlush) super.flush();
225 }
226 }
227
228 /**
229 * Checks if buf matches the line separator this.ls,
230 * setting this.truncatedNL if a partial match exists
231 * but the buffer portion is too short for a complete
232 * match
233 */
234 private boolean isNL(char []buf, int start, int end) {
235 for(int i=truncatedNL;i<ls.length && start+i<end;i++) {
236 int pos = start+i-truncatedNL;
237 if (buf[pos]!=ls[i]) {
238 if (truncatedNL !=0) truncatedNL=0;
239 return false;
240 }
241 }
242 if (end-start+truncatedNL < ls.length) {
243 truncatedNL=end-start;
244 return false;
245 }
246 if (truncatedNL !=0) truncatedNL=0;
247 return true;
248 }
249
250
251 /**
252 * Terminate the current line by writing the line separator string. The
253 * line separator string is defined by the system property
254 * <code>line.separator</code>, and is not necessarily a single newline
255 * character (<code>'\n'</code>).
256 */
257 public void println() {
258 super.println();
259 flush();
260 start=true;
261 }
262
263 /*public static void main(String []args) throws Exception {
264 IndentedPrintWriter pw = new IndentedPrintWriter(System.out, 5);
265 //pw.autoFlush=true;
266 pw.write(ls[0]);
267 pw.write(ls[1]);
268
269 pw.print("This is a test... \r");
270 pw.print("\nlet'see.");
271 pw.println("Hello"+System.getProperty("line.separator")+"World");
272 }*/
273
274 }
275
276