001 /*
002 * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved.
003 *
004 * This software is distributable under the BSD license. See the terms of the
005 * BSD license in the documentation provided with this software.
006 */
007 package jline;
008
009 import java.io.*;
010 import java.util.*;
011
012 /**
013 * An {@link InputStream} implementation that wraps a {@link ConsoleReader}.
014 * It is useful for setting up the {@link System#in} for a generic
015 * console.
016 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
017 */
018 public class ConsoleReaderInputStream extends SequenceInputStream {
019 private static InputStream systemIn = System.in;
020
021 public static void setIn() throws IOException {
022 setIn(new ConsoleReader());
023 }
024
025 public static void setIn(final ConsoleReader reader) {
026 System.setIn(new ConsoleReaderInputStream(reader));
027 }
028
029 /**
030 * Restore the original {@link System#in} input stream.
031 */
032 public static void restoreIn() {
033 System.setIn(systemIn);
034 }
035
036 public ConsoleReaderInputStream(final ConsoleReader reader) {
037 super(new ConsoleEnumeration(reader));
038 }
039
040 private static class ConsoleEnumeration implements Enumeration {
041 private final ConsoleReader reader;
042 private ConsoleLineInputStream next = null;
043 private ConsoleLineInputStream prev = null;
044
045 public ConsoleEnumeration(final ConsoleReader reader) {
046 this.reader = reader;
047 }
048
049 public Object nextElement() {
050 if (next != null) {
051 InputStream n = next;
052 prev = next;
053 next = null;
054
055 return n;
056 }
057
058 return new ConsoleLineInputStream(reader);
059 }
060
061 public boolean hasMoreElements() {
062 // the last line was null
063 if ((prev != null) && (prev.wasNull == true)) {
064 return false;
065 }
066
067 if (next == null) {
068 next = (ConsoleLineInputStream) nextElement();
069 }
070
071 return next != null;
072 }
073 }
074
075 private static class ConsoleLineInputStream extends InputStream {
076 private final ConsoleReader reader;
077 private String line = null;
078 private int index = 0;
079 private boolean eol = false;
080 protected boolean wasNull = false;
081
082 public ConsoleLineInputStream(final ConsoleReader reader) {
083 this.reader = reader;
084 }
085
086 public int read() throws IOException {
087 if (eol) {
088 return -1;
089 }
090
091 if (line == null) {
092 line = reader.readLine();
093 }
094
095 if (line == null) {
096 wasNull = true;
097 return -1;
098 }
099
100 if (index >= line.length()) {
101 eol = true;
102 return '\n'; // lines are ended with a newline
103 }
104
105 return line.charAt(index++);
106 }
107 }
108 }