1*5af32e75SAxel Dörfler /* Copyright (C) 1995,1996,1997,1999,2000,2002 Free Software Foundation, Inc.
2*5af32e75SAxel Dörfler This file is part of the GNU C Library.
3*5af32e75SAxel Dörfler
4*5af32e75SAxel Dörfler The GNU C Library is free software; you can redistribute it and/or
5*5af32e75SAxel Dörfler modify it under the terms of the GNU Lesser General Public
6*5af32e75SAxel Dörfler License as published by the Free Software Foundation; either
7*5af32e75SAxel Dörfler version 2.1 of the License, or (at your option) any later version.
8*5af32e75SAxel Dörfler
9*5af32e75SAxel Dörfler The GNU C Library is distributed in the hope that it will be useful,
10*5af32e75SAxel Dörfler but WITHOUT ANY WARRANTY; without even the implied warranty of
11*5af32e75SAxel Dörfler MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12*5af32e75SAxel Dörfler Lesser General Public License for more details.
13*5af32e75SAxel Dörfler
14*5af32e75SAxel Dörfler You should have received a copy of the GNU Lesser General Public
15*5af32e75SAxel Dörfler License along with the GNU C Library; if not, write to the Free
16*5af32e75SAxel Dörfler Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17*5af32e75SAxel Dörfler 02111-1307 USA. */
18*5af32e75SAxel Dörfler
19*5af32e75SAxel Dörfler #include "libioP.h"
20*5af32e75SAxel Dörfler #include "strfile.h"
21*5af32e75SAxel Dörfler #include <stdio.h>
22*5af32e75SAxel Dörfler #include <stdlib.h>
23*5af32e75SAxel Dörfler
24*5af32e75SAxel Dörfler
25*5af32e75SAxel Dörfler struct _IO_FILE_memstream
26*5af32e75SAxel Dörfler {
27*5af32e75SAxel Dörfler _IO_strfile _sf;
28*5af32e75SAxel Dörfler char **bufloc;
29*5af32e75SAxel Dörfler _IO_size_t *sizeloc;
30*5af32e75SAxel Dörfler };
31*5af32e75SAxel Dörfler
32*5af32e75SAxel Dörfler
33*5af32e75SAxel Dörfler static int _IO_mem_sync __P ((_IO_FILE* fp));
34*5af32e75SAxel Dörfler static void _IO_mem_finish __P ((_IO_FILE* fp, int));
35*5af32e75SAxel Dörfler static int _IO_wmem_sync __P ((_IO_FILE* fp));
36*5af32e75SAxel Dörfler static void _IO_wmem_finish __P ((_IO_FILE* fp, int));
37*5af32e75SAxel Dörfler
38*5af32e75SAxel Dörfler
39*5af32e75SAxel Dörfler static struct _IO_jump_t _IO_mem_jumps =
40*5af32e75SAxel Dörfler {
41*5af32e75SAxel Dörfler JUMP_INIT_DUMMY,
42*5af32e75SAxel Dörfler JUMP_INIT (finish, _IO_mem_finish),
43*5af32e75SAxel Dörfler JUMP_INIT (overflow, INTUSE(_IO_str_overflow)),
44*5af32e75SAxel Dörfler JUMP_INIT (underflow, INTUSE(_IO_str_underflow)),
45*5af32e75SAxel Dörfler JUMP_INIT (uflow, INTUSE(_IO_default_uflow)),
46*5af32e75SAxel Dörfler JUMP_INIT (pbackfail, INTUSE(_IO_str_pbackfail)),
47*5af32e75SAxel Dörfler JUMP_INIT (xsputn, INTUSE(_IO_default_xsputn)),
48*5af32e75SAxel Dörfler JUMP_INIT (xsgetn, INTUSE(_IO_default_xsgetn)),
49*5af32e75SAxel Dörfler JUMP_INIT (seekoff, INTUSE(_IO_str_seekoff)),
50*5af32e75SAxel Dörfler JUMP_INIT (seekpos, _IO_default_seekpos),
51*5af32e75SAxel Dörfler JUMP_INIT (setbuf, _IO_default_setbuf),
52*5af32e75SAxel Dörfler JUMP_INIT (sync, _IO_mem_sync),
53*5af32e75SAxel Dörfler JUMP_INIT (doallocate, INTUSE(_IO_default_doallocate)),
54*5af32e75SAxel Dörfler JUMP_INIT (read, _IO_default_read),
55*5af32e75SAxel Dörfler JUMP_INIT (write, _IO_default_write),
56*5af32e75SAxel Dörfler JUMP_INIT (seek, _IO_default_seek),
57*5af32e75SAxel Dörfler JUMP_INIT (close, _IO_default_close),
58*5af32e75SAxel Dörfler JUMP_INIT (stat, _IO_default_stat),
59*5af32e75SAxel Dörfler JUMP_INIT(showmanyc, _IO_default_showmanyc),
60*5af32e75SAxel Dörfler JUMP_INIT(imbue, _IO_default_imbue)
61*5af32e75SAxel Dörfler };
62*5af32e75SAxel Dörfler
63*5af32e75SAxel Dörfler static struct _IO_jump_t _IO_wmem_jumps =
64*5af32e75SAxel Dörfler {
65*5af32e75SAxel Dörfler JUMP_INIT_DUMMY,
66*5af32e75SAxel Dörfler JUMP_INIT (finish, (_IO_finish_t) _IO_wmem_finish),
67*5af32e75SAxel Dörfler JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
68*5af32e75SAxel Dörfler JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
69*5af32e75SAxel Dörfler JUMP_INIT (uflow, (_IO_underflow_t) INTUSE(_IO_wdefault_uflow)),
70*5af32e75SAxel Dörfler JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
71*5af32e75SAxel Dörfler JUMP_INIT (xsputn, (_IO_xsputn_t) INTUSE(_IO_wdefault_xsputn)),
72*5af32e75SAxel Dörfler JUMP_INIT (xsgetn, (_IO_xsgetn_t) INTUSE(_IO_wdefault_xsgetn)),
73*5af32e75SAxel Dörfler JUMP_INIT (seekoff, _IO_wstr_seekoff),
74*5af32e75SAxel Dörfler JUMP_INIT (seekpos, _IO_default_seekpos),
75*5af32e75SAxel Dörfler JUMP_INIT (setbuf, _IO_default_setbuf),
76*5af32e75SAxel Dörfler JUMP_INIT (sync, (_IO_sync_t) _IO_wmem_sync),
77*5af32e75SAxel Dörfler JUMP_INIT (doallocate, INTUSE(_IO_wdefault_doallocate)),
78*5af32e75SAxel Dörfler JUMP_INIT (read, _IO_default_read),
79*5af32e75SAxel Dörfler JUMP_INIT (write, _IO_default_write),
80*5af32e75SAxel Dörfler JUMP_INIT (seek, _IO_default_seek),
81*5af32e75SAxel Dörfler JUMP_INIT (close, _IO_default_close),
82*5af32e75SAxel Dörfler JUMP_INIT (stat, _IO_default_stat),
83*5af32e75SAxel Dörfler JUMP_INIT(showmanyc, _IO_default_showmanyc),
84*5af32e75SAxel Dörfler JUMP_INIT(imbue, _IO_default_imbue)
85*5af32e75SAxel Dörfler };
86*5af32e75SAxel Dörfler
87*5af32e75SAxel Dörfler /* Open a stream that writes into a malloc'd buffer that is expanded as
88*5af32e75SAxel Dörfler necessary. *BUFLOC and *SIZELOC are updated with the buffer's location
89*5af32e75SAxel Dörfler and the number of characters written on fflush or fclose. */
90*5af32e75SAxel Dörfler _IO_FILE *
open_memstream(bufloc,sizeloc)91*5af32e75SAxel Dörfler open_memstream (bufloc, sizeloc)
92*5af32e75SAxel Dörfler char **bufloc;
93*5af32e75SAxel Dörfler _IO_size_t *sizeloc;
94*5af32e75SAxel Dörfler {
95*5af32e75SAxel Dörfler struct locked_FILE
96*5af32e75SAxel Dörfler {
97*5af32e75SAxel Dörfler struct _IO_FILE_memstream fp;
98*5af32e75SAxel Dörfler #ifdef _IO_MTSAFE_IO
99*5af32e75SAxel Dörfler _IO_lock_t lock;
100*5af32e75SAxel Dörfler #endif
101*5af32e75SAxel Dörfler struct _IO_wide_data wd;
102*5af32e75SAxel Dörfler } *new_f;
103*5af32e75SAxel Dörfler char *buf;
104*5af32e75SAxel Dörfler
105*5af32e75SAxel Dörfler new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
106*5af32e75SAxel Dörfler if (new_f == NULL)
107*5af32e75SAxel Dörfler return NULL;
108*5af32e75SAxel Dörfler #ifdef _IO_MTSAFE_IO
109*5af32e75SAxel Dörfler new_f->fp._sf._sbf._f._lock = &new_f->lock;
110*5af32e75SAxel Dörfler #endif
111*5af32e75SAxel Dörfler
112*5af32e75SAxel Dörfler buf = malloc (_IO_BUFSIZ);
113*5af32e75SAxel Dörfler if (buf == NULL)
114*5af32e75SAxel Dörfler return NULL;
115*5af32e75SAxel Dörfler _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
116*5af32e75SAxel Dörfler _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps;
117*5af32e75SAxel Dörfler INTUSE(_IO_str_init_static) (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
118*5af32e75SAxel Dörfler new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
119*5af32e75SAxel Dörfler new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
120*5af32e75SAxel Dörfler new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
121*5af32e75SAxel Dörfler
122*5af32e75SAxel Dörfler new_f->fp.bufloc = bufloc;
123*5af32e75SAxel Dörfler new_f->fp.sizeloc = sizeloc;
124*5af32e75SAxel Dörfler
125*5af32e75SAxel Dörfler return (_IO_FILE *) &new_f->fp._sf._sbf;
126*5af32e75SAxel Dörfler }
127*5af32e75SAxel Dörfler libc_hidden_def (open_memstream)
128*5af32e75SAxel Dörfler
129*5af32e75SAxel Dörfler
130*5af32e75SAxel Dörfler static int
131*5af32e75SAxel Dörfler _IO_mem_sync (fp)
132*5af32e75SAxel Dörfler _IO_FILE* fp;
133*5af32e75SAxel Dörfler {
134*5af32e75SAxel Dörfler struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
135*5af32e75SAxel Dörfler int res;
136*5af32e75SAxel Dörfler
137*5af32e75SAxel Dörfler res = _IO_default_sync (fp);
138*5af32e75SAxel Dörfler if (res < 0)
139*5af32e75SAxel Dörfler return res;
140*5af32e75SAxel Dörfler
141*5af32e75SAxel Dörfler if (fp->_IO_write_ptr == fp->_IO_write_end)
142*5af32e75SAxel Dörfler {
143*5af32e75SAxel Dörfler INTUSE(_IO_str_overflow) (fp, '\0');
144*5af32e75SAxel Dörfler --fp->_IO_write_ptr;
145*5af32e75SAxel Dörfler }
146*5af32e75SAxel Dörfler else
147*5af32e75SAxel Dörfler *fp->_IO_write_ptr = '\0';
148*5af32e75SAxel Dörfler
149*5af32e75SAxel Dörfler *mp->bufloc = fp->_IO_write_base;
150*5af32e75SAxel Dörfler *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
151*5af32e75SAxel Dörfler
152*5af32e75SAxel Dörfler return 0;
153*5af32e75SAxel Dörfler }
154*5af32e75SAxel Dörfler
155*5af32e75SAxel Dörfler
156*5af32e75SAxel Dörfler static void
_IO_mem_finish(fp,dummy)157*5af32e75SAxel Dörfler _IO_mem_finish (fp, dummy)
158*5af32e75SAxel Dörfler _IO_FILE* fp;
159*5af32e75SAxel Dörfler int dummy;
160*5af32e75SAxel Dörfler {
161*5af32e75SAxel Dörfler struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
162*5af32e75SAxel Dörfler
163*5af32e75SAxel Dörfler *mp->bufloc = (char *) realloc (fp->_IO_write_base,
164*5af32e75SAxel Dörfler fp->_IO_write_ptr - fp->_IO_write_base + 1);
165*5af32e75SAxel Dörfler if (*mp->bufloc != NULL)
166*5af32e75SAxel Dörfler {
167*5af32e75SAxel Dörfler (*mp->bufloc)[fp->_IO_write_ptr - fp->_IO_write_base] = '\0';
168*5af32e75SAxel Dörfler *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
169*5af32e75SAxel Dörfler }
170*5af32e75SAxel Dörfler
171*5af32e75SAxel Dörfler fp->_IO_buf_base = NULL;
172*5af32e75SAxel Dörfler
173*5af32e75SAxel Dörfler INTUSE(_IO_default_finish) (fp, 0);
174*5af32e75SAxel Dörfler }
175*5af32e75SAxel Dörfler
176*5af32e75SAxel Dörfler
177*5af32e75SAxel Dörfler static int
_IO_wmem_sync(fp)178*5af32e75SAxel Dörfler _IO_wmem_sync (fp)
179*5af32e75SAxel Dörfler _IO_FILE* fp;
180*5af32e75SAxel Dörfler {
181*5af32e75SAxel Dörfler struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
182*5af32e75SAxel Dörfler int res;
183*5af32e75SAxel Dörfler
184*5af32e75SAxel Dörfler res = _IO_default_sync (fp);
185*5af32e75SAxel Dörfler if (res < 0)
186*5af32e75SAxel Dörfler return res;
187*5af32e75SAxel Dörfler
188*5af32e75SAxel Dörfler if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end)
189*5af32e75SAxel Dörfler {
190*5af32e75SAxel Dörfler _IO_wstr_overflow (fp, L'\0');
191*5af32e75SAxel Dörfler --fp->_wide_data->_IO_write_ptr;
192*5af32e75SAxel Dörfler }
193*5af32e75SAxel Dörfler else
194*5af32e75SAxel Dörfler *fp->_wide_data->_IO_write_ptr = '\0';
195*5af32e75SAxel Dörfler
196*5af32e75SAxel Dörfler *mp->bufloc = (char *) fp->_wide_data->_IO_write_base;
197*5af32e75SAxel Dörfler *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
198*5af32e75SAxel Dörfler - fp->_wide_data->_IO_write_base);
199*5af32e75SAxel Dörfler
200*5af32e75SAxel Dörfler return 0;
201*5af32e75SAxel Dörfler }
202*5af32e75SAxel Dörfler
203*5af32e75SAxel Dörfler
204*5af32e75SAxel Dörfler static void
_IO_wmem_finish(fp,dummy)205*5af32e75SAxel Dörfler _IO_wmem_finish (fp, dummy)
206*5af32e75SAxel Dörfler _IO_FILE* fp;
207*5af32e75SAxel Dörfler int dummy;
208*5af32e75SAxel Dörfler {
209*5af32e75SAxel Dörfler struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
210*5af32e75SAxel Dörfler
211*5af32e75SAxel Dörfler *mp->bufloc = (char *) realloc (fp->_wide_data->_IO_write_base,
212*5af32e75SAxel Dörfler (fp->_wide_data->_IO_write_ptr
213*5af32e75SAxel Dörfler - fp->_wide_data->_IO_write_base + 1)
214*5af32e75SAxel Dörfler * sizeof (wchar_t));
215*5af32e75SAxel Dörfler if (*mp->bufloc != NULL)
216*5af32e75SAxel Dörfler {
217*5af32e75SAxel Dörfler ((wchar_t *) (*mp->bufloc))[fp->_wide_data->_IO_write_ptr
218*5af32e75SAxel Dörfler - fp->_wide_data->_IO_write_base] = '\0';
219*5af32e75SAxel Dörfler *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
220*5af32e75SAxel Dörfler - fp->_wide_data->_IO_write_base);
221*5af32e75SAxel Dörfler }
222*5af32e75SAxel Dörfler
223*5af32e75SAxel Dörfler fp->_wide_data->_IO_buf_base = NULL;
224*5af32e75SAxel Dörfler
225*5af32e75SAxel Dörfler INTUSE(_IO_default_finish) (fp, 0);
226*5af32e75SAxel Dörfler }
227