1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 04:20:27 +01:00
Files
wmaker/WINGs/array.c
dan b2478b634f - the list multiple selection code is working now. it still needs some
minor work and cleanup.
- made some bag and array functions to return void instead of int.
- a few new array functions.
- better handling of mouse wheel.

!!! make clean after this update before you rebuild. some enums changed.
2000-10-01 23:26:03 +00:00

307 lines
6.0 KiB
C

/*
* Dynamically Resized Array
*
* Authors: Alfredo K. Kojima <kojima@windowmaker.org>
* Dan Pascu <dan@windowmaker.org>
*
* This code is released to the Public Domain, but
* proper credit is always appreciated :)
*/
#include <stdlib.h>
#include <string.h>
#include "WUtil.h"
#define INITIAL_SIZE 8
#define RESIZE_INCREMENT 8
typedef struct W_Array {
void **items; /* the array data */
int itemCount; /* # of items in array */
int allocSize; /* allocated size of array */
WMFreeDataProc *destructor; /* the destructor to free elements */
} W_Array;
WMArray*
WMCreateArray(int initialSize)
{
return WMCreateArrayWithDestructor(initialSize, NULL);
}
WMArray*
WMCreateArrayWithDestructor(int initialSize, WMFreeDataProc *destructor)
{
WMArray *array;
array = wmalloc(sizeof(WMArray));
if (initialSize <= 0) {
initialSize = INITIAL_SIZE;
}
array->items = wmalloc(sizeof(void*) * initialSize);
array->itemCount = 0;
array->allocSize = initialSize;
array->destructor = destructor;
return array;
}
WMArray*
WMCreateArrayWithArray(WMArray *array)
{
WMArray *newArray;
newArray = wmalloc(sizeof(WMArray));
newArray->items = wmalloc(sizeof(void*) * array->allocSize);
memcpy(newArray->items, array->items, sizeof(void*)*array->itemCount);
newArray->itemCount = array->itemCount;
newArray->allocSize = array->allocSize;
newArray->destructor = NULL;
return newArray;
}
void
WMEmptyArray(WMArray *array)
{
if (array->destructor) {
while (array->itemCount > 0) {
array->itemCount--;
array->destructor(array->items[array->itemCount]);
}
}
/*memset(array->items, 0, array->itemCount * sizeof(void*));*/
array->itemCount = 0;
}
void
WMFreeArray(WMArray *array)
{
WMEmptyArray(array);
free(array->items);
free(array);
}
int
WMGetArrayItemCount(WMArray *array)
{
return array->itemCount;
}
void
WMAppendArray(WMArray *array, WMArray *other)
{
if (other->itemCount == 0)
return;
if (array->itemCount + other->itemCount > array->allocSize) {
array->allocSize += other->allocSize;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
memcpy(array->items+array->itemCount, other->items,
sizeof(void*)*other->itemCount);
array->itemCount += other->itemCount;
}
void
WMAddToArray(WMArray *array, void *item)
{
if (array->itemCount >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
array->items[array->itemCount] = item;
array->itemCount++;
}
void
WMInsertInArray(WMArray *array, int index, void *item)
{
wassertr(index >= 0 && index <= array->itemCount);
if (array->itemCount >= array->allocSize) {
array->allocSize += RESIZE_INCREMENT;
array->items = wrealloc(array->items, sizeof(void*)*array->allocSize);
}
if (index < array->itemCount) {
memmove(array->items+index+1, array->items+index,
sizeof(void*)*(array->itemCount-index));
}
array->items[index] = item;
array->itemCount++;
}
void*
WMReplaceInArray(WMArray *array, int index, void *item)
{
void *old;
wassertrv(index >= 0 && index <= array->itemCount, NULL);
/* is it really useful to perform append if index == array->itemCount ? -Dan */
if (index == array->itemCount) {
WMAddToArray(array, item);
return NULL;
}
old = array->items[index];
array->items[index] = item;
return old;
}
int
WMDeleteFromArray(WMArray *array, int index)
{
wassertrv(index >= 0 && index < array->itemCount, 0);
if (array->destructor) {
array->destructor(array->items[index]);
}
if (index < array->itemCount-1) {
memmove(array->items+index, array->items+index+1,
sizeof(void*)*(array->itemCount-index-1));
}
array->itemCount--;
return 1;
}
int
WMRemoveFromArray(WMArray *array, void *item)
{
int i;
for (i = 0; i < array->itemCount; i++) {
if (array->items[i] == item) {
WMDeleteFromArray(array, i);
return 1;
}
}
return 0;
}
void*
WMGetFromArray(WMArray *array, int index)
{
if (index < 0 || index >= array->itemCount)
return NULL;
return array->items[index];
}
void*
WMPopFromArray(WMArray *array)
{
array->itemCount--;
return array->items[array->itemCount];
}
int
WMFindInArray(WMArray *array, WMMatchDataProc *match, void *cdata)
{
int i;
if (match!=NULL) {
for (i = 0; i < array->itemCount; i++) {
if ((*match)(array->items[i], cdata))
return i;
}
} else {
for (i = 0; i < array->itemCount; i++) {
if (array->items[i] == cdata)
return i;
}
}
return WANotFound;
}
int
WMCountInArray(WMArray *array, void *item)
{
int i, count;
for (i=0, count=0; i<array->itemCount; i++) {
if (array->items[i] == item)
count++;
}
return count;
}
void
WMSortArray(WMArray *array, WMCompareDataProc *comparer)
{
qsort(array->items, array->itemCount, sizeof(void*), comparer);
}
void
WMMapArray(WMArray *array, void (*function)(void*, void*), void *data)
{
int i;
for (i=0; i<array->itemCount; i++) {
(*function)(array->items[i], data);
}
}
WMArray*
WMGetSubarrayWithRange(WMArray* array, WMRange aRange)
{
WMArray *newArray;
if (aRange.count <= 0)
return WMCreateArray(0);
if (aRange.position < 0)
aRange.position = 0;
if (aRange.position >= array->itemCount)
aRange.position = array->itemCount - 1;
if (aRange.position + aRange.count > array->itemCount)
aRange.count = array->itemCount - aRange.position;
newArray = WMCreateArray(aRange.count);
memcpy(newArray->items, array->items+aRange.position,
sizeof(void*)*aRange.count);
newArray->itemCount = aRange.count;
return newArray;
}