s4:heimdal: import lorikeet-heimdal-202201172009 (commit 5a0b45cd723628b3690ea848548b...
[samba.git] / source4 / heimdal / lib / roken / strpool.c
1 /*
2  * Copyright (c) 2005 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include <config.h>
35
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include "roken.h"
39
40 struct rk_strpool {
41     char *str;
42     size_t len; /* strlen() of str */
43     size_t sz;  /* Allocated size */
44 };
45
46 /*
47  *
48  */
49
50 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
51 rk_strpoolfree(struct rk_strpool *p)
52 {
53     if (p && p->str) {
54         free(p->str);
55         p->str = NULL;
56     }
57     free(p);
58 }
59
60 /*
61  *
62  */
63
64 ROKEN_LIB_FUNCTION struct rk_strpool * ROKEN_LIB_CALL
65 rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...)
66 {
67     va_list ap;
68     char *str;
69     int len;
70
71     va_start(ap, fmt);
72     len = vasprintf(&str, fmt, ap);
73     va_end(ap);
74     if (str == NULL)
75         return rk_strpoolfree(p), NULL;
76
77     if (p == NULL) {
78         if ((p = malloc(sizeof(*p))) == NULL)
79             return free(str), NULL;
80         p->str = str;
81         p->len = p->sz = len;
82         return p;
83     } /* else grow the buffer and append `str', but don't grow too fast */
84
85     if (len + p->len + 1 > p->sz) {
86         size_t sz = p->len + len + 9 + (p->sz >> 2);
87         char *str2;
88
89         if ((str2 = realloc(p->str, sz)) == NULL)
90             return rk_strpoolfree(p), NULL;
91         p->str = str2;
92         p->sz = sz;
93     }
94     memcpy(p->str + p->len, str, len + 1);
95     p->len += len;
96     free(str);
97     return p;
98 }
99
100 /*
101  *
102  */
103
104 ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL
105 rk_strpoolcollect(struct rk_strpool *p)
106 {
107     char *str;
108     if (p == NULL)
109         return strdup("");
110     str = p->str;
111     p->str = NULL;
112     free(p);
113     return str;
114 }