qt: playlist: use item title if available
[vlc.git] / src / text / memstream.c
1 /*****************************************************************************
2  * memstream.c: heap-based output streams
3  *****************************************************************************
4  * Copyright (C) 2016 RĂ©mi Denis-Courmont
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <vlc_common.h>
26 #include <vlc_memstream.h>
27
28 #ifdef HAVE_OPEN_MEMSTREAM
29 int vlc_memstream_open(struct vlc_memstream *ms)
30 {
31     ms->stream = open_memstream(&ms->ptr, &ms->length);
32     return likely(ms->stream != NULL) ? 0 : EOF;
33 }
34
35 int vlc_memstream_flush(struct vlc_memstream *ms)
36 {
37     if (unlikely(ms->stream == NULL))
38         return EOF;
39
40     if (ferror(ms->stream))
41         return EOF;
42
43     return fflush(ms->stream);
44 }
45
46 int vlc_memstream_close(struct vlc_memstream *ms)
47 {
48     FILE *stream = ms->stream;
49     int ret;
50
51     if (unlikely(stream == NULL))
52         return EOF;
53
54     ms->stream = NULL;
55     ret = ferror(stream);
56
57     if (fclose(stream))
58         return EOF;
59
60     if (unlikely(ret))
61     {
62         free(ms->ptr);
63         return EOF;
64     }
65     return 0;
66
67
68 size_t vlc_memstream_write(struct vlc_memstream *ms, const void *ptr,
69                            size_t len)
70 {
71     if (unlikely(ms->stream == NULL))
72         return 0;
73
74     return fwrite(ptr, 1, len, ms->stream);
75 }
76
77 int vlc_memstream_putc(struct vlc_memstream *ms, int c)
78 {
79     if (unlikely(ms->stream == NULL))
80         return EOF;
81
82     return fputc(c, ms->stream);
83 }
84
85 int (vlc_memstream_puts)(struct vlc_memstream *ms, const char *str)
86 {
87     if (unlikely(ms->stream == NULL))
88         return EOF;
89
90     return fputs(str, ms->stream);
91 }
92
93 int vlc_memstream_vprintf(struct vlc_memstream *ms, const char *fmt,
94                           va_list args)
95 {
96     if (unlikely(ms->stream == NULL))
97         return EOF;
98
99     return vfprintf(ms->stream, fmt, args);
100 }
101
102 #else
103 #include <stdlib.h>
104
105 int vlc_memstream_open(struct vlc_memstream *ms)
106 {
107     ms->error = 0;
108     ms->ptr = calloc(1, 1);
109     if (unlikely(ms->ptr == NULL))
110         ms->error = EOF;
111     ms->length = 0;
112     return ms->error;
113 }
114
115 int vlc_memstream_flush(struct vlc_memstream *ms)
116 {
117     return ms->error;
118 }
119
120 int vlc_memstream_close(struct vlc_memstream *ms)
121 {
122     if (ms->error)
123         free(ms->ptr);
124     return ms->error;
125
126
127 size_t vlc_memstream_write(struct vlc_memstream *ms, const void *ptr,
128                            size_t len)
129 {
130     size_t newlen;
131
132     if (unlikely(add_overflow(ms->length, len, &newlen))
133      || unlikely(add_overflow(newlen, 1, &newlen)))
134         goto error;
135
136     char *base = realloc(ms->ptr, newlen);
137     if (unlikely(base == NULL))
138         goto error;
139
140     memcpy(base + ms->length, ptr, len);
141     ms->ptr = base;
142     ms->length += len;
143     base[ms->length] = '\0';
144     return len;
145
146 error:
147     ms->error = EOF;
148     return 0;
149 }
150
151 int vlc_memstream_putc(struct vlc_memstream *ms, int c)
152 {
153     return (vlc_memstream_write(ms, &(unsigned char){ c }, 1u) == 1) ? c : EOF;
154 }
155
156 int (vlc_memstream_puts)(struct vlc_memstream *ms, const char *str)
157 {
158     size_t len = strlen(str);
159     return (vlc_memstream_write(ms, str, len) == len) ? 0 : EOF;
160 }
161
162 int vlc_memstream_vprintf(struct vlc_memstream *ms, const char *fmt,
163                           va_list args)
164 {
165     va_list ap;
166     char *ptr;
167     int len;
168     size_t newlen;
169
170     va_copy(ap, args);
171     len = vsnprintf(NULL, 0, fmt, ap);
172     va_end(ap);
173
174     if (len < 0
175      || unlikely(add_overflow(ms->length, len, &newlen))
176      || unlikely(add_overflow(newlen, 1, &newlen)))
177         goto error;
178
179     ptr = realloc(ms->ptr, newlen);
180     if (ptr == NULL)
181         goto error;
182
183     vsnprintf(ptr + ms->length, len + 1, fmt, args);
184     ms->ptr = ptr;
185     ms->length += len;
186     return len;
187
188 error:
189     ms->error = EOF;
190     return EOF;
191 }
192 #endif
193
194 int vlc_memstream_printf(struct vlc_memstream *ms, const char *fmt, ...)
195 {
196     va_list ap;
197     int ret;
198
199     va_start(ap, fmt);
200     ret = vlc_memstream_vprintf(ms, fmt, ap);
201     va_end(ap);
202     return ret;
203 }