/** * 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; import java.nio.CharBuffer; import java.util.Arrays; import static java.lang.Character.*; /** * @author Santhosh Kumar T */ public final class Chars implements CharSequence{ private char buff[] = new char[100]; public int count; private int stack[] = new int[50]; int free = 0; public boolean isBuffering(){ return free>0; } public void push(){ if(free>=stack.length) stack = Arrays.copyOf(stack, stack.length<<1); stack[free++] = count; } public void expandCapacity(int increment){ int newCapacity = (buff.length+increment)<<1; if(newCapacity<0) newCapacity = Integer.MAX_VALUE; buff = Arrays.copyOf(buff, newCapacity); } public void append(char character){ if(count==buff.length) expandCapacity(1); buff[count++] = character; } public void append(char chars[], int offset, int len){ if(count+len==chars.length) expandCapacity(len); System.arraycopy(chars, offset, buff, count, len); count += len; } public void append(int codePoint){ if(codePoint<MIN_SUPPLEMENTARY_CODE_POINT){ if(count==buff.length) expandCapacity(1); buff[count++] = (char)codePoint; }else{ if(count==buff.length-1) expandCapacity(2); int offset = codePoint - MIN_SUPPLEMENTARY_CODE_POINT; buff[count++] = (char)((offset >>> 10) + MIN_HIGH_SURROGATE); buff[count++] = (char)((offset & 0x3ff) + MIN_LOW_SURROGATE); } } public Chars pop(int begin, int end){ offset = begin + stack[--free]; length = count-end; if(free==0) count = 0; return this; } public void clear(){ free = count = 0; } /*-------------------------------------------------[ CharSequence ]---------------------------------------------------*/ private int offset, length; public char[] array(){ return buff; } public int offset(){ return offset; } public int length(){ return length; } @Override public char charAt(int index){ if(index<0 || index>=length) throw new IndexOutOfBoundsException(index+" is not in range [0, "+length+")"); else return buff[offset+index]; } @Override public CharSequence subSequence(int start, int end){ if(start<0) throw new IndexOutOfBoundsException("CharArray index out of range: "+start); if(end>length) throw new IndexOutOfBoundsException("CharArray index out of range: "+end); if(start>end) throw new IndexOutOfBoundsException("CharArray index out of range: "+(end-start)); return (start==0 && end==length) ? this : CharBuffer.wrap(buff, this.offset+start, end-start); } @Override public String toString(){ return new String(buff, offset, length); } }