xref: /haiku/src/system/libroot/posix/glibc/libio/memstream.c (revision 5af32e752606778be5dd7379f319fe43cb3f6b8c)
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