20221212
[devspec.git] / devspec.en_US / project / recutils / src / rec-buf.c
blob428b42f948b73d9d6ec28b96e17403af891c3387
1 /* -*- mode: C -*-
3 * File: rec-buf.c
4 * Date: Fri Dec 17 18:40:53 2010
6 * GNU recutils - Flexible buffers.
8 */
10 /* Copyright (C) 2010-2019 Jose E. Marchesi */
12 /* This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <config.h>
28 #include <stdlib.h>
30 #include <rec.h>
32 #define REC_BUF_STEP 512
34 struct rec_buf_s
36 char *data;
37 size_t size;
38 size_t used;
40 /* Pointers to user-provided variables that will be updated at
41 rec_buf_destroy time. */
42 char **data_pointer;
43 size_t *size_pointer;
47 * Public functions.
50 rec_buf_t
51 rec_buf_new (char **data, size_t *size)
53 rec_buf_t new;
55 new = malloc (sizeof (struct rec_buf_s));
56 if (new)
58 new->data_pointer = data;
59 new->size_pointer = size;
61 new->data = malloc (REC_BUF_STEP);
62 new->size = REC_BUF_STEP;
63 new->used = 0;
65 if (!new->data)
67 free (new);
68 new = NULL;
72 return new;
75 void
76 rec_buf_close (rec_buf_t buf)
78 /* Adjust the buffer. */
79 if (buf->used > 0)
80 buf->data = realloc (buf->data, buf->used + 1);
81 buf->data[buf->used] = '\0';
83 /* Update the user-provided buffer and size. */
84 *(buf->data_pointer) = buf->data;
85 *(buf->size_pointer) = buf->used;
87 /* Don't deallocate buf->data */
88 free (buf);
91 void
92 rec_buf_rewind (rec_buf_t buf, int n)
94 if ((buf->used - n) >= 0)
95 buf->used = buf->used - n;
98 int
99 rec_buf_putc (int c, rec_buf_t buf)
101 unsigned int ret;
103 if (c == EOF)
104 return EOF;
106 ret = (unsigned int) c;
107 if ((buf->used + 1) > buf->size)
109 /* Allocate a new block */
110 buf->size = buf->size + REC_BUF_STEP;
111 buf->data = realloc (buf->data, buf->size);
113 if (!buf->data)
114 /* Not enough memory.
115 REC_BUF_STEP should not be 0. */
116 ret = EOF;
119 if (ret != EOF)
120 /* Add the character */
121 buf->data[buf->used++] = (char) c;
123 return ret;
127 rec_buf_puts (const char *str, rec_buf_t buf)
129 int ret;
130 const char *p;
132 ret = 0;
133 p = str;
134 while (*p != '\0')
136 if (rec_buf_putc (*p, buf) == EOF)
138 /* Error. */
139 ret = -1;
140 break;
143 ret++;
144 p++;
147 return ret;
150 /* End of rec-buf.c */