160 lines
4.4 KiB
C
160 lines
4.4 KiB
C
|
/*
|
||
|
* Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||
|
*
|
||
|
* This code is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License version 2 only, as
|
||
|
* published by the Free Software Foundation. Sun designates this
|
||
|
* particular file as subject to the "Classpath" exception as provided
|
||
|
* by Sun in the LICENSE file that accompanied this code.
|
||
|
*
|
||
|
* This code 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 General Public License
|
||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||
|
* accompanied this code).
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License version
|
||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
*
|
||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||
|
* have any questions.
|
||
|
*/
|
||
|
|
||
|
/* General routines for manipulating a bag data structure */
|
||
|
|
||
|
#include "util.h"
|
||
|
#include "bag.h"
|
||
|
|
||
|
struct bag {
|
||
|
void *items; /* hold items in bag, must align on itemSize */
|
||
|
int used; /* number of items in bag */
|
||
|
int allocated; /* space reserved */
|
||
|
int itemSize; /* size of each item, should init to sizeof item */
|
||
|
};
|
||
|
|
||
|
struct bag *
|
||
|
bagCreateBag(int itemSize, int initialAllocation) {
|
||
|
struct bag *theBag = (struct bag *)jvmtiAllocate(sizeof(struct bag));
|
||
|
if (theBag == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
itemSize = (itemSize + 7) & ~7; /* fit 8 byte boundary */
|
||
|
theBag->items = jvmtiAllocate(initialAllocation * itemSize);
|
||
|
if (theBag->items == NULL) {
|
||
|
jvmtiDeallocate(theBag);
|
||
|
return NULL;
|
||
|
}
|
||
|
theBag->used = 0;
|
||
|
theBag->allocated = initialAllocation;
|
||
|
theBag->itemSize = itemSize;
|
||
|
return theBag;
|
||
|
}
|
||
|
|
||
|
struct bag *
|
||
|
bagDup(struct bag *oldBag)
|
||
|
{
|
||
|
struct bag *newBag = bagCreateBag(oldBag->itemSize,
|
||
|
oldBag->allocated);
|
||
|
if (newBag != NULL) {
|
||
|
newBag->used = oldBag->used;
|
||
|
(void)memcpy(newBag->items, oldBag->items, newBag->used * newBag->itemSize);
|
||
|
}
|
||
|
return newBag;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
bagDestroyBag(struct bag *theBag)
|
||
|
{
|
||
|
if (theBag != NULL) {
|
||
|
jvmtiDeallocate(theBag->items);
|
||
|
jvmtiDeallocate(theBag);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void *
|
||
|
bagFind(struct bag *theBag, void *key)
|
||
|
{
|
||
|
char *items = theBag->items;
|
||
|
int itemSize = theBag->itemSize;
|
||
|
char *itemsEnd = items + (itemSize * theBag->used);
|
||
|
|
||
|
for (; items < itemsEnd; items += itemSize) {
|
||
|
/*LINTED*/
|
||
|
if (*((void**)items) == key) {
|
||
|
return items;
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void *
|
||
|
bagAdd(struct bag *theBag)
|
||
|
{
|
||
|
int allocated = theBag->allocated;
|
||
|
int itemSize = theBag->itemSize;
|
||
|
void *items = theBag->items;
|
||
|
void *ret;
|
||
|
|
||
|
/* if there are no unused slots reallocate */
|
||
|
if (theBag->used >= allocated) {
|
||
|
void *new_items;
|
||
|
allocated *= 2;
|
||
|
new_items = jvmtiAllocate(allocated * itemSize);
|
||
|
if (new_items == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
(void)memcpy(new_items, items, (theBag->used) * itemSize);
|
||
|
jvmtiDeallocate(items);
|
||
|
items = new_items;
|
||
|
theBag->allocated = allocated;
|
||
|
theBag->items = items;
|
||
|
}
|
||
|
ret = ((char *)items) + (itemSize * (theBag->used)++);
|
||
|
(void)memset(ret, 0, itemSize);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
bagDelete(struct bag *theBag, void *condemned)
|
||
|
{
|
||
|
int used = --(theBag->used);
|
||
|
int itemSize = theBag->itemSize;
|
||
|
void *items = theBag->items;
|
||
|
void *tailItem = ((char *)items) + (used * itemSize);
|
||
|
|
||
|
if (condemned != tailItem) {
|
||
|
(void)memcpy(condemned, tailItem, itemSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
bagDeleteAll(struct bag *theBag)
|
||
|
{
|
||
|
theBag->used = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
bagSize(struct bag *theBag)
|
||
|
{
|
||
|
return theBag->used;
|
||
|
}
|
||
|
|
||
|
jboolean
|
||
|
bagEnumerateOver(struct bag *theBag, bagEnumerateFunction func, void *arg)
|
||
|
{
|
||
|
char *items = theBag->items;
|
||
|
int itemSize = theBag->itemSize;
|
||
|
char *itemsEnd = items + (itemSize * theBag->used);
|
||
|
|
||
|
for (; items < itemsEnd; items += itemSize) {
|
||
|
if (!(func)((void *)items, arg)) {
|
||
|
return JNI_FALSE;
|
||
|
}
|
||
|
}
|
||
|
return JNI_TRUE;
|
||
|
}
|