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 }