001 /**
002 * jline - Java console input library
003 * Copyright (c) 2002,2003 Marc Prud'hommeaux mwp1@cornell.edu
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either
008 * version 2.1 of the License, or (at your option) any later version.
009 *
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013 * Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public
016 * License along with this library; if not, write to the Free Software
017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018 */
019 package jline;
020
021 import java.io.*;
022 import java.util.*;
023
024
025 /**
026 * An {@link InputStream} implementation that wraps a {@link ConsoleReader}.
027 * It is useful for setting up the {@link System#in} for a generic
028 * console.
029 *
030 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
031 */
032 public class ConsoleReaderInputStream
033 extends SequenceInputStream
034 {
035 private static InputStream systemIn = System.in;
036
037
038 public static void setIn ()
039 throws IOException
040 {
041 setIn (new ConsoleReader ());
042 }
043
044
045 public static void setIn (final ConsoleReader reader)
046 {
047 System.setIn (new ConsoleReaderInputStream (reader));
048 }
049
050
051 /**
052 * Restore the original {@link System#in} input stream.
053 */
054 public static void restoreIn ()
055 {
056 System.setIn (systemIn);
057 }
058
059
060 public ConsoleReaderInputStream (final ConsoleReader reader)
061 {
062 super (new ConsoleEnumeration (reader));
063 }
064
065
066 private static class ConsoleEnumeration
067 implements Enumeration
068 {
069 private final ConsoleReader reader;
070 private ConsoleLineInputStream next = null;
071 private ConsoleLineInputStream prev = null;
072
073
074 public ConsoleEnumeration (final ConsoleReader reader)
075 {
076 this.reader = reader;
077 }
078
079
080 public Object nextElement ()
081 {
082 if (next != null)
083 {
084 InputStream n = next;
085 prev = next;
086 next = null;
087 return n;
088 }
089
090 return new ConsoleLineInputStream (reader);
091 }
092
093
094 public boolean hasMoreElements ()
095 {
096 // the last line was null
097 if (prev != null && prev.wasNull == true)
098 return false;
099
100 if (next == null)
101 next = (ConsoleLineInputStream)nextElement ();
102
103 return next != null;
104 }
105 }
106
107
108 private static class ConsoleLineInputStream
109 extends InputStream
110 {
111 private final ConsoleReader reader;
112 private String line = null;
113 private int index = 0;
114 private boolean eol = false;
115 protected boolean wasNull = false;
116
117 public ConsoleLineInputStream (final ConsoleReader reader)
118 {
119 this.reader = reader;
120 }
121
122
123 public int read ()
124 throws IOException
125 {
126 if (eol)
127 return -1;
128
129 if (line == null)
130 line = reader.readLine ();
131
132 if (line == null)
133 {
134 wasNull = true;
135 return -1;
136 }
137
138 if (index >= line.length ())
139 {
140 eol = true;
141 return '\n'; // lines are ended with a newline
142 }
143
144 return line.charAt (index++);
145 }
146 }
147 }
148