Declare wcs functions only if compiling with MBS_SUPPORT. Don't use #elif for tradi...
[glibc.git] / libio / wstrops.c
blob92d7f2fe951ebf5dbeef5fc9211c5fc401f43a36
1 /* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
28 #include "strfile.h"
29 #include "libioP.h"
30 #include <string.h>
31 #include <wchar.h>
33 #if 0
34 /* The following definitions are for exposition only.
35 They map the terminology used in the ANSI/ISO C++ draft standard
36 to the implementation. */
38 /* allocated: set when a dynamic array object has been allocated, and
39 hence should be freed by the destructor for the strstreambuf object. */
40 #define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
42 /* constant: set when the array object has const elements,
43 so the output sequence cannot be written. */
44 #define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
46 /* alsize: the suggested minimum size for a dynamic array object. */
47 #define ALSIZE(FP) ??? /* not stored */
49 /* palloc: points to the function to call to allocate a dynamic array object.*/
50 #define PALLOC(FP) \
51 ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
53 /* pfree: points to the function to call to free a dynamic array object. */
54 #define PFREE(FP) \
55 ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
57 #endif
59 #ifdef TODO
60 /* An "unbounded buffer" is when a buffer is supplied, but with no
61 specified length. An example is the buffer argument to sprintf.
63 #endif
65 void
66 _IO_wstr_init_static (fp, ptr, size, pstart)
67 _IO_FILE *fp;
68 wchar_t *ptr;
69 int size;
70 wchar_t *pstart;
72 if (size == 0)
73 size = __wcslen (ptr);
74 else if (size < 0)
76 /* If size is negative 'the characters are assumed to
77 continue indefinitely.' This is kind of messy ... */
78 int s;
79 size = 512;
80 /* Try increasing powers of 2, as long as we don't wrap around. */
81 for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
82 size = s;
83 /* Try increasing size as much as we can without wrapping around. */
84 for (s = size >> 1; s > 0; s >>= 1)
86 if (ptr + size + s > ptr)
87 size += s;
90 _IO_wsetb (fp, ptr, ptr + size, 0);
92 fp->_wide_data->_IO_write_base = ptr;
93 fp->_wide_data->_IO_read_base = ptr;
94 fp->_wide_data->_IO_read_ptr = ptr;
95 if (pstart)
97 fp->_wide_data->_IO_write_ptr = pstart;
98 fp->_wide_data->_IO_write_end = ptr + size;
99 fp->_wide_data->_IO_read_end = pstart;
101 else
103 fp->_wide_data->_IO_write_ptr = ptr;
104 fp->_wide_data->_IO_write_end = ptr;
105 fp->_wide_data->_IO_read_end = ptr + size;
107 /* A null _allocate_buffer function flags the strfile as being static. */
108 (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
111 void
112 _IO_wstr_init_readonly (fp, ptr, size)
113 _IO_FILE *fp;
114 const char *ptr;
115 int size;
117 _IO_wstr_init_static (fp, (wchar_t *) ptr, size, NULL);
118 fp->_IO_file_flags |= _IO_NO_WRITES;
121 _IO_wint_t
122 _IO_wstr_overflow (fp, c)
123 _IO_FILE *fp;
124 _IO_wint_t c;
126 int flush_only = c == WEOF;
127 _IO_size_t pos;
128 if (fp->_flags & _IO_NO_WRITES)
129 return flush_only ? 0 : WEOF;
130 if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
132 fp->_flags |= _IO_CURRENTLY_PUTTING;
133 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
134 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
136 pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base;
137 if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only))
139 if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
140 return WEOF;
141 else
143 wchar_t *new_buf;
144 wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
145 _IO_size_t new_size = 2 * _IO_wblen (fp) + 100;
146 new_buf
147 = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
148 * sizeof (wchar_t));
149 if (new_buf == NULL)
151 /* __ferror(fp) = 1; */
152 return WEOF;
154 if (old_buf)
156 __wmemcpy (new_buf, old_buf, _IO_wblen (fp));
157 (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
158 /* Make sure _IO_setb won't try to delete _IO_buf_base. */
159 fp->_wide_data->_IO_buf_base = NULL;
161 _IO_wsetb (fp, new_buf, new_buf + new_size, 1);
162 fp->_wide_data->_IO_read_base =
163 new_buf + (fp->_wide_data->_IO_read_base - old_buf);
164 fp->_wide_data->_IO_read_ptr =
165 new_buf + (fp->_wide_data->_IO_read_ptr - old_buf);
166 fp->_wide_data->_IO_read_end =
167 new_buf + (fp->_wide_data->_IO_read_end - old_buf);
168 fp->_wide_data->_IO_write_ptr =
169 new_buf + (fp->_wide_data->_IO_write_ptr - old_buf);
171 fp->_wide_data->_IO_write_base = new_buf;
172 fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end;
176 if (!flush_only)
177 *fp->_wide_data->_IO_write_ptr++ = c;
178 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
179 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
180 return c;
183 _IO_wint_t
184 _IO_wstr_underflow (fp)
185 _IO_FILE *fp;
187 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
188 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
189 if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
191 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
192 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
193 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_end;
195 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
196 return *fp->_wide_data->_IO_read_ptr;
197 else
198 return WEOF;
201 /* The size of the valid part of the buffer. */
203 _IO_ssize_t
204 _IO_wstr_count (fp)
205 _IO_FILE *fp;
207 return ((fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end
208 ? fp->_wide_data->_IO_write_ptr : fp->_wide_data->_IO_read_end)
209 - fp->_wide_data->_IO_read_base);
212 _IO_off64_t
213 _IO_wstr_seekoff (fp, offset, dir, mode)
214 _IO_FILE *fp;
215 _IO_off64_t offset;
216 int dir;
217 int mode;
219 _IO_off64_t new_pos;
221 if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
222 mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
224 if (mode == 0)
226 /* Don't move any pointers. But there is no clear indication what
227 mode FP is in. Let's guess. */
228 if (fp->_IO_file_flags & _IO_NO_WRITES)
229 new_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base;
230 else
231 new_pos = (fp->_wide_data->_IO_write_ptr
232 - fp->_wide_data->_IO_write_base);
234 else
236 _IO_ssize_t cur_size = _IO_wstr_count (fp);
237 new_pos = EOF;
239 /* Move the get pointer, if requested. */
240 if (mode & _IOS_INPUT)
242 switch (dir)
244 case _IO_seek_end:
245 offset += cur_size;
246 break;
247 case _IO_seek_cur:
248 offset += (fp->_wide_data->_IO_read_ptr
249 - fp->_wide_data->_IO_read_base);
250 break;
251 default: /* case _IO_seek_set: */
252 break;
254 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
255 return EOF;
256 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
257 + offset);
258 fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base
259 + cur_size);
260 new_pos = offset;
263 /* Move the put pointer, if requested. */
264 if (mode & _IOS_OUTPUT)
266 switch (dir)
268 case _IO_seek_end:
269 offset += cur_size;
270 break;
271 case _IO_seek_cur:
272 offset += (fp->_wide_data->_IO_write_ptr
273 - fp->_wide_data->_IO_write_base);
274 break;
275 default: /* case _IO_seek_set: */
276 break;
278 if (offset < 0 || (_IO_ssize_t) offset > cur_size)
279 return EOF;
280 fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base
281 + offset);
282 new_pos = offset;
285 return new_pos;
288 _IO_wint_t
289 _IO_wstr_pbackfail (fp, c)
290 _IO_FILE *fp;
291 _IO_wint_t c;
293 if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
294 return WEOF;
295 return _IO_wdefault_pbackfail (fp, c);
298 void
299 _IO_wstr_finish (fp, dummy)
300 _IO_FILE *fp;
301 int dummy;
303 if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
304 (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
305 fp->_wide_data->_IO_buf_base = NULL;
307 _IO_wdefault_finish (fp, 0);
310 struct _IO_jump_t _IO_wstr_jumps =
312 JUMP_INIT_DUMMY,
313 JUMP_INIT(finish, _IO_wstr_finish),
314 JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow),
315 JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
316 JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
317 JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
318 JUMP_INIT(xsputn, _IO_wdefault_xsputn),
319 JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
320 JUMP_INIT(seekoff, _IO_wstr_seekoff),
321 JUMP_INIT(seekpos, _IO_default_seekpos),
322 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf),
323 JUMP_INIT(sync, _IO_default_sync),
324 JUMP_INIT(doallocate, _IO_wdefault_doallocate),
325 JUMP_INIT(read, _IO_default_read),
326 JUMP_INIT(write, _IO_default_write),
327 JUMP_INIT(seek, _IO_default_seek),
328 JUMP_INIT(close, _IO_default_close),
329 JUMP_INIT(stat, _IO_default_stat),
330 JUMP_INIT(showmanyc, _IO_default_showmanyc),
331 JUMP_INIT(imbue, _IO_default_imbue)