package org.nutz.lang.stream; import java.io.IOException; import java.io.Reader; import java.util.LinkedList; /** * 队列InputStream * @author juqkai(juqkai@gmail.com) */ public class QueueReader extends Reader{ //原始流 private Reader is; //缓存 private LinkedList<Integer> cache = new LinkedList<Integer>(); //peek索引 private int peekindex = 0; //是否到流尾 private boolean end = false; //列 private int col = 0; //行 private int row = 1; public QueueReader(Reader is) { this.is = is; } /** * 读取一项数据 * @param ends 结束符, 默认' ', '\r', '\n' * @return * @throws IOException */ public String readItem(char ... ends) throws IOException{ StringBuilder sb = new StringBuilder(); while(true){ switch (peek()) { case ' ': case '\r': case '\n': case -1: return sb.toString(); default: for(Character c : ends){ if(c.equals(peek())){ return sb.toString(); } } sb.append((char)poll()); } } } /** * 读取一行 * @return * @throws IOException */ public String readLine() throws IOException{ StringBuilder sb = new StringBuilder(); for(;;){ int v = peek(); if(v == '\r' || v == '\n'){ poll(); v = peekNext(); if(v == '\r' || v == '\n'){ poll(); } break; } sb.append((char)poll()); } return sb.toString(); } /** * 读取头部字节, 并删除 * @return * @throws IOException */ public int poll() throws IOException{ peekindex = 0; int v = -1; if(cache.size() <= 0){ v = is.read(); } else { v = cache.poll(); } if(v == -1){ end = true; } if(v == '\n'){ col = 0; row ++; } else { col ++; } return v; } /** * 访问头部开始第几个字节, 不删除 * @param index * @return * @throws IOException */ public int peek(int index) throws IOException{ while(cache.size() <= index){ cache.add(is.read()); } return cache.get(index); } /** * 访问上次peekNext访问的下个位置的字节, 未访问过则访问索引0, poll, peek后归零, 不删除 * @return * @throws IOException */ public int peekNext() throws IOException{ return peek(peekindex ++); } /** * 访问头部字节, 不删除 * @return * @throws IOException */ public int peek() throws IOException{ peekindex = 0; int v = peek(peekindex ++); if(v == -1){ end = true; } return v; } /** * 跳过和丢弃输入流中的数据 */ public long skip(long n) throws IOException { int s = cache.size(); if(s > 0){ if(s < n){ n = n - s; } else { for(int i = 0; i < n; i ++){ cache.poll(); } return n; } } return super.skip(n) + s; } /** * 是否结束 * @return */ public boolean isEnd(){ return end; } public int read(char[] cbuf, int off, int len) throws IOException { for(int i = 0; i < len ; i++){ if(isEnd()){ return -1; } cbuf[off + i] = (char) poll(); } return len; } public void close() throws IOException { is.close(); cache.clear(); } /** * 是否以 start 开始 * @param start * @return * @throws IOException */ public boolean startWith(String start) throws IOException{ char[] cs = start.toCharArray(); int i = 0; for(;i < cs.length; i ++){ if(peek(i) != cs[i]){ return false; } } return true; } public int getCol() { return col; } public int getRow() { return row; } }