1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
3 package edu.berkeley.sbp.chr;
6 import java.lang.reflect.*;
7 import java.lang.ref.*;
8 import edu.berkeley.sbp.*;
9 import edu.berkeley.sbp.util.*;
10 import edu.berkeley.sbp.misc.*;
11 import edu.berkeley.sbp.Input.Location;
13 public class CharInput extends Cartesian.Input<Character> {
15 private static class RollbackReader extends Reader {
16 private final Reader r;
17 public RollbackReader(Reader r) { this.r = r; }
19 private char[] queue = new char[1024];
23 private void unread(char c) {
24 if (tail >= queue.length) {
25 if (tail - head > queue.length/2) {
26 char[] queue2 = new char[queue.length * 2];
27 System.arraycopy(queue, head, queue2, 0, tail-head);
29 System.arraycopy(queue, head, queue, 0, tail-head);
37 public void close() throws IOException { r.close(); }
38 public int read() throws IOException {
43 public int read(char cbuf[]) throws IOException { return read(cbuf, 0, cbuf.length); }
44 public int read(char cbuf[], int off, int len) throws IOException {
46 int count = Math.min(len, tail-head);
47 System.arraycopy(queue, head, cbuf, off, count);
51 return r.read(cbuf, off, len);
53 public long skip(long n) throws IOException { return r.skip(n); }
54 public boolean ready() throws IOException { return true; }
55 public boolean markSupported() { return false; }
56 public void mark(int readAheadLimit) throws IOException { throw new IOException("not supported"); }
57 public void reset() throws IOException { throw new IOException("not supported"); }
60 private final RollbackReader r;
62 public CharInput(String s) { this(new StringReader(s)); }
63 public CharInput(Reader r) { this(r, null); }
64 public CharInput(Reader r, String s) { this.r = new RollbackReader(new BufferedReader(r)); }
65 public CharInput(InputStream i) { this(i, null); }
66 public CharInput(InputStream i, String s) { this(new InputStreamReader(i), s); }
68 public CharInput(InputStream i, String s, boolean indent) {
69 this(new InputStreamReader(i), s);
74 boolean indent = false;
75 private int count = 0;
76 private StringBuilder cache = new StringBuilder();
78 public void setCacheEnabled(boolean enabled) {
79 if (!enabled) cache = null;
80 else if (cache == null) cache = new StringBuilder();
84 int lastIndentation = 0;
85 int queuedIndentation = 0;
86 char queuedCharacter = ' ';
89 public boolean isCR() { return cr; }
90 public Character _next() throws IOException {
91 Character ret = __next();
92 if (ret==null) return null;
93 char c = ret.charValue();
95 if (ret==CharAtom.left) System.out.print("\033[31m{\033[0m");
96 else if (ret==CharAtom.right) System.out.print("\033[31m}\033[0m");
97 else System.out.print(c+"");
101 public Character __next() throws IOException {
105 if (queuedIndentation < 0) {
107 return CharAtom.right;
109 if (queuedSpaces > 0) {
113 if (queuedIndentation > 0) {
115 return CharAtom.left;
118 if (queuedCharacter != ' ') {
119 char ret = queuedCharacter;
120 queuedCharacter = ' ';
126 /*System.err.print("\r...done \r"); */
127 if (indent && indentation >= 0) {
128 redent(indentation - lastIndentation);
129 //System.err.println("\r \rindent: " + (indentation - lastIndentation));
130 lastIndentation = indentation;
137 if (cache != null) cache.append(c);
143 } else if (c==' ' && indentation >= 0) {
145 } else if (indentation >= 0) {
146 //System.err.println("\r \rindent: " + (indentation - lastIndentation));
147 redent(indentation - lastIndentation);
149 lastIndentation = indentation;
157 private void redent(int i) {
158 if (i<0) { r.unread(CharAtom.right); redent(i+1); return; }
159 if (i>0) { r.unread(CharAtom.left); redent(i-1); return; }
162 int queuedSpaces = 0;
164 public String showRegion(Region<Character> rc) {
165 if (cache == null) return null;
166 Cartesian.Region r = (Cartesian.Region)rc;
167 int start = r.getStart().getScalar()+1;
168 int end = r.getEnd().getScalar()+1;
169 if (start < 0) start = 0;
170 if (end < start) end = start;
171 if (end > cache.length()) end = cache.length();
173 if (end-start < 60) ret = cachesubstring(start, end);
174 else ret = cachesubstring(start, start+25) +
176 cachesubstring(end-25, end);
177 return StringUtil.escapify(ret, "\n\r");
180 private String cachesubstring(int start, int end) {
181 if (start < 0) start = 0;
182 if (end < 0) end = 0;
183 if (start >= cache.length()) start = cache.length();
184 if (end >= cache.length()) end = cache.length();
185 return cache.substring(start, end);