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