/* * Copyright (C) 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.facebook.tools.io; import java.io.OutputStream; import java.io.PrintStream; import java.util.Arrays; public class TerminalPrintStream extends PrintStream { private final boolean interactive; private boolean currentLineIsStatus = false; private TerminalPrintStream(OutputStream out, boolean interactive) { super(out, true); this.interactive = interactive; } public static TerminalPrintStream interactive(OutputStream out) { return new TerminalPrintStream(out, true); } public static TerminalPrintStream noninteractive(OutputStream out) { return new TerminalPrintStream(out, false); } @Override public void write(int b) { eraseStatusLine(); super.write(b); } @Override public void write(byte[] buffer, int offset, int length) { if (currentLineIsStatus) { // HACK eraseStatusLine() modifies buffer, so we need to copy/restore byte[] bufferCopy = Arrays.copyOf(buffer, buffer.length); eraseStatusLine(); buffer = bufferCopy; } super.write(buffer, offset, length); } public void printfln(String format, Object... args) { printf(format, args); println(); } public void status(String line) { if (interactive) { print(line); flush(); currentLineIsStatus = true; } } public void status(boolean b) { status(Boolean.toString(b)); } public void status(char c) { status(Character.toString(c)); } public void status(int i) { status(Integer.toString(i)); } public void status(long l) { status(Long.toString(l)); } public void status(float f) { status(Float.toString(f)); } public void status(double d) { status(Double.toString(d)); } public void status(char[] s) { status(new String(s)); } public void status(Object obj) { status(String.valueOf(obj)); } public void statusf(String format, Object... args) { status(String.format(format, args)); } private void eraseStatusLine() { if (currentLineIsStatus) { currentLineIsStatus = false; flush(); print("\r\033[2K"); flush(); } } }