1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/* Copyright (c) 2002-2003 krzYszcz and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* LATER generic handling of reentrant output request and self-invoked set */
#include <string.h>
#include "m_pd.h"
#include "grow.h"
/* Prior to this call a caller is supposed to check for *nrequested > *sizep.
Returns a reallocated buffer's pointer (success) or a given 'bufini'
default value (failure).
Upon return *nrequested contains the actual number of elements:
requested (success) or a given default value of 'inisize' (failure). */
void *grow_nodata(int *nrequested, int *sizep, void *bufp,
int inisize, void *bufini, size_t typesize)
{
int newsize = *sizep * 2;
while (newsize < *nrequested) newsize *= 2;
if (bufp == bufini)
bufp = getbytes(newsize * typesize);
else
bufp = resizebytes(bufp, *sizep * typesize, newsize * typesize);
if (bufp)
{
*sizep = newsize;
return (bufp);
}
else
{
*nrequested = *sizep = inisize;
return (bufini);
}
}
/* Like grow_nodata(), but preserving first *nexisting elements. */
void *grow_withdata(int *nrequested, int *nexisting,
int *sizep, void *bufp,
int inisize, void *bufini, size_t typesize)
{
int newsize = *sizep * 2;
while (newsize < *nrequested) newsize *= 2;
if (bufp == bufini)
{
if (!(bufp = getbytes(newsize * typesize)))
{
*nrequested = *sizep = inisize;
return (bufini);
}
*sizep = newsize;
memcpy(bufp, bufini, *nexisting * typesize);
}
else
{
int oldsize = *sizep;
if (!(bufp = resizebytes(bufp, *sizep * typesize, newsize * typesize)))
{
*nrequested = *sizep = inisize;
*nexisting = 0;
return (bufini);
}
*sizep = newsize;
}
return (bufp);
}
/* Like grow_nodata(), but preserving a 'tail' of *nexisting elements,
starting from *startp. */
/* LATER rethink handling of a start pointer (clumsy now) */
void *grow_withtail(int *nrequested, int *nexisting, char **startp,
int *sizep, void *bufp,
int inisize, void *bufini, size_t typesize)
{
int newsize = *sizep * 2;
while (newsize < *nrequested) newsize *= 2;
if (bufp == bufini)
{
char *oldstart = *startp;
if (!(bufp = getbytes(newsize * typesize)))
{
*nrequested = *sizep = inisize;
return (bufini);
}
*startp = (char *)bufp + (newsize - *nexisting) * typesize;
*sizep = newsize;
memcpy(*startp, oldstart, *nexisting * typesize);
}
else
{
int oldsize = *sizep;
if (!(bufp = resizebytes(bufp, *sizep * typesize, newsize * typesize)))
{
*startp = (char *)bufini + inisize * typesize;
*nrequested = *sizep = inisize;
*nexisting = 0;
return (bufini);
}
*startp = (char *)bufp + (newsize - *nexisting) * typesize;
*sizep = newsize;
memmove(*startp, (char *)bufp + (oldsize - *nexisting) * typesize,
*nexisting * typesize);
}
return (bufp);
}
|