1*5af32e75SAxel Dörfler /* Copyright (C) 1993, 1997-2000, 2001, 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 As a special exception, if you link the code in this file with
20*5af32e75SAxel Dörfler files compiled with a GNU compiler to produce an executable,
21*5af32e75SAxel Dörfler that does not cause the resulting executable to be covered by
22*5af32e75SAxel Dörfler the GNU Lesser General Public License. This exception does not
23*5af32e75SAxel Dörfler however invalidate any other reasons why the executable file
24*5af32e75SAxel Dörfler might be covered by the GNU Lesser General Public License.
25*5af32e75SAxel Dörfler This exception applies to code released by its copyright holders
26*5af32e75SAxel Dörfler in files containing the exception. */
27*5af32e75SAxel Dörfler
28*5af32e75SAxel Dörfler #include "libioP.h"
29*5af32e75SAxel Dörfler #include "strfile.h"
30*5af32e75SAxel Dörfler #include <string.h>
31*5af32e75SAxel Dörfler #include <stdio_ext.h>
32*5af32e75SAxel Dörfler
33*5af32e75SAxel Dörfler #if 0
34*5af32e75SAxel Dörfler /* The following definitions are for exposition only.
35*5af32e75SAxel Dörfler They map the terminology used in the ANSI/ISO C++ draft standard
36*5af32e75SAxel Dörfler to the implementation. */
37*5af32e75SAxel Dörfler
38*5af32e75SAxel Dörfler /* allocated: set when a dynamic array object has been allocated, and
39*5af32e75SAxel Dörfler hence should be freed by the destructor for the strstreambuf object. */
40*5af32e75SAxel Dörfler #define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
41*5af32e75SAxel Dörfler
42*5af32e75SAxel Dörfler /* constant: set when the array object has const elements,
43*5af32e75SAxel Dörfler so the output sequence cannot be written. */
44*5af32e75SAxel Dörfler #define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
45*5af32e75SAxel Dörfler
46*5af32e75SAxel Dörfler /* alsize: the suggested minimum size for a dynamic array object. */
47*5af32e75SAxel Dörfler #define ALSIZE(FP) ??? /* not stored */
48*5af32e75SAxel Dörfler
49*5af32e75SAxel Dörfler /* palloc: points to the function to call to allocate a dynamic array object.*/
50*5af32e75SAxel Dörfler #define PALLOC(FP) \
51*5af32e75SAxel Dörfler ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
52*5af32e75SAxel Dörfler
53*5af32e75SAxel Dörfler /* pfree: points to the function to call to free a dynamic array object. */
54*5af32e75SAxel Dörfler #define PFREE(FP) \
55*5af32e75SAxel Dörfler ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
56*5af32e75SAxel Dörfler
57*5af32e75SAxel Dörfler #endif
58*5af32e75SAxel Dörfler
59*5af32e75SAxel Dörfler #ifdef TODO
60*5af32e75SAxel Dörfler /* An "unbounded buffer" is when a buffer is supplied, but with no
61*5af32e75SAxel Dörfler specified length. An example is the buffer argument to sprintf.
62*5af32e75SAxel Dörfler */
63*5af32e75SAxel Dörfler #endif
64*5af32e75SAxel Dörfler
65*5af32e75SAxel Dörfler void
_IO_str_init_static(sf,ptr,size,pstart)66*5af32e75SAxel Dörfler _IO_str_init_static (sf, ptr, size, pstart)
67*5af32e75SAxel Dörfler _IO_strfile *sf;
68*5af32e75SAxel Dörfler char *ptr;
69*5af32e75SAxel Dörfler int size;
70*5af32e75SAxel Dörfler char *pstart;
71*5af32e75SAxel Dörfler {
72*5af32e75SAxel Dörfler _IO_FILE *fp = &sf->_sbf._f;
73*5af32e75SAxel Dörfler
74*5af32e75SAxel Dörfler if (size == 0)
75*5af32e75SAxel Dörfler size = strlen (ptr);
76*5af32e75SAxel Dörfler else if (size < 0)
77*5af32e75SAxel Dörfler {
78*5af32e75SAxel Dörfler /* If size is negative 'the characters are assumed to
79*5af32e75SAxel Dörfler continue indefinitely.' This is kind of messy ... */
80*5af32e75SAxel Dörfler int s;
81*5af32e75SAxel Dörfler size = 512;
82*5af32e75SAxel Dörfler /* Try increasing powers of 2, as long as we don't wrap around. */
83*5af32e75SAxel Dörfler for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
84*5af32e75SAxel Dörfler size = s;
85*5af32e75SAxel Dörfler /* Try increasing size as much as we can without wrapping around. */
86*5af32e75SAxel Dörfler for (s = size >> 1; s > 0; s >>= 1)
87*5af32e75SAxel Dörfler {
88*5af32e75SAxel Dörfler if (ptr + size + s > ptr)
89*5af32e75SAxel Dörfler size += s;
90*5af32e75SAxel Dörfler }
91*5af32e75SAxel Dörfler }
92*5af32e75SAxel Dörfler INTUSE(_IO_setb) (fp, ptr, ptr + size, 0);
93*5af32e75SAxel Dörfler
94*5af32e75SAxel Dörfler fp->_IO_write_base = ptr;
95*5af32e75SAxel Dörfler fp->_IO_read_base = ptr;
96*5af32e75SAxel Dörfler fp->_IO_read_ptr = ptr;
97*5af32e75SAxel Dörfler if (pstart)
98*5af32e75SAxel Dörfler {
99*5af32e75SAxel Dörfler fp->_IO_write_ptr = pstart;
100*5af32e75SAxel Dörfler fp->_IO_write_end = ptr + size;
101*5af32e75SAxel Dörfler fp->_IO_read_end = pstart;
102*5af32e75SAxel Dörfler }
103*5af32e75SAxel Dörfler else
104*5af32e75SAxel Dörfler {
105*5af32e75SAxel Dörfler fp->_IO_write_ptr = ptr;
106*5af32e75SAxel Dörfler fp->_IO_write_end = ptr;
107*5af32e75SAxel Dörfler fp->_IO_read_end = ptr+size;
108*5af32e75SAxel Dörfler }
109*5af32e75SAxel Dörfler /* A null _allocate_buffer function flags the strfile as being static. */
110*5af32e75SAxel Dörfler sf->_s._allocate_buffer = (_IO_alloc_type) 0;
111*5af32e75SAxel Dörfler }
112*5af32e75SAxel Dörfler INTDEF(_IO_str_init_static)
113*5af32e75SAxel Dörfler
114*5af32e75SAxel Dörfler void
115*5af32e75SAxel Dörfler _IO_str_init_readonly (sf, ptr, size)
116*5af32e75SAxel Dörfler _IO_strfile *sf;
117*5af32e75SAxel Dörfler const char *ptr;
118*5af32e75SAxel Dörfler int size;
119*5af32e75SAxel Dörfler {
120*5af32e75SAxel Dörfler INTUSE(_IO_str_init_static) (sf, (char *) ptr, size, NULL);
121*5af32e75SAxel Dörfler sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
122*5af32e75SAxel Dörfler }
123*5af32e75SAxel Dörfler
124*5af32e75SAxel Dörfler int
_IO_str_overflow(fp,c)125*5af32e75SAxel Dörfler _IO_str_overflow (fp, c)
126*5af32e75SAxel Dörfler _IO_FILE *fp;
127*5af32e75SAxel Dörfler int c;
128*5af32e75SAxel Dörfler {
129*5af32e75SAxel Dörfler int flush_only = c == EOF;
130*5af32e75SAxel Dörfler _IO_size_t pos;
131*5af32e75SAxel Dörfler if (fp->_flags & _IO_NO_WRITES)
132*5af32e75SAxel Dörfler return flush_only ? 0 : EOF;
133*5af32e75SAxel Dörfler if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
134*5af32e75SAxel Dörfler {
135*5af32e75SAxel Dörfler fp->_flags |= _IO_CURRENTLY_PUTTING;
136*5af32e75SAxel Dörfler fp->_IO_write_ptr = fp->_IO_read_ptr;
137*5af32e75SAxel Dörfler fp->_IO_read_ptr = fp->_IO_read_end;
138*5af32e75SAxel Dörfler }
139*5af32e75SAxel Dörfler pos = fp->_IO_write_ptr - fp->_IO_write_base;
140*5af32e75SAxel Dörfler if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
141*5af32e75SAxel Dörfler {
142*5af32e75SAxel Dörfler if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
143*5af32e75SAxel Dörfler return EOF;
144*5af32e75SAxel Dörfler else
145*5af32e75SAxel Dörfler {
146*5af32e75SAxel Dörfler char *new_buf;
147*5af32e75SAxel Dörfler char *old_buf = fp->_IO_buf_base;
148*5af32e75SAxel Dörfler _IO_size_t new_size = 2 * _IO_blen (fp) + 100;
149*5af32e75SAxel Dörfler new_buf
150*5af32e75SAxel Dörfler = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
151*5af32e75SAxel Dörfler if (new_buf == NULL)
152*5af32e75SAxel Dörfler {
153*5af32e75SAxel Dörfler /* __ferror(fp) = 1; */
154*5af32e75SAxel Dörfler return EOF;
155*5af32e75SAxel Dörfler }
156*5af32e75SAxel Dörfler if (old_buf)
157*5af32e75SAxel Dörfler {
158*5af32e75SAxel Dörfler memcpy (new_buf, old_buf, _IO_blen (fp));
159*5af32e75SAxel Dörfler (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
160*5af32e75SAxel Dörfler /* Make sure _IO_setb won't try to delete _IO_buf_base. */
161*5af32e75SAxel Dörfler fp->_IO_buf_base = NULL;
162*5af32e75SAxel Dörfler }
163*5af32e75SAxel Dörfler #if 0
164*5af32e75SAxel Dörfler if (lenp == &LEN(fp)) /* use '\0'-filling */
165*5af32e75SAxel Dörfler memset (new_buf + pos, 0, blen() - pos);
166*5af32e75SAxel Dörfler #endif
167*5af32e75SAxel Dörfler INTUSE(_IO_setb) (fp, new_buf, new_buf + new_size, 1);
168*5af32e75SAxel Dörfler fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
169*5af32e75SAxel Dörfler fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
170*5af32e75SAxel Dörfler fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
171*5af32e75SAxel Dörfler fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
172*5af32e75SAxel Dörfler
173*5af32e75SAxel Dörfler fp->_IO_write_base = new_buf;
174*5af32e75SAxel Dörfler fp->_IO_write_end = fp->_IO_buf_end;
175*5af32e75SAxel Dörfler }
176*5af32e75SAxel Dörfler }
177*5af32e75SAxel Dörfler
178*5af32e75SAxel Dörfler if (!flush_only)
179*5af32e75SAxel Dörfler *fp->_IO_write_ptr++ = (unsigned char) c;
180*5af32e75SAxel Dörfler if (fp->_IO_write_ptr > fp->_IO_read_end)
181*5af32e75SAxel Dörfler fp->_IO_read_end = fp->_IO_write_ptr;
182*5af32e75SAxel Dörfler return c;
183*5af32e75SAxel Dörfler }
184*5af32e75SAxel Dörfler INTDEF(_IO_str_overflow)
185*5af32e75SAxel Dörfler
186*5af32e75SAxel Dörfler int
187*5af32e75SAxel Dörfler _IO_str_underflow (fp)
188*5af32e75SAxel Dörfler _IO_FILE *fp;
189*5af32e75SAxel Dörfler {
190*5af32e75SAxel Dörfler if (fp->_IO_write_ptr > fp->_IO_read_end)
191*5af32e75SAxel Dörfler fp->_IO_read_end = fp->_IO_write_ptr;
192*5af32e75SAxel Dörfler if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
193*5af32e75SAxel Dörfler {
194*5af32e75SAxel Dörfler fp->_flags &= ~_IO_CURRENTLY_PUTTING;
195*5af32e75SAxel Dörfler fp->_IO_read_ptr = fp->_IO_write_ptr;
196*5af32e75SAxel Dörfler fp->_IO_write_ptr = fp->_IO_write_end;
197*5af32e75SAxel Dörfler }
198*5af32e75SAxel Dörfler if (fp->_IO_read_ptr < fp->_IO_read_end)
199*5af32e75SAxel Dörfler return *((unsigned char *) fp->_IO_read_ptr);
200*5af32e75SAxel Dörfler else
201*5af32e75SAxel Dörfler return EOF;
202*5af32e75SAxel Dörfler }
203*5af32e75SAxel Dörfler INTDEF(_IO_str_underflow)
204*5af32e75SAxel Dörfler
205*5af32e75SAxel Dörfler /* The size of the valid part of the buffer. */
206*5af32e75SAxel Dörfler
207*5af32e75SAxel Dörfler _IO_ssize_t
208*5af32e75SAxel Dörfler _IO_str_count (fp)
209*5af32e75SAxel Dörfler _IO_FILE *fp;
210*5af32e75SAxel Dörfler {
211*5af32e75SAxel Dörfler return ((fp->_IO_write_ptr > fp->_IO_read_end
212*5af32e75SAxel Dörfler ? fp->_IO_write_ptr : fp->_IO_read_end)
213*5af32e75SAxel Dörfler - fp->_IO_read_base);
214*5af32e75SAxel Dörfler }
215*5af32e75SAxel Dörfler
216*5af32e75SAxel Dörfler _IO_off64_t
_IO_str_seekoff(fp,offset,dir,mode)217*5af32e75SAxel Dörfler _IO_str_seekoff (fp, offset, dir, mode)
218*5af32e75SAxel Dörfler _IO_FILE *fp;
219*5af32e75SAxel Dörfler _IO_off64_t offset;
220*5af32e75SAxel Dörfler int dir;
221*5af32e75SAxel Dörfler int mode;
222*5af32e75SAxel Dörfler {
223*5af32e75SAxel Dörfler _IO_off64_t new_pos;
224*5af32e75SAxel Dörfler
225*5af32e75SAxel Dörfler if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
226*5af32e75SAxel Dörfler mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
227*5af32e75SAxel Dörfler
228*5af32e75SAxel Dörfler if (mode == 0)
229*5af32e75SAxel Dörfler {
230*5af32e75SAxel Dörfler /* Don't move any pointers. But there is no clear indication what
231*5af32e75SAxel Dörfler mode FP is in. Let's guess. */
232*5af32e75SAxel Dörfler if (fp->_IO_file_flags & _IO_NO_WRITES)
233*5af32e75SAxel Dörfler new_pos = fp->_IO_read_ptr - fp->_IO_read_base;
234*5af32e75SAxel Dörfler else
235*5af32e75SAxel Dörfler new_pos = fp->_IO_write_ptr - fp->_IO_write_base;
236*5af32e75SAxel Dörfler }
237*5af32e75SAxel Dörfler else
238*5af32e75SAxel Dörfler {
239*5af32e75SAxel Dörfler _IO_ssize_t cur_size = _IO_str_count(fp);
240*5af32e75SAxel Dörfler new_pos = EOF;
241*5af32e75SAxel Dörfler
242*5af32e75SAxel Dörfler /* Move the get pointer, if requested. */
243*5af32e75SAxel Dörfler if (mode & _IOS_INPUT)
244*5af32e75SAxel Dörfler {
245*5af32e75SAxel Dörfler switch (dir)
246*5af32e75SAxel Dörfler {
247*5af32e75SAxel Dörfler case _IO_seek_end:
248*5af32e75SAxel Dörfler offset += cur_size;
249*5af32e75SAxel Dörfler break;
250*5af32e75SAxel Dörfler case _IO_seek_cur:
251*5af32e75SAxel Dörfler offset += fp->_IO_read_ptr - fp->_IO_read_base;
252*5af32e75SAxel Dörfler break;
253*5af32e75SAxel Dörfler default: /* case _IO_seek_set: */
254*5af32e75SAxel Dörfler break;
255*5af32e75SAxel Dörfler }
256*5af32e75SAxel Dörfler if (offset < 0 || (_IO_ssize_t) offset > cur_size)
257*5af32e75SAxel Dörfler return EOF;
258*5af32e75SAxel Dörfler fp->_IO_read_ptr = fp->_IO_read_base + offset;
259*5af32e75SAxel Dörfler fp->_IO_read_end = fp->_IO_read_base + cur_size;
260*5af32e75SAxel Dörfler new_pos = offset;
261*5af32e75SAxel Dörfler }
262*5af32e75SAxel Dörfler
263*5af32e75SAxel Dörfler /* Move the put pointer, if requested. */
264*5af32e75SAxel Dörfler if (mode & _IOS_OUTPUT)
265*5af32e75SAxel Dörfler {
266*5af32e75SAxel Dörfler switch (dir)
267*5af32e75SAxel Dörfler {
268*5af32e75SAxel Dörfler case _IO_seek_end:
269*5af32e75SAxel Dörfler offset += cur_size;
270*5af32e75SAxel Dörfler break;
271*5af32e75SAxel Dörfler case _IO_seek_cur:
272*5af32e75SAxel Dörfler offset += fp->_IO_write_ptr - fp->_IO_write_base;
273*5af32e75SAxel Dörfler break;
274*5af32e75SAxel Dörfler default: /* case _IO_seek_set: */
275*5af32e75SAxel Dörfler break;
276*5af32e75SAxel Dörfler }
277*5af32e75SAxel Dörfler if (offset < 0 || (_IO_ssize_t) offset > cur_size)
278*5af32e75SAxel Dörfler return EOF;
279*5af32e75SAxel Dörfler fp->_IO_write_ptr = fp->_IO_write_base + offset;
280*5af32e75SAxel Dörfler new_pos = offset;
281*5af32e75SAxel Dörfler }
282*5af32e75SAxel Dörfler }
283*5af32e75SAxel Dörfler return new_pos;
284*5af32e75SAxel Dörfler }
285*5af32e75SAxel Dörfler INTDEF(_IO_str_seekoff)
286*5af32e75SAxel Dörfler
287*5af32e75SAxel Dörfler int
288*5af32e75SAxel Dörfler _IO_str_pbackfail (fp, c)
289*5af32e75SAxel Dörfler _IO_FILE *fp;
290*5af32e75SAxel Dörfler int c;
291*5af32e75SAxel Dörfler {
292*5af32e75SAxel Dörfler if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
293*5af32e75SAxel Dörfler return EOF;
294*5af32e75SAxel Dörfler return INTUSE(_IO_default_pbackfail) (fp, c);
295*5af32e75SAxel Dörfler }
296*5af32e75SAxel Dörfler INTDEF(_IO_str_pbackfail)
297*5af32e75SAxel Dörfler
298*5af32e75SAxel Dörfler void
299*5af32e75SAxel Dörfler _IO_str_finish (fp, dummy)
300*5af32e75SAxel Dörfler _IO_FILE *fp;
301*5af32e75SAxel Dörfler int dummy;
302*5af32e75SAxel Dörfler {
303*5af32e75SAxel Dörfler if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
304*5af32e75SAxel Dörfler (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
305*5af32e75SAxel Dörfler fp->_IO_buf_base = NULL;
306*5af32e75SAxel Dörfler
307*5af32e75SAxel Dörfler INTUSE(_IO_default_finish) (fp, 0);
308*5af32e75SAxel Dörfler }
309*5af32e75SAxel Dörfler
310*5af32e75SAxel Dörfler struct _IO_jump_t _IO_str_jumps =
311*5af32e75SAxel Dörfler {
312*5af32e75SAxel Dörfler JUMP_INIT_DUMMY,
313*5af32e75SAxel Dörfler JUMP_INIT(finish, _IO_str_finish),
314*5af32e75SAxel Dörfler JUMP_INIT(overflow, INTUSE(_IO_str_overflow)),
315*5af32e75SAxel Dörfler JUMP_INIT(underflow, INTUSE(_IO_str_underflow)),
316*5af32e75SAxel Dörfler JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
317*5af32e75SAxel Dörfler JUMP_INIT(pbackfail, INTUSE(_IO_str_pbackfail)),
318*5af32e75SAxel Dörfler JUMP_INIT(xsputn, INTUSE(_IO_default_xsputn)),
319*5af32e75SAxel Dörfler JUMP_INIT(xsgetn, INTUSE(_IO_default_xsgetn)),
320*5af32e75SAxel Dörfler JUMP_INIT(seekoff, INTUSE(_IO_str_seekoff)),
321*5af32e75SAxel Dörfler JUMP_INIT(seekpos, _IO_default_seekpos),
322*5af32e75SAxel Dörfler JUMP_INIT(setbuf, _IO_default_setbuf),
323*5af32e75SAxel Dörfler JUMP_INIT(sync, _IO_default_sync),
324*5af32e75SAxel Dörfler JUMP_INIT(doallocate, INTUSE(_IO_default_doallocate)),
325*5af32e75SAxel Dörfler JUMP_INIT(read, _IO_default_read),
326*5af32e75SAxel Dörfler JUMP_INIT(write, _IO_default_write),
327*5af32e75SAxel Dörfler JUMP_INIT(seek, _IO_default_seek),
328*5af32e75SAxel Dörfler JUMP_INIT(close, _IO_default_close),
329*5af32e75SAxel Dörfler JUMP_INIT(stat, _IO_default_stat),
330*5af32e75SAxel Dörfler JUMP_INIT(showmanyc, _IO_default_showmanyc),
331*5af32e75SAxel Dörfler JUMP_INIT(imbue, _IO_default_imbue)
332*5af32e75SAxel Dörfler };
333