/*
* Copyright 2015-present 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.buck.util;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public interface ProcessListeners {
class CapturingListener implements ListeningProcessExecutor.ProcessListener {
protected ListeningProcessExecutor.LaunchedProcess process;
public ByteArrayOutputStream capturedStdout = new ByteArrayOutputStream();
public ByteArrayOutputStream capturedStderr = new ByteArrayOutputStream();
@Override
public void onStart(ListeningProcessExecutor.LaunchedProcess process) {
this.process = process;
}
@Override
public void onExit(int exitCode) {}
@Override
public void onStdout(ByteBuffer buffer, boolean closed) {
writeBufferToStream(buffer, capturedStdout);
}
@Override
public void onStderr(ByteBuffer buffer, boolean closed) {
writeBufferToStream(buffer, capturedStderr);
}
private final void writeBufferToStream(ByteBuffer buffer, ByteArrayOutputStream stream) {
if (buffer.hasArray()) {
stream.write(buffer.array(), buffer.position(), buffer.remaining());
buffer.position(buffer.limit());
} else {
byte[] bufferBytes = new byte[buffer.remaining()];
// This updates buffer.position().
buffer.get(bufferBytes);
stream.write(bufferBytes, 0, bufferBytes.length);
}
}
@Override
public boolean onStdinReady(ByteBuffer buffer) {
return false;
}
}
class StdinWritingListener extends CapturingListener {
private final ByteBuffer bufferToWrite;
public StdinWritingListener(String string) {
bufferToWrite = ByteBuffer.wrap(string.getBytes(StandardCharsets.UTF_8));
}
@Override
public boolean onStdinReady(ByteBuffer buffer) {
if (!bufferToWrite.hasRemaining()) {
process.closeStdin(true);
buffer.flip();
return false;
}
if (buffer.remaining() >= bufferToWrite.remaining()) {
// All our data fits in the buffer.
buffer.put(bufferToWrite);
} else {
// Not all our data fits in the buffer. Copy as much as we can,
// then indicate we have more data to write.
ByteBuffer subBuffer = bufferToWrite.slice();
subBuffer.limit(buffer.remaining());
buffer.put(subBuffer);
bufferToWrite.position(bufferToWrite.position() + subBuffer.limit());
}
buffer.flip();
return true;
}
}
}