package railo.runtime.type; import java.io.Serializable; import java.util.ArrayList; import railo.commons.lang.SizeOf; import railo.runtime.exp.ExpressionException; /** * CFML array object */ public final class ArrayInt implements Sizeable,Serializable { private static final int NULL = 0; private int[] arr; private final int cap=32; private int size=0; private int offset=0; private int offCount=0; /** * constructor with default dimesnion (1) */ public ArrayInt() { arr=new int[offset+cap]; } /** * constructor with to data to fill * @param objects Objects array data to fill */ public ArrayInt(int[] objects) { arr=objects; size=arr.length; offset=0; } public int get(int key, int defaultValue) { if(key>size || key<1) { return defaultValue; } int o=arr[(offset+key)-1]; if(o==NULL) return defaultValue; return o; } public int get(int key) throws ExpressionException { if(key<1 || key>size) { throw invalidPosition(key); } int o=arr[(offset+key)-1]; if(o==NULL) { throw invalidPosition(key); } return o; } /** * Exception method if key doesn't exist at given position * @param pos * @return exception */ private ExpressionException invalidPosition(int pos) { return new ExpressionException("Element at position ["+pos+"] doesn't exist in array"); } public int set(int key, int value) { if(offset+key>arr.length)enlargeCapacity(key); if(key>size)size=key; return arr[(offset+key)-1]=value; } /** * !!! all methods that use this method must be sync * enlarge the inner array to given size * @param key min size of the array */ private synchronized void enlargeCapacity(int key) { int diff=offCount-offset; int newSize=arr.length; if(newSize<1) newSize=1; while(newSize<key+offset+diff) { newSize*=2; } if(newSize>arr.length) { int[] na=new int[newSize]; for(int i=offset;i<offset+size;i++) { na[i+diff]=arr[i]; } arr=na; offset+=diff; } } /* * * !!! all methods that use this method must be sync * enlarge the offset if 0 * / private void enlargeOffset() { if(offset==0) { offCount=offCount==0?1:offCount*2; offset=offCount; int[] narr=new int[arr.length+offset]; for(int i=0;i<size;i++) { narr[offset+i]=arr[i]; } arr=narr; } }*/ public int size() { return size; } public int[] keys() { ArrayList lst=new ArrayList(); int count=0; for(int i=offset;i<offset+size;i++) { int o=arr[i]; count++; if(o!=NULL) lst.add(Integer.valueOf(count)); } int[] ints=new int[lst.size()]; for(int i=0;i<ints.length;i++){ ints[i]=((Integer)lst.get(i)).intValue(); } return ints; } public int remove(int key) throws ExpressionException { if(key>size || key<1) throw invalidPosition(key); int obj=get(key,NULL); for(int i=(offset+key)-1;i<(offset+size)-1;i++) { arr[i]=arr[i+1]; } size--; return obj; } public int removeEL(int key) { if(key>size || key<1) return NULL; int obj=get(key,NULL); for(int i=(offset+key)-1;i<(offset+size)-1;i++) { arr[i]=arr[i+1]; } size--; return obj; } public void clear() { if(size()>0) { arr=new int[cap]; size=0; offCount=1; offset=0; } } public int add(int o) { if(offset+size+1>arr.length)enlargeCapacity(size+1); arr[offset+size]=o; size++; return o; } public int[] toArray() { int[] rtn=new int[size]; int count=0; for(int i=offset;i<offset+size;i++) { rtn[count++]=arr[i]; } return rtn; } public boolean contains(int key) { return get(key,NULL)!=NULL; } @Override public long sizeOf() { return SizeOf.size(arr) +SizeOf.size(cap) +SizeOf.size(size) +SizeOf.size(offset) +SizeOf.size(offCount) +SizeOf.REF_SIZE; } }