Replace deprecated luaL_openlib() by luaL_register()
[apps/madmutt.git] / lib-lib / buffer.c
1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or (at
5  *  your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful, but
8  *  WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  *  General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15  *  MA 02110-1301, USA.
16  *
17  *  Copyright © 2006 Pierre Habouzit
18  */
19
20 /*
21  * Copyright notice from original mutt:
22  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
23  *
24  * This file is part of mutt-ng, see http://www.muttng.org/.
25  * It's licensed under the GNU General Public License,
26  * please see the file GPL in the top level source directory.
27  */
28
29 #include "lib-lib.h"
30
31 void buffer_splice(buffer_t *buf, ssize_t pos, ssize_t len,
32                    const void *data, ssize_t dlen)
33 {
34     if (dlen >= len)
35         buffer_extend(buf, dlen - len);
36     if (len >= buf->len)
37         len = buf->len;
38     memmove(buf->data + pos + dlen,
39             buf->data + pos + len,
40             buf->len - pos - len);
41     memcpy(buf->data + pos, data, dlen);
42     buffer_setlen(buf, buf->len + dlen - len);
43 }
44
45 void buffer_consume_upto(buffer_t *buf, const char *s)
46 {
47     assert (buf->data <= s && s <= buf->data + buf->len);
48     buffer_splice(buf, 0, s - buf->data, NULL, 0);
49 }
50
51 ssize_t buffer_addvf(buffer_t *buf, const char *fmt, va_list args)
52 {
53     ssize_t len;
54     va_list ap;
55
56     va_copy(ap, args);
57     buffer_ensure(buf, BUFSIZ);
58
59     len = vsnprintf(buf->data + buf->len, buf->size - buf->len, fmt, args);
60     if (len < 0)
61         return len;
62     if (len >= buf->size - buf->len) {
63         buffer_ensure(buf, len);
64         vsnprintf(buf->data + buf->len, buf->size - buf->len, fmt, ap);
65     }
66     buf->len += len;
67     buf->data[buf->len] = '\0';
68
69     return len;
70 }
71
72 ssize_t buffer_addf(buffer_t *buf, const char *fmt, ...)
73 {
74     ssize_t res;
75     va_list args;
76     va_start(args, fmt);
77     res = buffer_addvf(buf, fmt, args);
78     va_end(args);
79     return res;
80 }
81 /****** LEGACY BUFFERS *******/
82
83 /*
84  * Creates and initializes a BUFFER*. If passed an existing BUFFER*,
85  * just initializes. Frees anything already in the buffer.
86  *
87  * Disregards the 'destroy' flag, which seems reserved for caller.
88  * This is bad, but there's no apparent protocol for it.
89  */
90 BUFFER *mutt_buffer_init(BUFFER *b)
91 {
92     if (!b) {
93         b = p_new(BUFFER, 1);
94     }
95     p_delete(&b->data);
96     p_clear(b, 1);
97     return b;
98 }
99
100 /*
101  * Creates and initializes a BUFFER*. If passed an existing BUFFER*,
102  * just initializes. Frees anything already in the buffer. Copies in
103  * the seed string.
104  *
105  * Disregards the 'destroy' flag, which seems reserved for caller.
106  * This is bad, but there's no apparent protocol for it.
107  */
108 BUFFER *mutt_buffer_from(BUFFER * b, const char *seed)
109 {
110     if (!seed)
111         return NULL;
112
113     b = mutt_buffer_init(b);
114     b->dsize = m_strlen(seed);
115     b->data  = m_strdup(seed);
116     b->dptr  = (char *)b->data + b->dsize;
117     return b;
118 }
119
120 void mutt_buffer_free(BUFFER **p)
121 {
122     if (p && *p) {
123         p_delete(&(*p)->data);
124         p_delete(p);
125     }
126 }
127
128 /* dynamically grows a BUFFER to accomodate s, in increments of 128 bytes.
129  * Always one byte bigger than necessary for the null terminator, and
130  * the buffer is always null-terminated */
131 void mutt_buffer_add(BUFFER *buf, const char *s, ssize_t len)
132 {
133     size_t offset;
134
135     if (buf->dptr + len + 1 > buf->data + buf->dsize) {
136         offset = buf->dptr - buf->data;
137         buf->dsize += ((len + 1 + 127) & ~127);
138         p_realloc(&buf->data, buf->dsize);
139         buf->dptr = buf->data + offset;
140     }
141     memcpy(buf->dptr, s, len);
142     buf->dptr += len;
143     *buf->dptr = '\0';
144 }
145