1 /* |
|
2 * Copyright (c) 2002-2016, the original author or authors. |
|
3 * |
|
4 * This software is distributable under the BSD license. See the terms of the |
|
5 * BSD license in the documentation provided with this software. |
|
6 * |
|
7 * http://www.opensource.org/licenses/bsd-license.php |
|
8 */ |
|
9 package jdk.internal.jline.console.internal; |
|
10 |
|
11 import jdk.internal.jline.console.ConsoleReader; |
|
12 |
|
13 import java.io.IOException; |
|
14 import java.io.InputStream; |
|
15 import java.io.SequenceInputStream; |
|
16 import java.util.Enumeration; |
|
17 |
|
18 // FIXME: Clean up API and move to jline.console.runner package |
|
19 |
|
20 /** |
|
21 * An {@link InputStream} implementation that wraps a {@link ConsoleReader}. |
|
22 * It is useful for setting up the {@link System#in} for a generic console. |
|
23 * |
|
24 * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a> |
|
25 * @since 2.7 |
|
26 */ |
|
27 class ConsoleReaderInputStream |
|
28 extends SequenceInputStream |
|
29 { |
|
30 private static InputStream systemIn = System.in; |
|
31 |
|
32 public static void setIn() throws IOException { |
|
33 setIn(new ConsoleReader()); |
|
34 } |
|
35 |
|
36 public static void setIn(final ConsoleReader reader) { |
|
37 System.setIn(new ConsoleReaderInputStream(reader)); |
|
38 } |
|
39 |
|
40 /** |
|
41 * Restore the original {@link System#in} input stream. |
|
42 */ |
|
43 public static void restoreIn() { |
|
44 System.setIn(systemIn); |
|
45 } |
|
46 |
|
47 public ConsoleReaderInputStream(final ConsoleReader reader) { |
|
48 super(new ConsoleEnumeration(reader)); |
|
49 } |
|
50 |
|
51 private static class ConsoleEnumeration |
|
52 implements Enumeration<InputStream> |
|
53 { |
|
54 private final ConsoleReader reader; |
|
55 private ConsoleLineInputStream next = null; |
|
56 private ConsoleLineInputStream prev = null; |
|
57 |
|
58 public ConsoleEnumeration(final ConsoleReader reader) { |
|
59 this.reader = reader; |
|
60 } |
|
61 |
|
62 public InputStream nextElement() { |
|
63 if (next != null) { |
|
64 InputStream n = next; |
|
65 prev = next; |
|
66 next = null; |
|
67 |
|
68 return n; |
|
69 } |
|
70 |
|
71 return new ConsoleLineInputStream(reader); |
|
72 } |
|
73 |
|
74 public boolean hasMoreElements() { |
|
75 // the last line was null |
|
76 if ((prev != null) && (prev.wasNull == true)) { |
|
77 return false; |
|
78 } |
|
79 |
|
80 if (next == null) { |
|
81 next = (ConsoleLineInputStream) nextElement(); |
|
82 } |
|
83 |
|
84 return next != null; |
|
85 } |
|
86 } |
|
87 |
|
88 private static class ConsoleLineInputStream |
|
89 extends InputStream |
|
90 { |
|
91 private final ConsoleReader reader; |
|
92 private String line = null; |
|
93 private int index = 0; |
|
94 private boolean eol = false; |
|
95 protected boolean wasNull = false; |
|
96 |
|
97 public ConsoleLineInputStream(final ConsoleReader reader) { |
|
98 this.reader = reader; |
|
99 } |
|
100 |
|
101 public int read() throws IOException { |
|
102 if (eol) { |
|
103 return -1; |
|
104 } |
|
105 |
|
106 if (line == null) { |
|
107 line = reader.readLine(); |
|
108 } |
|
109 |
|
110 if (line == null) { |
|
111 wasNull = true; |
|
112 return -1; |
|
113 } |
|
114 |
|
115 if (index >= line.length()) { |
|
116 eol = true; |
|
117 return '\n'; // lines are ended with a newline |
|
118 } |
|
119 |
|
120 return line.charAt(index++); |
|
121 } |
|
122 } |
|
123 } |
|