package se.krka.kahlua.vm; import se.krka.kahlua.stdlib.BaseLib; public class LuaArray implements LuaTable { private LuaTable metatable; private Object[] data; private int len; private boolean recalculateLen; public LuaArray() { data = new Object[16]; len = 0; } public int len() { if (recalculateLen) { int index = this.len - 1; Object[] data = this.data; while (index >= 0) { if (data[index] != null) { break; } index--; } this.len = index + 1; recalculateLen = false; } return len; } public Object rawget(int index) { if (index < 1 || index > len) { return null; } return data[(index - 1)]; } public void rawset(int index, Object value) { if (index <= 0) { BaseLib.fail("Index out of range: " + index); } if (index >= len) { if (value == null) { if (index == len) { data[index - 1] = value; recalculateLen = true; } return; } if (data.length < index) { int newMaxLen = 2 * index; int newCap = newMaxLen - 1; Object[] newData = new Object[newCap]; System.arraycopy(data, 0, newData, 0, len); data = newData; } len = index; } data[(index - 1)] = value; } private int getKeyIndex(Object key) { if (key instanceof Double) { Double d = (Double) key; return d.intValue(); } return -1; } public Object rawget(Object key) { LuaTableImpl.checkKey(key); int index = getKeyIndex(key); return rawget(index); } public void rawset(Object key, Object value) { LuaTableImpl.checkKey(key); int index = getKeyIndex(key); if (index == -1) { BaseLib.fail("Invalid table key: " + key); } rawset(index, value); } public Object next(Object key) { int index; if (key == null) { index = 0; } else { index = getKeyIndex(key); if (index <= 0 || index > len) { BaseLib.fail("invalid key to 'next'"); return null; } } while (index < len) { if (data[index] != null) { return LuaState.toDouble(index + 1); } index++; } return null; } public LuaTable getMetatable() { return metatable; } public void setMetatable(LuaTable metatable) { this.metatable = metatable; } public void updateWeakSettings(boolean weakKeys, boolean weakValues) { BaseLib.fail("Can't set weakness on arrays"); } }