diff --git a/configure.ac b/configure.ac index 45dac5a..7d6a738 100644 --- a/configure.ac +++ b/configure.ac @@ -64,5 +64,6 @@ AC_CONFIG_FILES([Makefile src/hash/Makefile src/queue/Makefile src/tree/Makefile + src/dynarray/Makefile include/Makefile]) AC_OUTPUT diff --git a/include/Makefile.am b/include/Makefile.am index a28d27f..77bec2d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -4,4 +4,5 @@ nobase_include_HEADERS = trdata.h \ tr/hash_value.h \ tr/queue.h \ tr/tree.h \ + tr/dynarray.h \ tr/interface/hashable.h diff --git a/include/tr/dynarray.h b/include/tr/dynarray.h new file mode 100644 index 0000000..094c493 --- /dev/null +++ b/include/tr/dynarray.h @@ -0,0 +1,44 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TR_DYNARRAY_H__ +#define __TR_DYNARRAY_H__ + +#include + +#include "trbase.h" + +TR_CLASS(TR_Dynarray) { + size_t size; + const void ** data; +}; +TR_INSTANCE_INIT(TR_Dynarray); +TR_CLASSVARS_DECL(TR_Dynarray) {}; + +size_t TR_darrPut(TR_Dynarray, const void *); +void TR_darrPutAt(TR_Dynarray, const void *, size_t); + +#define TR_darrGet(this, idx) ((this)->data[(idx)]) + +#endif // __TR_DYNARRAY_H__ + +// vim: set ts=4 sw=4: diff --git a/include/trdata.h b/include/trdata.h index 05d5ab0..ff10164 100644 --- a/include/trdata.h +++ b/include/trdata.h @@ -6,6 +6,7 @@ #include "tr/hash_value.h" #include "tr/queue.h" #include "tr/tree.h" +#include "tr/dynarray.h" #include "tr/interface/hashable.h" #endif // __TR_DATA_H__ diff --git a/src/Makefile.am b/src/Makefile.am index bee8a22..5440ac8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,8 @@ AM_LDFLAGS += -lpthread TRDATALIBS = cbuf/libcbuf.la \ hash/libhash.la \ queue/libqueue.la \ - tree/libtree.la + tree/libtree.la \ + dynarray/libdynarray.la lib_LTLIBRARIES = libtrdata.la @@ -16,4 +17,4 @@ libtrdata_la_CFLAGS = $(AM_CFLAGS) libtrdata_la_LIBADD = $(TRDATALIBS) libtrdata_la_LDFLAGS = -version-info 0:0:0 $(AM_LDFLAGS) -SUBDIRS = cbuf hash queue tree +SUBDIRS = cbuf hash queue tree dynarray diff --git a/src/dynarray/Makefile.am b/src/dynarray/Makefile.am new file mode 100644 index 0000000..f094ba7 --- /dev/null +++ b/src/dynarray/Makefile.am @@ -0,0 +1,13 @@ +ACLOCAL_AMFLAGS = -I m4 +AUTOMAKE_OPTIONS = subdir-objects + +AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread +AM_LDFLAGS += -lpthread + +DYNARRAY = dynarray.c put.c + +noinst_LTLIBRARIES = libdynarray.la + +libdynarray_la_SOURCES = $(DYNARRAY) +libdynarray_la_CFLAGS = $(AM_CFLAGS) +libdynarray_la_LIBADD = $(AM_LDFLAGS) diff --git a/src/dynarray/dynarray.c b/src/dynarray/dynarray.c new file mode 100644 index 0000000..dca554a --- /dev/null +++ b/src/dynarray/dynarray.c @@ -0,0 +1,59 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "trbase.h" +#include "tr/dynarray.h" + +static +inline +void +_darrResize(TR_Dynarray this, size_t index) +{ + if (index > (long)this->size - 1) { + void * new_data = TR_calloc(index + 1, sizeof(void *)); + memcpy(new_data, this->data, this->size * sizeof(void *)); + TR_MEM_FREE(this->data); + this->data = (const void **)new_data; + this->size = TR_getUsableSize(new_data) / sizeof(void *); + } +} + +static +int +darrCtor(void * _this) +{ + return 0; +} + +static +void +darrDtor(void * _this) +{ + TR_MEM_FREE(((TR_Dynarray)_this)->data); +} + +TR_INIT_IFACE(TR_Class, darrCtor, darrDtor, NULL); +TR_CREATE_CLASS(TR_Dynarray, NULL, NULL, TR_IF(TR_Class)); + +// vim: set ts=4 sw=4: diff --git a/src/dynarray/put.c b/src/dynarray/put.c new file mode 100644 index 0000000..e5d9355 --- /dev/null +++ b/src/dynarray/put.c @@ -0,0 +1,60 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "trbase.h" +#include "tr/dynarray.h" + +static +inline +void +_darrResize(TR_Dynarray this, size_t index) +{ + if (!this->size || index > this->size - 1) { + void * new_data = TR_calloc(index + 1, sizeof(void *)); + memcpy(new_data, this->data, this->size * sizeof(void *)); + TR_MEM_FREE(this->data); + this->data = (const void **)new_data; + this->size = TR_getUsableSize(new_data) / sizeof(void *); + } +} + +size_t +TR_darrPut(TR_Dynarray this, const void * data) +{ + size_t i = this->size; + + while (this->data && ! this->data[--i]); + TR_darrPutAt(this, data, this->data && this->data[i] ? i+1 : i); + + return i; +} + +void +TR_darrPutAt(TR_Dynarray this, const void * data, size_t idx) +{ + _darrResize(this, idx); + this->data[idx] = data; +} + +// vim: set ts=4 sw=4: