001 /**
002 * jline - Java console input library
003 * Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or
007 * without modification, are permitted provided that the following
008 * conditions are met:
009 *
010 * Redistributions of source code must retain the above copyright
011 * notice, this list of conditions and the following disclaimer.
012 *
013 * Redistributions in binary form must reproduce the above copyright
014 * notice, this list of conditions and the following disclaimer
015 * in the documentation and/or other materials provided with
016 * the distribution.
017 *
018 * Neither the name of JLine nor the names of its contributors
019 * may be used to endorse or promote products derived from this
020 * software without specific prior written permission.
021 *
022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
025 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
026 * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
027 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
028 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
029 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
031 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
033 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
034 * OF THE POSSIBILITY OF SUCH DAMAGE.
035 */
036 package jline;
037
038 import java.io.*;
039 import java.util.*;
040
041
042 /**
043 * An {@link InputStream} implementation that wraps a {@link ConsoleReader}.
044 * It is useful for setting up the {@link System#in} for a generic
045 * console.
046 *
047 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
048 */
049 public class ConsoleReaderInputStream
050 extends SequenceInputStream
051 {
052 private static InputStream systemIn = System.in;
053
054
055 public static void setIn ()
056 throws IOException
057 {
058 setIn (new ConsoleReader ());
059 }
060
061
062 public static void setIn (final ConsoleReader reader)
063 {
064 System.setIn (new ConsoleReaderInputStream (reader));
065 }
066
067
068 /**
069 * Restore the original {@link System#in} input stream.
070 */
071 public static void restoreIn ()
072 {
073 System.setIn (systemIn);
074 }
075
076
077 public ConsoleReaderInputStream (final ConsoleReader reader)
078 {
079 super (new ConsoleEnumeration (reader));
080 }
081
082
083 private static class ConsoleEnumeration
084 implements Enumeration
085 {
086 private final ConsoleReader reader;
087 private ConsoleLineInputStream next = null;
088 private ConsoleLineInputStream prev = null;
089
090
091 public ConsoleEnumeration (final ConsoleReader reader)
092 {
093 this.reader = reader;
094 }
095
096
097 public Object nextElement ()
098 {
099 if (next != null)
100 {
101 InputStream n = next;
102 prev = next;
103 next = null;
104 return n;
105 }
106
107 return new ConsoleLineInputStream (reader);
108 }
109
110
111 public boolean hasMoreElements ()
112 {
113 // the last line was null
114 if (prev != null && prev.wasNull == true)
115 return false;
116
117 if (next == null)
118 next = (ConsoleLineInputStream)nextElement ();
119
120 return next != null;
121 }
122 }
123
124
125 private static class ConsoleLineInputStream
126 extends InputStream
127 {
128 private final ConsoleReader reader;
129 private String line = null;
130 private int index = 0;
131 private boolean eol = false;
132 protected boolean wasNull = false;
133
134 public ConsoleLineInputStream (final ConsoleReader reader)
135 {
136 this.reader = reader;
137 }
138
139
140 public int read ()
141 throws IOException
142 {
143 if (eol)
144 return -1;
145
146 if (line == null)
147 line = reader.readLine ();
148
149 if (line == null)
150 {
151 wasNull = true;
152 return -1;
153 }
154
155 if (index >= line.length ())
156 {
157 eol = true;
158 return '\n'; // lines are ended with a newline
159 }
160
161 return line.charAt (index++);
162 }
163 }
164 }
165