1 /*        $NetBSD: mvect.c,v 1.4 2025/02/25 19:15:52 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