001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.type; 020 021import java.io.Serializable; 022import java.util.ArrayList; 023 024import lucee.commons.lang.SizeOf; 025import lucee.runtime.exp.ExpressionException; 026 027 028 029/** 030 * CFML array object 031 */ 032public final class ArrayInt implements Sizeable,Serializable { 033 034 private static final int NULL = 0; 035 private int[] arr; 036 private final int cap=32; 037 private int size=0; 038 private int offset=0; 039 private int offCount=0; 040 041 /** 042 * constructor with default dimesnion (1) 043 */ 044 public ArrayInt() { 045 arr=new int[offset+cap]; 046 } 047 048 /** 049 * constructor with to data to fill 050 * @param objects Objects array data to fill 051 */ 052 public ArrayInt(int[] objects) { 053 arr=objects; 054 size=arr.length; 055 offset=0; 056 } 057 058 public int get(int key, int defaultValue) { 059 if(key>size || key<1) { 060 return defaultValue; 061 } 062 int o=arr[(offset+key)-1]; 063 if(o==NULL) return defaultValue; 064 return o; 065 } 066 067 public int get(int key) throws ExpressionException { 068 if(key<1 || key>size) { 069 throw invalidPosition(key); 070 } 071 072 int o=arr[(offset+key)-1]; 073 074 if(o==NULL) { 075 throw invalidPosition(key); 076 } 077 return o; 078 } 079 080 /** 081 * Exception method if key doesn't exist at given position 082 * @param pos 083 * @return exception 084 */ 085 private ExpressionException invalidPosition(int pos) { 086 return new ExpressionException("Element at position ["+pos+"] doesn't exist in array"); 087 } 088 089 public int set(int key, int value) { 090 if(offset+key>arr.length)enlargeCapacity(key); 091 if(key>size)size=key; 092 return arr[(offset+key)-1]=value; 093 } 094 095 /** 096 * !!! all methods that use this method must be sync 097 * enlarge the inner array to given size 098 * @param key min size of the array 099 */ 100 private synchronized void enlargeCapacity(int key) { 101 int diff=offCount-offset; 102 103 int newSize=arr.length; 104 if(newSize<1) newSize=1; 105 while(newSize<key+offset+diff) { 106 newSize*=2; 107 } 108 if(newSize>arr.length) { 109 int[] na=new int[newSize]; 110 for(int i=offset;i<offset+size;i++) { 111 na[i+diff]=arr[i]; 112 } 113 arr=na; 114 offset+=diff; 115 } 116 } 117 118 /* * 119 * !!! all methods that use this method must be sync 120 * enlarge the offset if 0 121 * / 122 private void enlargeOffset() { 123 if(offset==0) { 124 offCount=offCount==0?1:offCount*2; 125 offset=offCount; 126 int[] narr=new int[arr.length+offset]; 127 for(int i=0;i<size;i++) { 128 narr[offset+i]=arr[i]; 129 } 130 arr=narr; 131 } 132 }*/ 133 134 public int size() { 135 return size; 136 } 137 138 public int[] keys() { 139 ArrayList lst=new ArrayList(); 140 int count=0; 141 for(int i=offset;i<offset+size;i++) { 142 int o=arr[i]; 143 count++; 144 if(o!=NULL) lst.add(Integer.valueOf(count)); 145 } 146 147 int[] ints=new int[lst.size()]; 148 149 for(int i=0;i<ints.length;i++){ 150 ints[i]=((Integer)lst.get(i)).intValue(); 151 } 152 return ints; 153 } 154 155 public int remove(int key) throws ExpressionException { 156 if(key>size || key<1) throw invalidPosition(key); 157 int obj=get(key,NULL); 158 for(int i=(offset+key)-1;i<(offset+size)-1;i++) { 159 arr[i]=arr[i+1]; 160 } 161 size--; 162 return obj; 163 } 164 165 public int removeEL(int key) { 166 if(key>size || key<1) return NULL; 167 int obj=get(key,NULL); 168 169 for(int i=(offset+key)-1;i<(offset+size)-1;i++) { 170 arr[i]=arr[i+1]; 171 } 172 size--; 173 return obj; 174 } 175 176 public void clear() { 177 if(size()>0) { 178 arr=new int[cap]; 179 size=0; 180 offCount=1; 181 offset=0; 182 } 183 } 184 185 public int add(int o) { 186 if(offset+size+1>arr.length)enlargeCapacity(size+1); 187 arr[offset+size]=o; 188 size++; 189 return o; 190 } 191 192 public int[] toArray() { 193 int[] rtn=new int[size]; 194 int count=0; 195 for(int i=offset;i<offset+size;i++) { 196 rtn[count++]=arr[i]; 197 } 198 return rtn; 199 } 200 201 public boolean contains(int key) { 202 return get(key,NULL)!=NULL; 203 } 204 205 @Override 206 public long sizeOf() { 207 return SizeOf.size(arr) 208 +SizeOf.size(cap) 209 +SizeOf.size(size) 210 +SizeOf.size(offset) 211 +SizeOf.size(offCount) 212 +SizeOf.REF_SIZE; 213 } 214 215}