Mercurial > hg > truffle
comparison graal/com.oracle.max.criutils/src/com/oracle/max/criutils/LogStream.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3732:3e2e8b8abdaf | 3733:e233f5660da4 |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.max.criutils; | |
24 | |
25 import java.io.*; | |
26 | |
27 /** | |
28 * A utility for printing compiler debug and informational output to an output stream. | |
29 * | |
30 * A {@link LogStream} instance maintains an internal buffer that is flushed to the underlying | |
31 * output stream every time one of the {@code println} methods is invoked, or a newline character | |
32 * ({@code '\n'}) is written. | |
33 * | |
34 * All of the {@code print} and {@code println} methods return the {code LogStream} instance | |
35 * on which they were invoked. This allows chaining of these calls to mitigate use of String | |
36 * concatenation by the caller. | |
37 * | |
38 * A {@code LogStream} maintains a current {@linkplain #indentationLevel() indentation} level. | |
39 * Each line of output written to this stream has {@code n} spaces prefixed to it where | |
40 * {@code n} is the value that would be returned by {@link #indentationLevel()} when the first | |
41 * character of a new line is written. | |
42 * | |
43 * A {@code LogStream} maintains a current {@linkplain #position() position} for the current | |
44 * line being written. This position can be advanced to a specified position by | |
45 * {@linkplain #fillTo(int, char) filling} this stream with a given character. | |
46 */ | |
47 public class LogStream { | |
48 | |
49 /** | |
50 * Null output stream that simply swallows any output sent to it. | |
51 */ | |
52 public static final LogStream SINK = new LogStream(); | |
53 | |
54 private static final PrintStream SINK_PS = new PrintStream(new OutputStream() { | |
55 @Override | |
56 public void write(int b) throws IOException { } | |
57 }); | |
58 | |
59 private LogStream() { | |
60 this.ps = null; | |
61 this.lineBuffer = null; | |
62 } | |
63 | |
64 /** | |
65 * The output stream to which this log stream writes. | |
66 */ | |
67 private final PrintStream ps; | |
68 | |
69 private final StringBuilder lineBuffer; | |
70 private int indentationLevel; | |
71 private char indentation = ' '; | |
72 private boolean indentationDisabled; | |
73 | |
74 public final PrintStream out() { | |
75 if (ps == null) { | |
76 return SINK_PS; | |
77 } | |
78 return ps; | |
79 } | |
80 | |
81 /** | |
82 * The system dependent line separator. | |
83 */ | |
84 public static final String LINE_SEPARATOR = System.getProperty("line.separator"); | |
85 | |
86 /** | |
87 * Creates a new log stream. | |
88 * | |
89 * @param os the underlying output stream to which prints are sent | |
90 */ | |
91 public LogStream(OutputStream os) { | |
92 ps = os instanceof PrintStream ? (PrintStream) os : new PrintStream(os); | |
93 lineBuffer = new StringBuilder(100); | |
94 } | |
95 | |
96 /** | |
97 * Creates a new log stream that shares the same {@linkplain #ps output stream} as a given {@link LogStream}. | |
98 * | |
99 * @param log a LogStream whose output stream is shared with this one | |
100 */ | |
101 public LogStream(LogStream log) { | |
102 ps = log.ps; | |
103 lineBuffer = new StringBuilder(100); | |
104 } | |
105 | |
106 /** | |
107 * Prepends {@link #indentation} to the current output line until its write position is equal to the | |
108 * current {@linkplain #indentationLevel()} level. | |
109 */ | |
110 private void indent() { | |
111 if (ps != null) { | |
112 if (!indentationDisabled && indentationLevel != 0) { | |
113 while (lineBuffer.length() < indentationLevel) { | |
114 lineBuffer.append(indentation); | |
115 } | |
116 } | |
117 } | |
118 } | |
119 | |
120 private LogStream flushLine(boolean withNewline) { | |
121 if (ps != null) { | |
122 if (withNewline) { | |
123 lineBuffer.append(LINE_SEPARATOR); | |
124 } | |
125 ps.print(lineBuffer.toString()); | |
126 ps.flush(); | |
127 lineBuffer.setLength(0); | |
128 } | |
129 return this; | |
130 } | |
131 | |
132 /** | |
133 * Flushes the stream. This is done by terminating the current line if it is not at position 0 | |
134 * and then flushing the underlying output stream. | |
135 */ | |
136 public void flush() { | |
137 if (ps != null) { | |
138 if (lineBuffer.length() != 0) { | |
139 flushLine(false); | |
140 } | |
141 ps.flush(); | |
142 } | |
143 } | |
144 | |
145 /** | |
146 * Gets the current column position of this log stream. | |
147 * | |
148 * @return the current column position of this log stream | |
149 */ | |
150 public int position() { | |
151 return lineBuffer == null ? 0 : lineBuffer.length(); | |
152 | |
153 } | |
154 | |
155 /** | |
156 * Gets the current indentation level for this log stream. | |
157 * | |
158 * @return the current indentation level for this log stream. | |
159 */ | |
160 public int indentationLevel() { | |
161 return indentationLevel; | |
162 } | |
163 | |
164 /** | |
165 * Adjusts the current indentation level of this log stream. | |
166 * | |
167 * @param delta | |
168 */ | |
169 public void adjustIndentation(int delta) { | |
170 if (delta < 0) { | |
171 indentationLevel = Math.max(0, indentationLevel + delta); | |
172 } else { | |
173 indentationLevel += delta; | |
174 } | |
175 } | |
176 | |
177 /** | |
178 * Gets the current indentation character of this log stream. | |
179 */ | |
180 public char indentation() { | |
181 return indentation; | |
182 } | |
183 | |
184 public void disableIndentation() { | |
185 indentationDisabled = true; | |
186 } | |
187 | |
188 public void enableIndentation() { | |
189 indentationDisabled = false; | |
190 } | |
191 | |
192 /** | |
193 * Sets the character used for indentation. | |
194 */ | |
195 public void setIndentation(char c) { | |
196 indentation = c; | |
197 } | |
198 | |
199 /** | |
200 * Advances this stream's {@linkplain #position() position} to a given position by | |
201 * repeatedly appending a given character as necessary. | |
202 * | |
203 * @param position the position to which this stream's position will be advanced | |
204 * @param filler the character used to pad the stream | |
205 */ | |
206 public LogStream fillTo(int position, char filler) { | |
207 if (ps != null) { | |
208 indent(); | |
209 while (lineBuffer.length() < position) { | |
210 lineBuffer.append(filler); | |
211 } | |
212 } | |
213 return this; | |
214 } | |
215 | |
216 /** | |
217 * Writes a boolean value to this stream as {@code "true"} or {@code "false"}. | |
218 * | |
219 * @param b the value to be printed | |
220 * @return this {@link LogStream} instance | |
221 */ | |
222 public LogStream print(boolean b) { | |
223 if (ps != null) { | |
224 indent(); | |
225 lineBuffer.append(b); | |
226 } | |
227 return this; | |
228 } | |
229 | |
230 /** | |
231 * Writes a boolean value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
232 * | |
233 * @param b the value to be printed | |
234 * @return this {@link LogStream} instance | |
235 */ | |
236 public LogStream println(boolean b) { | |
237 if (ps != null) { | |
238 indent(); | |
239 lineBuffer.append(b); | |
240 return flushLine(true); | |
241 } | |
242 return this; | |
243 } | |
244 | |
245 /** | |
246 * Writes a character value to this stream. | |
247 * | |
248 * @param c the value to be printed | |
249 * @return this {@link LogStream} instance | |
250 */ | |
251 public LogStream print(char c) { | |
252 if (ps != null) { | |
253 indent(); | |
254 lineBuffer.append(c); | |
255 if (c == '\n') { | |
256 if (lineBuffer.indexOf(LINE_SEPARATOR, lineBuffer.length() - LINE_SEPARATOR.length()) != -1) { | |
257 flushLine(false); | |
258 } | |
259 } | |
260 } | |
261 return this; | |
262 } | |
263 | |
264 /** | |
265 * Writes a character value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
266 * | |
267 * @param c the value to be printed | |
268 * @return this {@link LogStream} instance | |
269 */ | |
270 public LogStream println(char c) { | |
271 if (ps != null) { | |
272 indent(); | |
273 lineBuffer.append(c); | |
274 flushLine(true); | |
275 } | |
276 return this; | |
277 } | |
278 | |
279 /** | |
280 * Prints an int value. | |
281 * | |
282 * @param i the value to be printed | |
283 * @return this {@link LogStream} instance | |
284 */ | |
285 public LogStream print(int i) { | |
286 if (ps != null) { | |
287 indent(); | |
288 lineBuffer.append(i); | |
289 } | |
290 return this; | |
291 } | |
292 | |
293 /** | |
294 * Writes an int value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
295 * | |
296 * @param i the value to be printed | |
297 * @return this {@link LogStream} instance | |
298 */ | |
299 public LogStream println(int i) { | |
300 if (ps != null) { | |
301 indent(); | |
302 lineBuffer.append(i); | |
303 return flushLine(true); | |
304 } | |
305 return this; | |
306 } | |
307 | |
308 /** | |
309 * Writes a float value to this stream. | |
310 * | |
311 * @param f the value to be printed | |
312 * @return this {@link LogStream} instance | |
313 */ | |
314 public LogStream print(float f) { | |
315 if (ps != null) { | |
316 indent(); | |
317 lineBuffer.append(f); | |
318 } | |
319 return this; | |
320 } | |
321 | |
322 /** | |
323 * Writes a float value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
324 * | |
325 * @param f the value to be printed | |
326 * @return this {@link LogStream} instance | |
327 */ | |
328 public LogStream println(float f) { | |
329 if (ps != null) { | |
330 indent(); | |
331 lineBuffer.append(f); | |
332 return flushLine(true); | |
333 } | |
334 return this; | |
335 } | |
336 | |
337 /** | |
338 * Writes a long value to this stream. | |
339 * | |
340 * @param l the value to be printed | |
341 * @return this {@link LogStream} instance | |
342 */ | |
343 public LogStream print(long l) { | |
344 if (ps != null) { | |
345 indent(); | |
346 lineBuffer.append(l); | |
347 } | |
348 return this; | |
349 } | |
350 | |
351 /** | |
352 * Writes a long value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
353 * | |
354 * @param l the value to be printed | |
355 * @return this {@link LogStream} instance | |
356 */ | |
357 public LogStream println(long l) { | |
358 if (ps != null) { | |
359 indent(); | |
360 lineBuffer.append(l); | |
361 return flushLine(true); | |
362 } | |
363 return this; | |
364 } | |
365 | |
366 /** | |
367 * Writes a double value to this stream. | |
368 * | |
369 * @param d the value to be printed | |
370 * @return this {@link LogStream} instance | |
371 */ | |
372 public LogStream print(double d) { | |
373 if (ps != null) { | |
374 indent(); | |
375 lineBuffer.append(d); | |
376 } | |
377 return this; | |
378 } | |
379 | |
380 /** | |
381 * Writes a double value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
382 * | |
383 * @param d the value to be printed | |
384 * @return this {@link LogStream} instance | |
385 */ | |
386 public LogStream println(double d) { | |
387 if (ps != null) { | |
388 indent(); | |
389 lineBuffer.append(d); | |
390 return flushLine(true); | |
391 } | |
392 return this; | |
393 } | |
394 | |
395 /** | |
396 * Writes a {@code String} value to this stream. This method ensures that the {@linkplain #position() position} | |
397 * of this stream is updated correctly with respect to any {@linkplain #LINE_SEPARATOR line separators} | |
398 * present in {@code s}. | |
399 * | |
400 * @param s the value to be printed | |
401 * @return this {@link LogStream} instance | |
402 */ | |
403 public LogStream print(String s) { | |
404 if (ps != null) { | |
405 if (s == null) { | |
406 indent(); | |
407 lineBuffer.append(s); | |
408 return this; | |
409 } | |
410 | |
411 int index = 0; | |
412 int next = s.indexOf(LINE_SEPARATOR, index); | |
413 while (index < s.length()) { | |
414 indent(); | |
415 if (next > index) { | |
416 lineBuffer.append(s.substring(index, next)); | |
417 flushLine(true); | |
418 index = next + LINE_SEPARATOR.length(); | |
419 next = s.indexOf(LINE_SEPARATOR, index); | |
420 } else { | |
421 lineBuffer.append(s.substring(index)); | |
422 break; | |
423 } | |
424 } | |
425 } | |
426 return this; | |
427 } | |
428 | |
429 /** | |
430 * Writes a {@code String} value to this stream followed by a {@linkplain #LINE_SEPARATOR line separator}. | |
431 * | |
432 * @param s the value to be printed | |
433 * @return this {@link LogStream} instance | |
434 */ | |
435 public LogStream println(String s) { | |
436 if (ps != null) { | |
437 print(s); | |
438 flushLine(true); | |
439 } | |
440 return this; | |
441 } | |
442 | |
443 /** | |
444 * Writes a formatted string to this stream. | |
445 * | |
446 * @param format a format string as described in {@link String#format(String, Object...)} | |
447 * @param args the arguments to be formatted | |
448 * @return this {@link LogStream} instance | |
449 */ | |
450 public LogStream printf(String format, Object... args) { | |
451 if (ps != null) { | |
452 print(String.format(format, args)); | |
453 } | |
454 return this; | |
455 } | |
456 | |
457 /** | |
458 * Writes a {@linkplain #LINE_SEPARATOR line separator} to this stream. | |
459 * | |
460 * @return this {@code LogStream} instance | |
461 */ | |
462 public LogStream println() { | |
463 if (ps != null) { | |
464 indent(); | |
465 flushLine(true); | |
466 } | |
467 return this; | |
468 } | |
469 } |