Mercurial > hg > truffle
diff graal/com.oracle.max.base/src/com/sun/max/io/Streams.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.base/src/com/sun/max/io/Streams.java Sat Dec 17 19:59:18 2011 +0100 @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.max.io; + +import java.io.*; + +import com.sun.max.lang.*; + +/** + * Supplementary java.io utils. + */ +public final class Streams { + + private Streams() { + } + + public static void copy(InputStream inputStream, OutputStream outputStream) throws IOException { + final byte[] buffer = new byte[8192]; + int count; + while ((count = inputStream.read(buffer, 0, buffer.length)) > 0) { + outputStream.write(buffer, 0, count); + } + outputStream.flush(); + } + + public static void copy(Reader reader, Writer writer) throws IOException { + final char[] buffer = new char[8192]; + int count; + while ((count = reader.read(buffer, 0, buffer.length)) > 0) { + writer.write(buffer, 0, count); + } + writer.flush(); + } + + public static boolean equals(InputStream inputStream1, InputStream inputStream2) throws IOException { + final int n = 8192; + final byte[] buffer1 = new byte[n]; + final byte[] buffer2 = new byte[n]; + while (true) { + final int n1 = inputStream1.read(buffer1, 0, n); + final int n2 = inputStream2.read(buffer2, 0, n); + if (n1 != n2) { + return false; + } + if (n1 <= 0) { + return true; + } + if (!Bytes.equals(buffer1, buffer2, n)) { + return false; + } + } + } + + public static final class Redirector extends Thread { + + private final InputStream inputStream; + private final OutputStream outputStream; + private final String name; + private final int maxLines; + private final Process process; + private boolean closed; + + private Redirector(Process process, InputStream inputStream, OutputStream outputStream, String name, int maxLines) { + super("StreamRedirector{" + name + "}"); + this.inputStream = inputStream; + this.outputStream = outputStream; + this.name = name; + this.maxLines = maxLines; + this.process = process; + start(); + } + + public void close() { + closed = true; + } + + @Override + public void run() { + try { + try { + int line = 1; + while (!closed) { + if (inputStream.available() == 0) { + // A busy yielding loop is used so that this thread can be + // stopped via a call to close() by another thread. Otherwise, + // this thread could be blocked forever on an input stream + // that is not closed and does not have any available data. + // The prime example of course is System.in. + Thread.yield(); + // wait for a few milliseconds to avoid eating too much CPU. + Thread.sleep(10); + continue; + } + + final int b = inputStream.read(); + if (b < 0) { + return; + } + if (line <= maxLines) { + outputStream.write(b); + } + if (b == '\n') { + if (line == maxLines) { + outputStream.write(("<redirected stream concatenated after " + maxLines + " lines>" + System.getProperty("line.separator", "\n")).getBytes()); + } + ++line; + } + } + outputStream.flush(); + } catch (IOException ioe) { + try { + process.exitValue(); + + // This just means the process was terminated and the relevant pipe no longer exists + } catch (IllegalThreadStateException e) { + // Some other unexpected IO error occurred -> rethrow + throw e; + } + } + } catch (Throwable throwable) { + if (name != null) { + System.err.println("Error while redirecting sub-process stream for \"" + name + "\""); + } + throwable.printStackTrace(); + } + } + + } + + public static Redirector redirect(Process process, InputStream inputStream, OutputStream outputStream, String name, int maxLines) { + return new Redirector(process, inputStream, outputStream, name, maxLines); + } + + public static Redirector redirect(Process process, InputStream inputStream, OutputStream outputStream, String name) { + return redirect(process, inputStream, outputStream, name, Integer.MAX_VALUE); + } + + public static Redirector redirect(Process process, InputStream inputStream, OutputStream outputStream) { + return redirect(process, inputStream, outputStream, null, Integer.MAX_VALUE); + } + + /** + * Scans a given buffered input stream for a given sequence of bytes. If the sequence is found, then the read + * position of the stream is immediately after the sequence. Otherwise, the read position is at the end of the + * stream. + * + * @param stream + * the stream to search + * @param bytes + * the byte pattern to search for + * @return true if {@code bytes} is found in {@code stream} + */ + public static boolean search(BufferedInputStream stream, byte[] bytes) throws IOException { + if (bytes.length == 0) { + return true; + } + int b1 = stream.read(); + top: + while (b1 != -1) { + if (b1 == (bytes[0] & 0xff)) { + for (int i = 1; i < bytes.length; ++i) { + b1 = stream.read(); + if (b1 != (bytes[i] & 0xff)) { + continue top; + } + } + return true; + } + b1 = stream.read(); + } + return false; + } + + /** + * Scans a given buffered reader for a given sequence of characters. If the sequence is found, then the read + * position of the reader is immediately after the sequence. Otherwise, the read position is at the end of the + * reader. + * + * @param reader + * the reader to search + * @param chars + * the char pattern to search for + * @return true if {@code chars} is found in {@code reader} + */ + public static boolean search(BufferedReader reader, char[] chars) throws IOException { + if (chars.length == 0) { + return true; + } + int c1 = reader.read(); + top: + while (c1 != -1) { + if (c1 == chars[0]) { + for (int i = 1; i < chars.length; ++i) { + c1 = reader.read(); + if (c1 != chars[i]) { + continue top; + } + } + return true; + } + c1 = reader.read(); + } + return false; + } + + public static boolean startsWith(BufferedInputStream bufferedInputStream, byte[] bytes) throws IOException { + final byte[] data = new byte[bytes.length]; + bufferedInputStream.mark(bytes.length); + try { + readFully(bufferedInputStream, data); + if (java.util.Arrays.equals(data, bytes)) { + return true; + } + } catch (IOException ioException) { + // This is OK + } + bufferedInputStream.reset(); + return false; + } + + public static boolean startsWith(BufferedReader bufferedReader, char[] chars) throws IOException { + final char[] data = new char[chars.length]; + bufferedReader.mark(chars.length); + try { + readFully(bufferedReader, data); + if (java.util.Arrays.equals(data, chars)) { + return true; + } + } catch (IOException ioException) { + // This is OK + } + bufferedReader.reset(); + return false; + } + + /** + * @see DataInput#readFully(byte[]) + */ + public static byte[] readFully(InputStream stream, byte[] buffer) throws IOException { + return readFully(stream, buffer, 0, buffer.length); + } + + /** + * @see DataInput#readFully(byte[], int, int) + */ + public static byte[] readFully(InputStream stream, byte[] buffer, int offset, int length) throws IOException { + if (length < 0) { + throw new IndexOutOfBoundsException(); + } + int n = 0; + while (n < length) { + final int count = stream.read(buffer, offset + n, length - n); + if (count < 0) { + throw new EOFException((length - n) + " of " + length + " bytes unread"); + } + n += count; + } + return buffer; + } + + /** + * The analogous operation as {@link DataInput#readFully(byte[])} for {@link Reader}s. + */ + public static char[] readFully(Reader reader, char[] buffer) throws IOException { + return readFully(reader, buffer, 0, buffer.length); + } + + /** + * The analogous operation as {@link DataInput#readFully(byte[], int, int)} for {@link Reader}s. + */ + public static char[] readFully(Reader reader, char[] buffer, int offset, int length) throws IOException { + if (length < 0) { + throw new IndexOutOfBoundsException(); + } + int n = 0; + while (n < length) { + final int count = reader.read(buffer, offset + n, length - n); + if (count < 0) { + throw new TruncatedInputException((length - n) + " of " + length + " characters unread", n); + } + n += count; + } + return buffer; + } +}