84 size_t len = roundup(src->str_len, STR_CHUNK_SZ);
85 dest->str_s = zalloc(src->str_ops, len);
86 if (dest->str_s == NULL)
87 return (B_FALSE);
88
89 (void) memcpy(dest->str_s, src->str_s, src->str_len);
90 dest->str_len = src->str_len;
91 dest->str_size = len;
92
93 return (B_TRUE);
94 }
95
96 /*
97 * ensure s has at least amt bytes free, resizing if necessary
98 */
99 static boolean_t
100 str_reserve(str_t *s, size_t amt)
101 {
102 size_t newlen = s->str_len + amt;
103
104 if ((amt > 0) && (s->str_len + amt <= s->str_size))
105 return (B_TRUE);
106
107 size_t newsize = roundup(newlen, STR_CHUNK_SZ);
108 void *temp;
109
110 if (IS_REF(s)) {
111 temp = zalloc(s->str_ops, newsize);
112 if (temp == NULL)
113 return (B_FALSE);
114
115 (void) memcpy(temp, s->str_s, s->str_len);
116 } else {
117 temp = xrealloc(s->str_ops, s->str_s, s->str_size, newsize);
118 if (temp == NULL)
119 return (B_FALSE);
120 }
121
122 s->str_s = temp;
123 s->str_size = newsize;
146 {
147 /* empty string is a noop */
148 if (src->str_s == NULL || src->str_len == 0)
149 return (B_TRUE);
150
151 /* if src is a reference, we can just copy that */
152 if (dest->str_s == NULL && IS_REF(src)) {
153 *dest = *src;
154 return (B_TRUE);
155 }
156
157 if (!str_reserve(dest, src->str_len))
158 return (B_FALSE);
159
160 (void) memcpy(dest->str_s + dest->str_len, src->str_s, src->str_len);
161 dest->str_len += src->str_len;
162 return (B_TRUE);
163 }
164
165 boolean_t
166 str_append_c(str_t *s, int c)
167 {
168 if (!str_reserve(s, 1))
169 return (B_FALSE);
170
171 s->str_s[s->str_len++] = c;
172 return (B_TRUE);
173 }
174
175 boolean_t
176 str_insert(str_t *s, size_t idx, const char *cstr, size_t cstrlen)
177 {
178 if (cstr == NULL)
179 return (B_TRUE);
180
181 if (cstrlen == 0)
182 cstrlen = strlen(cstr);
183
184 str_t src = {
185 .str_s = (char *)cstr,
186 .str_len = cstrlen,
192 }
193
194 boolean_t
195 str_insert_str(str_t *dest, size_t idx, const str_t *src)
196 {
197 ASSERT3U(idx, <=, dest->str_len);
198
199 if (idx == dest->str_len)
200 return (str_append_str(dest, src));
201
202 if (idx == 0 && dest->str_s == NULL && IS_REF(src)) {
203 sysdem_ops_t *ops = dest->str_ops;
204 *dest = *src;
205 dest->str_ops = ops;
206 return (B_TRUE);
207 }
208
209 if (!str_reserve(dest, src->str_len))
210 return (B_FALSE);
211
212 /* Unlike some programmers, *I* can read manpages. */
213 (void) memmove(dest->str_s + idx + src->str_len, dest->str_s + idx,
214 dest->str_len - idx);
215 (void) memcpy(dest->str_s + idx, src->str_s, src->str_len);
216 dest->str_len += src->str_len;
217
218 return (B_TRUE);
219 }
220
221 boolean_t
222 str_erase(str_t *s, size_t pos, size_t len)
223 {
224 ASSERT3U(pos, <, s->str_len);
225 ASSERT3U(pos + len, <=, s->str_len);
226
227 if (IS_REF(s)) {
228 if (!str_reserve(s, 0))
229 return (B_FALSE);
230 }
231
232 (void) memmove(s->str_s + pos, s->str_s + pos + len, s->str_len - len);
233 s->str_len -= len;
234 return (B_TRUE);
|
84 size_t len = roundup(src->str_len, STR_CHUNK_SZ);
85 dest->str_s = zalloc(src->str_ops, len);
86 if (dest->str_s == NULL)
87 return (B_FALSE);
88
89 (void) memcpy(dest->str_s, src->str_s, src->str_len);
90 dest->str_len = src->str_len;
91 dest->str_size = len;
92
93 return (B_TRUE);
94 }
95
96 /*
97 * ensure s has at least amt bytes free, resizing if necessary
98 */
99 static boolean_t
100 str_reserve(str_t *s, size_t amt)
101 {
102 size_t newlen = s->str_len + amt;
103
104 /* overflow check */
105 if (newlen < s->str_len || newlen < amt)
106 return (B_FALSE);
107
108 if ((amt > 0) && (s->str_len + amt <= s->str_size))
109 return (B_TRUE);
110
111 size_t newsize = roundup(newlen, STR_CHUNK_SZ);
112 void *temp;
113
114 if (IS_REF(s)) {
115 temp = zalloc(s->str_ops, newsize);
116 if (temp == NULL)
117 return (B_FALSE);
118
119 (void) memcpy(temp, s->str_s, s->str_len);
120 } else {
121 temp = xrealloc(s->str_ops, s->str_s, s->str_size, newsize);
122 if (temp == NULL)
123 return (B_FALSE);
124 }
125
126 s->str_s = temp;
127 s->str_size = newsize;
150 {
151 /* empty string is a noop */
152 if (src->str_s == NULL || src->str_len == 0)
153 return (B_TRUE);
154
155 /* if src is a reference, we can just copy that */
156 if (dest->str_s == NULL && IS_REF(src)) {
157 *dest = *src;
158 return (B_TRUE);
159 }
160
161 if (!str_reserve(dest, src->str_len))
162 return (B_FALSE);
163
164 (void) memcpy(dest->str_s + dest->str_len, src->str_s, src->str_len);
165 dest->str_len += src->str_len;
166 return (B_TRUE);
167 }
168
169 boolean_t
170 str_append_c(str_t *s, char c)
171 {
172 if (!str_reserve(s, 1))
173 return (B_FALSE);
174
175 s->str_s[s->str_len++] = c;
176 return (B_TRUE);
177 }
178
179 boolean_t
180 str_insert(str_t *s, size_t idx, const char *cstr, size_t cstrlen)
181 {
182 if (cstr == NULL)
183 return (B_TRUE);
184
185 if (cstrlen == 0)
186 cstrlen = strlen(cstr);
187
188 str_t src = {
189 .str_s = (char *)cstr,
190 .str_len = cstrlen,
196 }
197
198 boolean_t
199 str_insert_str(str_t *dest, size_t idx, const str_t *src)
200 {
201 ASSERT3U(idx, <=, dest->str_len);
202
203 if (idx == dest->str_len)
204 return (str_append_str(dest, src));
205
206 if (idx == 0 && dest->str_s == NULL && IS_REF(src)) {
207 sysdem_ops_t *ops = dest->str_ops;
208 *dest = *src;
209 dest->str_ops = ops;
210 return (B_TRUE);
211 }
212
213 if (!str_reserve(dest, src->str_len))
214 return (B_FALSE);
215
216 /*
217 * Shift the contents of dest over at the insertion point. Since
218 * src and dest ranges will overlap, and unlike some programmers,
219 * *I* can read man pages - memmove() is the appropriate function
220 * to this.
221 */
222 (void) memmove(dest->str_s + idx + src->str_len, dest->str_s + idx,
223 dest->str_len - idx);
224
225 /*
226 * However the content to insert does not overlap with the destination
227 * so memcpy() is fine here.
228 */
229 (void) memcpy(dest->str_s + idx, src->str_s, src->str_len);
230 dest->str_len += src->str_len;
231
232 return (B_TRUE);
233 }
234
235 boolean_t
236 str_erase(str_t *s, size_t pos, size_t len)
237 {
238 ASSERT3U(pos, <, s->str_len);
239 ASSERT3U(pos + len, <=, s->str_len);
240
241 if (IS_REF(s)) {
242 if (!str_reserve(s, 0))
243 return (B_FALSE);
244 }
245
246 (void) memmove(s->str_s + pos, s->str_s + pos + len, s->str_len - len);
247 s->str_len -= len;
248 return (B_TRUE);
|