Browse Source

[core] add generic vector implementation

From: Stefan Bühler <stbuehler@web.de>

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3115 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/heads/lighttpd-1.4.x
Stefan Bühler 6 years ago
parent
commit
8455734f4a
  1. 1
      NEWS
  2. 1
      src/CMakeLists.txt
  3. 3
      src/Makefile.am
  4. 1
      src/SConscript
  5. 17
      src/vector.c
  6. 75
      src/vector.h

1
NEWS

@ -42,6 +42,7 @@ NEWS
* [core] fix request_start in keep-alive requests to mark time when received first byte (fixes #2412)
* [core] truncate pidfile on exit (fixes #2695)
* consistent inclusion of config.h at top of files (fixes #2073)
* [core] add generic vector implementation
- 1.4.39 - 2016-01-02
* [core] fix memset_s call (fixes #2698)

1
src/CMakeLists.txt

@ -482,6 +482,7 @@ set(COMMON_SRC
stat_cache.c plugin.c joblist.c etag.c array.c
data_string.c data_count.c data_array.c
data_integer.c md5.c data_fastcgi.c
vector.c
fdevent_select.c fdevent_libev.c
fdevent_poll.c fdevent_linux_sysepoll.c
fdevent_solaris_devpoll.c fdevent_solaris_port.c

3
src/Makefile.am

@ -62,6 +62,7 @@ common_src=base64.c buffer.c log.c \
stat_cache.c plugin.c joblist.c etag.c array.c \
data_string.c data_count.c data_array.c \
data_integer.c md5.c data_fastcgi.c \
vector.c \
fdevent_select.c fdevent_libev.c \
fdevent_poll.c fdevent_linux_sysepoll.c \
fdevent_solaris_devpoll.c fdevent_solaris_port.c \
@ -274,7 +275,7 @@ hdr = server.h base64.h buffer.h network.h log.h keyvalue.h \
md5.h http_auth.h stream.h \
fdevent.h connections.h base.h stat_cache.h \
plugin.h mod_auth.h \
etag.h joblist.h array.h crc32.h \
etag.h joblist.h array.h vector.h crc32.h \
network_backends.h configfile.h \
mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \
configparser.h mod_ssi_exprparser.h \

1
src/SConscript

@ -44,6 +44,7 @@ common_src = Split("base64.c buffer.c log.c \
stat_cache.c plugin.c joblist.c etag.c array.c \
data_string.c data_count.c data_array.c \
data_integer.c md5.c data_fastcgi.c \
vector.c \
fdevent_select.c fdevent_libev.c \
fdevent_poll.c fdevent_linux_sysepoll.c \
fdevent_solaris_devpoll.c fdevent_solaris_port.c \

17
src/vector.c

@ -0,0 +1,17 @@
#include "first.h"
#include "vector.h"
#include "base.h"
void *vector_realloc(void *data, size_t elem_size, size_t size, size_t used) {
const size_t total_size = elem_size * size;
const size_t used_size = elem_size * used;
force_assert(size <= SIZE_MAX / elem_size);
data = realloc(data, total_size);
force_assert(NULL != data);
/* clear new memory */
memset(((char*)data) + used_size, 0, total_size - used_size);
return data;
}

75
src/vector.h

@ -0,0 +1,75 @@
#ifndef LI_VECTOR_H
#define LI_VECTOR_H
#include "first.h"
#ifndef SIZE_MAX
# ifdef SIZE_T_MAX
# define SIZE_MAX SIZE_T_MAX
# else
# define SIZE_MAX ((size_t)~0)
# endif
#endif
#include <stdlib.h>
#include <string.h>
static inline size_t vector_align_size(size_t s) {
size_t a = (s + 16) & ((size_t)~15);
return (a < s) ? s : a;
}
void *vector_realloc(void *data, size_t elem_size, size_t size, size_t used);
#define DEFINE_TYPED_VECTOR(name, entry, release) \
typedef struct vector_ ## name { \
entry* data; \
size_t used; \
size_t size; \
} vector_ ## name; \
static inline void vector_ ## name ## _init(vector_ ## name *v) { \
v->data = NULL; \
v->used = v->size = 0; \
} \
static inline vector_ ## name *vector_ ## name ## _alloc() { \
vector_ ## name *v = malloc(sizeof(*v)); \
force_assert(NULL != v); \
vector_ ## name ## _init(v); \
return v; \
} \
static inline void vector_ ## name ## _clear(vector_ ## name *v) { \
size_t ndx; \
vector_ ## name vcopy = *v; \
vector_ ## name ## _init(v); \
if (release) for (ndx = 0; ndx < vcopy.used; ++ndx) release(vcopy.data[ndx]); \
free(vcopy.data); \
} \
static inline void vector_ ## name ## _free(vector_ ## name *v) { \
if (NULL != v) { \
vector_ ## name ## _clear(v); \
free(v); \
} \
} \
static inline void vector_ ## name ## _reserve(vector_ ## name *v, size_t p) { \
force_assert(v->used < SIZE_MAX - p); \
if (v->size < v->used + p) { \
v->size = vector_align_size(v->used + p); \
v->data = vector_realloc(v->data, sizeof(entry), v->size, v->used); \
} \
} \
static inline void vector_ ## name ## _push(vector_ ## name *v, entry e) { \
vector_ ## name ## _reserve(v, 1); \
v->data[v->used++] = e; \
} \
static inline entry vector_ ## name ## _pop(vector_ ## name *v) { \
force_assert(v->used > 0); \
return v->data[--v->used]; \
} \
struct vector_ ## name /* expect trailing semicolon */ \
/* end of DEFINE_TYPED_VECTOR */
#define DEFINE_TYPED_VECTOR_NO_RELEASE(name, entry) \
DEFINE_TYPED_VECTOR(name, entry, ((void(*)(entry)) NULL)) \
/* end of DEFINE_TYPED_VECTOR_NO_RELEASE */
#endif
Loading…
Cancel
Save