// -*- c++ -*- /* * Jakelib2 - General purpose C++ library * Copyright (C) 2001 Florian Wolff (florian@donuz.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: Vector.jlc,v 1.6 2003/09/27 08:10:29 florian Exp $ */ #include "jakelib2.h" #include "jakelib2/lang/System.h" #include "jakelib2/util/Vector.h" #include "jakelib2/lang/Synchronizer.h" #include using namespace jakelib::lang; using namespace jakelib::util; JAKELIB_IMPLEMENT_CLASS("jakelib.util.Vector", Vector, Object) #ifndef WINOWS32 # include # include #endif /*****************************************************************************\ * Vector | *****************************************************************************/ Vector::Vector() { init(10, 0); } Vector::Vector(int initialCapacity) { init(initialCapacity, 0); } Vector::Vector(int initialCapacity, int capacityIncrement) { init(initialCapacity, capacityIncrement); } Vector::~Vector() { GC_FREE(elementData); } /*****************************************************************************\ * init | *****************************************************************************/ void Vector::init(int initialCapacity, int capacityIncrement) { if (initialCapacity < 0) throw new IllegalArgumentException(`"Illegal capacity: "` .. initialCapacity .. JAKELIB_AT2("jakelib.util.Vector.init")); if (capacityIncrement < 0) throw new IllegalArgumentException(`"Illegal increment: "` .. capacityIncrement .. JAKELIB_AT2("jakelib.util.Vector.init")); this->capacityIncrement = capacityIncrement; elementData = (Object**) GC_MALLOC(initialCapacity * sizeof(Object*)); elementCount = 0; capacity = initialCapacity; } /*****************************************************************************\ * addElement | *****************************************************************************/ int Vector::addElement(Object* object) { int newIndex; JAKELIB_SYNCHRONIZED(this); ensureCapacity(elementCount + 1); elementData[elementCount++] = object; newIndex = elementCount - 1; return newIndex; } /*****************************************************************************\ * ensureCapacity | *****************************************************************************/ void Vector::ensureCapacity(int minCapacity) { if (minCapacity > capacity) { int newCapacity = (capacityIncrement > 0) ? (capacity + capacityIncrement) : (capacity * 2); if (newCapacity < minCapacity) newCapacity = minCapacity; Object** newElementData = (Object**) GC_REALLOC(elementData, sizeof(Object*) * newCapacity); if (newElementData == null) throw new MemoryException(`"Allocating "` .. (jlong) (sizeof(Object*) * newCapacity) .. `" bytes of memory"` .. JAKELIB_AT2("jakelib.util.Vector.ensureCapacity")); elementData = newElementData; capacity = newCapacity; } } /*****************************************************************************\ * elementAt | *****************************************************************************/ Object* Vector::elementAt(int index) { JAKELIB_SYNCHRONIZED(this); if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(`""` .. index .. `" >= "` .. elementCount .. JAKELIB_AT2("jakelib.util.Vector.elementAt")); } if (index < 0) { throw new IllegalArgumentException(`""` .. index .. `" < 0"` .. JAKELIB_AT2("jakelib.util.Vector.elementAt")); } return elementData[index]; } /*****************************************************************************\ * size | *****************************************************************************/ int Vector::size() { return elementCount; } /*****************************************************************************\ * set | *****************************************************************************/ void Vector::set(int index, Object* object) { JAKELIB_SYNCHRONIZED(this); if (index < 0) { throw new IllegalArgumentException(`""` .. index .. `" < 0"` .. JAKELIB_AT2("jakelib.util.Vector.set")); } ensureCapacity(index +1); elementData[index] = object; } /*****************************************************************************\ * clear | *****************************************************************************/ void Vector::clear() { JAKELIB_SYNCHRONIZED(this); elementCount = 0; } /*****************************************************************************\ * indexOf | *****************************************************************************/ int Vector::indexOf(Object* object) { JAKELIB_SYNCHRONIZED(this); for (int idx = 0; idx < elementCount; idx++) if (elementData[idx] == object) { return idx; } return -1; } /*****************************************************************************\ * contains | *****************************************************************************/ jboolean Vector::contains(Object* object) { return (indexOf(object) != -1); } /*****************************************************************************\ * removeLastElement | *****************************************************************************/ void Vector::removeLastElement() { JAKELIB_SYNCHRONIZED(this); if (elementCount == 0) { return; } elementCount --; elementData[elementCount] = null; } /*****************************************************************************\ * removeElement | *****************************************************************************/ jboolean Vector::removeElement(Object* object) { int i = indexOf(object); if (i >= 0) { removeElementAt(i); return true; } return false; } /*****************************************************************************\ * removeElementAt | *****************************************************************************/ void Vector::removeElementAt(int index) { JAKELIB_SYNCHRONIZED(this); if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(`""` .. index .. `" >= "` .. elementCount .. JAKELIB_AT2("jakelib.util.Vector.removeElementAt")); } else if (index < 0) { throw new ArrayIndexOutOfBoundsException(`""` .. index .. `" < 0"` .. JAKELIB_AT2("jakelib.util.Vector.removeElementAt")); } int j = elementCount - index - 1; if (j > 0) { for (int idx = index; idx < elementCount - 1; idx++) elementData[idx] = elementData[idx + 1]; } elementCount--; } /*****************************************************************************\ * isEmpty | *****************************************************************************/ jboolean Vector::isEmpty() { return (size() == 0); } /*****************************************************************************\ * toString | *****************************************************************************/ String* Vector::toString() { JAKELIB_SYNCHRONIZED(this); StringBuffer buf("["); for (int idx = 0; idx < elementCount; idx++) { if (elementData[idx] == null) buf.append("null"); else buf.append(elementData[idx]->toString()); if (idx < elementCount -1) buf.append(", "); } buf.append("]"); return buf.toString(); } /*****************************************************************************\ * copyInto | *****************************************************************************/ void Vector::copyInto(Array* a) { if (a == null) throw new NullPointerException(JAKELIB_AT2("jakelib.util.Vector.copyInto")); setSize(a->length()); if (a->length() > elementCount) { throw new ArrayIndexOutOfBoundsException(`""` .. a->length() .. `" >= "` .. elementCount .. JAKELIB_AT2("jakelib.util.Vector.copyInto")); } memmove(elementData, a->getArray(), a->length() * sizeof(Object*)); } /*****************************************************************************\ * setSize | *****************************************************************************/ void Vector::setSize(jint newSize) { ensureCapacity(newSize); elementCount = newSize; } /*****************************************************************************\ * setElementAt | *****************************************************************************/ void Vector::setElementAt(Object* obj, jint index) { set(index, obj); }