/**
* Copyright 2015 Santhosh Kumar Tekuri
*
* The JLibs authors license this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package jlibs.nbp;
/**
* @author Santhosh Kumar T
*/
public final class Stream{
final int chars[];
int begin = 0;
int end = 0;
public Stream(int capacity){
chars = new int[capacity+1];
}
int capacity(){
return chars.length-1;
}
public int length(){
int len = end-begin;
return len<0 ? len+chars.length : len;
}
public int charAt(int index){
assert index>=0 && index<length();
return chars[(begin+index)%chars.length];
}
public void clear(){
begin = end = lookAhead.end = 0;
}
String toString(int length){
StringBuilder buff = new StringBuilder();
for(int i=0; i<length; i++){
int data = charAt(i);
if(data==-1)
buff.append("<EOF>");
else
buff.appendCodePoint(data);
}
return buff.toString();
}
@Override
public String toString(){
return toString(length());
}
public final LookAhead lookAhead = new LookAhead();
public final class LookAhead{
int end;
public int length(){
int len = end-begin;
return len<0 ? len+chars.length : len;
}
public boolean isEmpty(){
return end==begin;
}
public int charAt(int index){
assert index>=0 && index<length();
return chars[(begin+index)%chars.length];
}
// returns true if this was a fresh data added
public boolean add(int ch){
if(this.end!=Stream.this.end){ // hasNext()
assert getNext()==ch : "expected char: "+ch;
end = (end+1)%chars.length;
return false;
}else{
assert capacity()>Stream.this.length() : "Stream is Full";
chars[end] = ch;
this.end = Stream.this.end = (end+1)%chars.length;
return true;
}
}
public void consumed(){
assert Stream.this.length()>0 : "nothing found to consume";
if(begin==end) // length()==0
begin = end = (begin+1)%chars.length;
else
begin = (begin+1)%chars.length;
}
public void reset(){
end = begin;
}
public int getNext(){
return this.end==Stream.this.end ? -2 : chars[end];
}
@Override
public String toString(){
return Stream.this.toString(length());
}
}
}