001 package railo.runtime.type; 002 003 import java.io.Serializable; 004 import java.util.ArrayList; 005 006 import railo.commons.lang.SizeOf; 007 import railo.runtime.exp.ExpressionException; 008 009 010 011 /** 012 * CFML array object 013 */ 014 public final class ArrayInt implements Sizeable,Serializable { 015 016 private static final int NULL = 0; 017 private int[] arr; 018 private final int cap=32; 019 private int size=0; 020 private int offset=0; 021 private int offCount=0; 022 023 /** 024 * constructor with default dimesnion (1) 025 */ 026 public ArrayInt() { 027 arr=new int[offset+cap]; 028 } 029 030 /** 031 * constructor with to data to fill 032 * @param objects Objects array data to fill 033 */ 034 public ArrayInt(int[] objects) { 035 arr=objects; 036 size=arr.length; 037 offset=0; 038 } 039 040 public int get(int key, int defaultValue) { 041 if(key>size || key<1) { 042 return defaultValue; 043 } 044 int o=arr[(offset+key)-1]; 045 if(o==NULL) return defaultValue; 046 return o; 047 } 048 049 public int get(int key) throws ExpressionException { 050 if(key<1 || key>size) { 051 throw invalidPosition(key); 052 } 053 054 int o=arr[(offset+key)-1]; 055 056 if(o==NULL) { 057 throw invalidPosition(key); 058 } 059 return o; 060 } 061 062 /** 063 * Exception method if key doesn't exist at given position 064 * @param pos 065 * @return exception 066 */ 067 private ExpressionException invalidPosition(int pos) { 068 return new ExpressionException("Element at position ["+pos+"] doesn't exist in array"); 069 } 070 071 public int set(int key, int value) { 072 if(offset+key>arr.length)enlargeCapacity(key); 073 if(key>size)size=key; 074 return arr[(offset+key)-1]=value; 075 } 076 077 /** 078 * !!! all methods that use this method must be sync 079 * enlarge the inner array to given size 080 * @param key min size of the array 081 */ 082 private synchronized void enlargeCapacity(int key) { 083 int diff=offCount-offset; 084 085 int newSize=arr.length; 086 if(newSize<1) newSize=1; 087 while(newSize<key+offset+diff) { 088 newSize*=2; 089 } 090 if(newSize>arr.length) { 091 int[] na=new int[newSize]; 092 for(int i=offset;i<offset+size;i++) { 093 na[i+diff]=arr[i]; 094 } 095 arr=na; 096 offset+=diff; 097 } 098 } 099 100 /* * 101 * !!! all methods that use this method must be sync 102 * enlarge the offset if 0 103 * / 104 private void enlargeOffset() { 105 if(offset==0) { 106 offCount=offCount==0?1:offCount*2; 107 offset=offCount; 108 int[] narr=new int[arr.length+offset]; 109 for(int i=0;i<size;i++) { 110 narr[offset+i]=arr[i]; 111 } 112 arr=narr; 113 } 114 }*/ 115 116 public int size() { 117 return size; 118 } 119 120 public int[] keys() { 121 ArrayList lst=new ArrayList(); 122 int count=0; 123 for(int i=offset;i<offset+size;i++) { 124 int o=arr[i]; 125 count++; 126 if(o!=NULL) lst.add(Integer.valueOf(count)); 127 } 128 129 int[] ints=new int[lst.size()]; 130 131 for(int i=0;i<ints.length;i++){ 132 ints[i]=((Integer)lst.get(i)).intValue(); 133 } 134 return ints; 135 } 136 137 public int remove(int key) throws ExpressionException { 138 if(key>size || key<1) throw invalidPosition(key); 139 int obj=get(key,NULL); 140 for(int i=(offset+key)-1;i<(offset+size)-1;i++) { 141 arr[i]=arr[i+1]; 142 } 143 size--; 144 return obj; 145 } 146 147 public int removeEL(int key) { 148 if(key>size || key<1) return NULL; 149 int obj=get(key,NULL); 150 151 for(int i=(offset+key)-1;i<(offset+size)-1;i++) { 152 arr[i]=arr[i+1]; 153 } 154 size--; 155 return obj; 156 } 157 158 public void clear() { 159 if(size()>0) { 160 arr=new int[cap]; 161 size=0; 162 offCount=1; 163 offset=0; 164 } 165 } 166 167 public int add(int o) { 168 if(offset+size+1>arr.length)enlargeCapacity(size+1); 169 arr[offset+size]=o; 170 size++; 171 return o; 172 } 173 174 public int[] toArray() { 175 int[] rtn=new int[size]; 176 int count=0; 177 for(int i=offset;i<offset+size;i++) { 178 rtn[count++]=arr[i]; 179 } 180 return rtn; 181 } 182 183 public boolean contains(int key) { 184 return get(key,NULL)!=NULL; 185 } 186 187 @Override 188 public long sizeOf() { 189 return SizeOf.size(arr) 190 +SizeOf.size(cap) 191 +SizeOf.size(size) 192 +SizeOf.size(offset) 193 +SizeOf.size(offCount) 194 +SizeOf.REF_SIZE; 195 } 196 197 }