1/*
2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <stdlib.h>
25#include <string.h>
26
27#include "ossl-buffer.h"
28
29BUF_MEM *
30BUF_MEM_new(void)
31{
32	BUF_MEM *b;
33
34	b = malloc(sizeof(BUF_MEM));
35	if (NULL == b) {
36		return (NULL);
37	}
38
39	b->length = 0;
40	b->max = 0;
41	b->data = NULL;
42
43	return (b);
44}
45
46
47void
48BUF_MEM_free(BUF_MEM *b)
49{
50	if (NULL == b) {
51		return;
52	}
53
54	if (NULL != b->data) {
55		memset(b->data, 0, (unsigned int)b->max);
56		free(b->data);
57	}
58	free(b);
59}
60
61
62int
63BUF_MEM_grow(BUF_MEM *str, int len)
64{
65	char *ret;
66	unsigned int n;
67
68	if (str->length >= len) {
69		str->length = len;
70		return (len);
71	}
72	if (str->max >= len) {
73		memset(&str->data[str->length], 0, len-str->length);
74		str->length = len;
75		return (len);
76	}
77	n = (len + 3) / 3 * 4;
78	if (str->data == NULL) {
79		ret = malloc(n);
80	} else{
81		ret = realloc(str->data, n);
82	}
83	if (ret == NULL) {
84		/* BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); */
85		len = 0;
86	} else {
87		str->data = ret;
88		str->max = n;
89		memset(&str->data[str->length], 0, len-str->length);
90		str->length = len;
91	}
92
93	return (len);
94}
95
96
97int
98BUF_MEM_grow_clean(BUF_MEM *str, int len)
99{
100	char *ret;
101	unsigned int n;
102
103	if (str->length >= len) {
104		memset(&str->data[len], 0, str->length-len);
105		str->length = len;
106		return (len);
107	}
108	if (str->max >= len) {
109		memset(&str->data[str->length], 0, len-str->length);
110		str->length = len;
111		return (len);
112	}
113	n = (len + 3) / 3 * 4;
114	if (NULL == str->data) {
115		ret = malloc(n);
116	} else {
117		if (n <= 0) {
118			return (0);
119		}
120		if ((ret = malloc(n)) != NULL) {
121			memcpy(ret, str->data, str->max);
122			memset(str->data, 0, str->max);
123			free(str->data);
124		}
125	}
126	if (ret == NULL) {
127		len = 0;
128	} else {
129		str->data = ret;
130		str->max = n;
131		memset(&str->data[str->length], 0, len - str->length);
132		str->length = len;
133	}
134	return (len);
135}
136
137
138size_t
139BUF_strlcpy(char *dst, const char *src, size_t size)
140{
141	size_t l = 0;
142
143	for ( ; size > 1 && *src; size--) {
144		*dst++ = *src++;
145		l++;
146	}
147	if (size) {
148		*dst = '\0';
149	}
150	return (l + strlen(src));
151}
152
153
154size_t
155BUF_strlcat(char *dst, const char *src, size_t size)
156{
157	size_t l = 0;
158
159	for ( ; size > 0 && *dst; size--, dst++) {
160		l++;
161	}
162	return (l + BUF_strlcpy(dst, src, size));
163}
164