xref: /titanic_41/usr/src/lib/libcmdutils/common/custr.c (revision 61d1e6c58253de1520313067e756b41e17a077cb)
1*61d1e6c5SJoshua M. Clulow /*
2*61d1e6c5SJoshua M. Clulow  * This file and its contents are supplied under the terms of the
3*61d1e6c5SJoshua M. Clulow  * Common Development and Distribution License ("CDDL"), version 1.0.
4*61d1e6c5SJoshua M. Clulow  * You may only use this file in accordance with the terms of version
5*61d1e6c5SJoshua M. Clulow  * 1.0 of the CDDL.
6*61d1e6c5SJoshua M. Clulow  *
7*61d1e6c5SJoshua M. Clulow  * A full copy of the text of the CDDL should have accompanied this
8*61d1e6c5SJoshua M. Clulow  * source.  A copy of the CDDL is also available via the Internet at
9*61d1e6c5SJoshua M. Clulow  * http://www.illumos.org/license/CDDL.
10*61d1e6c5SJoshua M. Clulow  */
11*61d1e6c5SJoshua M. Clulow 
12*61d1e6c5SJoshua M. Clulow /*
13*61d1e6c5SJoshua M. Clulow  * String utility functions with dynamic memory management.
14*61d1e6c5SJoshua M. Clulow  */
15*61d1e6c5SJoshua M. Clulow 
16*61d1e6c5SJoshua M. Clulow /*
17*61d1e6c5SJoshua M. Clulow  * Copyright 2014, Joyent, Inc.
18*61d1e6c5SJoshua M. Clulow  */
19*61d1e6c5SJoshua M. Clulow 
20*61d1e6c5SJoshua M. Clulow #include <stdlib.h>
21*61d1e6c5SJoshua M. Clulow #include <err.h>
22*61d1e6c5SJoshua M. Clulow #include <string.h>
23*61d1e6c5SJoshua M. Clulow 
24*61d1e6c5SJoshua M. Clulow #include "libcmdutils.h"
25*61d1e6c5SJoshua M. Clulow 
26*61d1e6c5SJoshua M. Clulow struct custr {
27*61d1e6c5SJoshua M. Clulow 	size_t cus_strlen;
28*61d1e6c5SJoshua M. Clulow 	size_t cus_datalen;
29*61d1e6c5SJoshua M. Clulow 	char *cus_data;
30*61d1e6c5SJoshua M. Clulow };
31*61d1e6c5SJoshua M. Clulow 
32*61d1e6c5SJoshua M. Clulow #define	STRING_CHUNK_SIZE	64
33*61d1e6c5SJoshua M. Clulow 
34*61d1e6c5SJoshua M. Clulow void
custr_reset(custr_t * cus)35*61d1e6c5SJoshua M. Clulow custr_reset(custr_t *cus)
36*61d1e6c5SJoshua M. Clulow {
37*61d1e6c5SJoshua M. Clulow 	if (cus->cus_data == NULL)
38*61d1e6c5SJoshua M. Clulow 		return;
39*61d1e6c5SJoshua M. Clulow 
40*61d1e6c5SJoshua M. Clulow 	cus->cus_strlen = 0;
41*61d1e6c5SJoshua M. Clulow 	cus->cus_data[0] = '\0';
42*61d1e6c5SJoshua M. Clulow }
43*61d1e6c5SJoshua M. Clulow 
44*61d1e6c5SJoshua M. Clulow size_t
custr_len(custr_t * cus)45*61d1e6c5SJoshua M. Clulow custr_len(custr_t *cus)
46*61d1e6c5SJoshua M. Clulow {
47*61d1e6c5SJoshua M. Clulow 	return (cus->cus_strlen);
48*61d1e6c5SJoshua M. Clulow }
49*61d1e6c5SJoshua M. Clulow 
50*61d1e6c5SJoshua M. Clulow const char *
custr_cstr(custr_t * cus)51*61d1e6c5SJoshua M. Clulow custr_cstr(custr_t *cus)
52*61d1e6c5SJoshua M. Clulow {
53*61d1e6c5SJoshua M. Clulow 	return (cus->cus_data);
54*61d1e6c5SJoshua M. Clulow }
55*61d1e6c5SJoshua M. Clulow 
56*61d1e6c5SJoshua M. Clulow int
custr_appendc(custr_t * cus,char newc)57*61d1e6c5SJoshua M. Clulow custr_appendc(custr_t *cus, char newc)
58*61d1e6c5SJoshua M. Clulow {
59*61d1e6c5SJoshua M. Clulow 	char news[2];
60*61d1e6c5SJoshua M. Clulow 
61*61d1e6c5SJoshua M. Clulow 	news[0] = newc;
62*61d1e6c5SJoshua M. Clulow 	news[1] = '\0';
63*61d1e6c5SJoshua M. Clulow 
64*61d1e6c5SJoshua M. Clulow 	return (custr_append(cus, news));
65*61d1e6c5SJoshua M. Clulow }
66*61d1e6c5SJoshua M. Clulow 
67*61d1e6c5SJoshua M. Clulow int
custr_append(custr_t * cus,const char * news)68*61d1e6c5SJoshua M. Clulow custr_append(custr_t *cus, const char *news)
69*61d1e6c5SJoshua M. Clulow {
70*61d1e6c5SJoshua M. Clulow 	size_t len = strlen(news);
71*61d1e6c5SJoshua M. Clulow 	size_t chunksz = STRING_CHUNK_SIZE;
72*61d1e6c5SJoshua M. Clulow 
73*61d1e6c5SJoshua M. Clulow 	while (chunksz < len) {
74*61d1e6c5SJoshua M. Clulow 		chunksz *= 2;
75*61d1e6c5SJoshua M. Clulow 	}
76*61d1e6c5SJoshua M. Clulow 
77*61d1e6c5SJoshua M. Clulow 	if (len + cus->cus_strlen + 1 >= cus->cus_datalen) {
78*61d1e6c5SJoshua M. Clulow 		char *new_data;
79*61d1e6c5SJoshua M. Clulow 		size_t new_datalen = cus->cus_datalen + chunksz;
80*61d1e6c5SJoshua M. Clulow 
81*61d1e6c5SJoshua M. Clulow 		/*
82*61d1e6c5SJoshua M. Clulow 		 * Allocate replacement memory:
83*61d1e6c5SJoshua M. Clulow 		 */
84*61d1e6c5SJoshua M. Clulow 		if ((new_data = malloc(new_datalen)) == NULL) {
85*61d1e6c5SJoshua M. Clulow 			return (-1);
86*61d1e6c5SJoshua M. Clulow 		}
87*61d1e6c5SJoshua M. Clulow 
88*61d1e6c5SJoshua M. Clulow 		/*
89*61d1e6c5SJoshua M. Clulow 		 * Copy existing data into replacement memory and free
90*61d1e6c5SJoshua M. Clulow 		 * the old memory.
91*61d1e6c5SJoshua M. Clulow 		 */
92*61d1e6c5SJoshua M. Clulow 		if (cus->cus_data != NULL) {
93*61d1e6c5SJoshua M. Clulow 			(void) memcpy(new_data, cus->cus_data,
94*61d1e6c5SJoshua M. Clulow 			    cus->cus_strlen + 1);
95*61d1e6c5SJoshua M. Clulow 			free(cus->cus_data);
96*61d1e6c5SJoshua M. Clulow 		}
97*61d1e6c5SJoshua M. Clulow 
98*61d1e6c5SJoshua M. Clulow 		/*
99*61d1e6c5SJoshua M. Clulow 		 * Swap in the replacement buffer:
100*61d1e6c5SJoshua M. Clulow 		 */
101*61d1e6c5SJoshua M. Clulow 		cus->cus_data = new_data;
102*61d1e6c5SJoshua M. Clulow 		cus->cus_datalen = new_datalen;
103*61d1e6c5SJoshua M. Clulow 	}
104*61d1e6c5SJoshua M. Clulow 	/*
105*61d1e6c5SJoshua M. Clulow 	 * Append new string to existing string:
106*61d1e6c5SJoshua M. Clulow 	 */
107*61d1e6c5SJoshua M. Clulow 	(void) memcpy(cus->cus_data + cus->cus_strlen, news, len + 1);
108*61d1e6c5SJoshua M. Clulow 	cus->cus_strlen += len;
109*61d1e6c5SJoshua M. Clulow 
110*61d1e6c5SJoshua M. Clulow 	return (0);
111*61d1e6c5SJoshua M. Clulow }
112*61d1e6c5SJoshua M. Clulow 
113*61d1e6c5SJoshua M. Clulow int
custr_alloc(custr_t ** cus)114*61d1e6c5SJoshua M. Clulow custr_alloc(custr_t **cus)
115*61d1e6c5SJoshua M. Clulow {
116*61d1e6c5SJoshua M. Clulow 	custr_t *t;
117*61d1e6c5SJoshua M. Clulow 
118*61d1e6c5SJoshua M. Clulow 	if ((t = calloc(1, sizeof (*t))) == NULL) {
119*61d1e6c5SJoshua M. Clulow 		*cus = NULL;
120*61d1e6c5SJoshua M. Clulow 		return (-1);
121*61d1e6c5SJoshua M. Clulow 	}
122*61d1e6c5SJoshua M. Clulow 
123*61d1e6c5SJoshua M. Clulow 	*cus = t;
124*61d1e6c5SJoshua M. Clulow 	return (0);
125*61d1e6c5SJoshua M. Clulow }
126*61d1e6c5SJoshua M. Clulow 
127*61d1e6c5SJoshua M. Clulow void
custr_free(custr_t * cus)128*61d1e6c5SJoshua M. Clulow custr_free(custr_t *cus)
129*61d1e6c5SJoshua M. Clulow {
130*61d1e6c5SJoshua M. Clulow 	if (cus == NULL)
131*61d1e6c5SJoshua M. Clulow 		return;
132*61d1e6c5SJoshua M. Clulow 
133*61d1e6c5SJoshua M. Clulow 	free(cus->cus_data);
134*61d1e6c5SJoshua M. Clulow 	free(cus);
135*61d1e6c5SJoshua M. Clulow }
136