xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/mvect.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1 /*	$NetBSD: mvect.c,v 1.3 2020/03/18 19:05:21 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	mvect 3
6 /* SUMMARY
7 /*	memory vector management
8 /* SYNOPSIS
9 /*	#include <mvect.h>
10 /*
11 /*	char	*mvect_alloc(vector, elsize, nelm, init_fn, wipe_fn)
12 /*	MVECT	*vector;
13 /*	ssize_t	elsize;
14 /*	ssize_t	nelm;
15 /*	void	(*init_fn)(char *ptr, ssize_t count);
16 /*	void	(*wipe_fn)(char *ptr, ssize_t count);
17 /*
18 /*	char	*mvect_realloc(vector, nelm)
19 /*	MVECT	*vector;
20 /*	ssize_t	nelm;
21 /*
22 /*	char	*mvect_free(vector)
23 /*	MVECT	*vector;
24 /* DESCRIPTION
25 /*	This module supports memory management for arrays of arbitrary
26 /*	objects.  It is up to the application to provide specific code
27 /*	that initializes and uses object memory.
28 /*
29 /*	mvect_alloc() initializes memory for a vector with elements
30 /*	of \fIelsize\fR bytes, and with at least \fInelm\fR elements.
31 /*	\fIinit_fn\fR is a null pointer, or a pointer to a function
32 /*	that initializes \fIcount\fR vector elements.
33 /*	\fIwipe_fn\fR is a null pointer, or a pointer to a function
34 /*	that is complementary to \fIinit_fn\fR. This routine is called
35 /*	by mvect_free(). The result of mvect_alloc() is a pointer to
36 /*	the allocated vector.
37 /*
38 /*	mvect_realloc() guarantees that the specified vector has space
39 /*	for at least \fInelm\fR elements. The result is a pointer to the
40 /*	allocated vector, which may change across calls.
41 /*
42 /*	mvect_free() releases storage for the named vector. The result
43 /*	is a convenient null pointer.
44 /* SEE ALSO
45 /*	mymalloc(3) memory management
46 /* DIAGNOSTICS
47 /*	Problems are reported via the msg(3) diagnostics routines:
48 /*	the requested amount of memory is not available; improper use
49 /*	is detected; other fatal errors.
50 /* LICENSE
51 /* .ad
52 /* .fi
53 /*	The Secure Mailer license must be distributed with this software.
54 /* AUTHOR(S)
55 /*	Wietse Venema
56 /*	IBM T.J. Watson Research
57 /*	P.O. Box 704
58 /*	Yorktown Heights, NY 10598, USA
59 /*
60 /*	Wietse Venema
61 /*	Google, Inc.
62 /*	111 8th Avenue
63 /*	New York, NY 10011, USA
64 /*--*/
65 
66 /* System library. */
67 
68 #include <sys_defs.h>
69 
70 /* Utility library. */
71 
72 #include "mymalloc.h"
73 #include "mvect.h"
74 
75 /* mvect_alloc - allocate memory vector */
76 
mvect_alloc(MVECT * vect,ssize_t elsize,ssize_t nelm,void (* init_fn)(char *,ssize_t),void (* wipe_fn)(char *,ssize_t))77 char   *mvect_alloc(MVECT *vect, ssize_t elsize, ssize_t nelm,
78                void (*init_fn) (char *, ssize_t), void (*wipe_fn) (char *, ssize_t))
79 {
80     vect->init_fn = init_fn;
81     vect->wipe_fn = wipe_fn;
82     vect->nelm = 0;
83     vect->ptr = mymalloc(elsize * nelm);
84     vect->nelm = nelm;
85     vect->elsize = elsize;
86     if (vect->init_fn)
87 	vect->init_fn(vect->ptr, vect->nelm);
88     return (vect->ptr);
89 }
90 
91 /* mvect_realloc - adjust memory vector allocation */
92 
mvect_realloc(MVECT * vect,ssize_t nelm)93 char   *mvect_realloc(MVECT *vect, ssize_t nelm)
94 {
95     ssize_t old_len = vect->nelm;
96     ssize_t incr = nelm - old_len;
97     ssize_t new_nelm;
98 
99     if (incr > 0) {
100 	if (incr < old_len)
101 	    incr = old_len;
102 	new_nelm = vect->nelm + incr;
103 	vect->ptr = myrealloc(vect->ptr, vect->elsize * new_nelm);
104 	vect->nelm = new_nelm;
105 	if (vect->init_fn)
106 	    vect->init_fn(vect->ptr + old_len * vect->elsize, incr);
107     }
108     return (vect->ptr);
109 }
110 
111 /* mvect_free - release memory vector storage */
112 
mvect_free(MVECT * vect)113 char   *mvect_free(MVECT *vect)
114 {
115     if (vect->wipe_fn)
116 	vect->wipe_fn(vect->ptr, vect->nelm);
117     myfree(vect->ptr);
118     return (0);
119 }
120