|
|
1.1 root 1: /*
2: Copyright (C) 1993 Free Software Foundation
3:
4: This file is part of the GNU IO Library. This library is free
5: software; you can redistribute it and/or modify it under the
6: terms of the GNU General Public License as published by the
7: Free Software Foundation; either version 2, or (at your option)
8: any later version.
9:
10: This library is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with GNU CC; see the file COPYING. If not, write to
17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18:
19: As a special exception, if you link this library with files
20: compiled with a GNU compiler to produce an executable, this does not cause
21: the resulting executable to be covered by the GNU General Public License.
22: This exception does not however invalidate any other reasons why
23: the executable file might be covered by the GNU General Public License. */
24:
25: #include "strfile.h"
26: #include "libioP.h"
27: #include <string.h>
28:
29: #define LEN(fp) (((_IO_strfile*)(fp))->_s._len)
30:
31: #ifdef TODO
32: /* An "unbounded buffer" is when a buffer is supplied, but with no
33: specified length. An example is the buffer argument to sprintf.
34: */
35: #endif
36:
37: void
38: _IO_str_init_static (fp, ptr, size, pstart)
39: _IO_FILE *fp;
40: char *ptr;
41: int size;
42: char *pstart;
43: {
44: if (size == 0)
45: size = strlen(ptr);
46: else if (size < 0)
47: {
48: /* If size is negative 'the characters are assumed to
49: continue indefinitely.' This is kind of messy ... */
50: #if 1
51: int s;
52: size = 512;
53: /* Try increasing powers of 2, as long as we don't wrap around.
54: This can lose in pathological cases (ptr near the end
55: of the address space). A better solution might be to
56: adjust the size on underflow/overflow. FIXME. */
57: for (s; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
58: size = s;
59: size = s;
60: #else
61: /* The following semi-portable kludge assumes that
62: sizeof(unsigned long) == sizeof(char*). Hence,
63: (unsigned long)(-1) should be the largest possible address. */
64: unsigned long highest = (unsigned long)(-1);
65: /* Pointers are signed on some brain-damaged systems, in
66: which case we divide by two to get the maximum signed address. */
67: if ((char*)highest < ptr)
68: highest >>= 1;
69: size = (char*)highest - ptr;
70: #endif
71: }
72: _IO_setb(fp, ptr, ptr+size, 0);
73:
74: fp->_IO_write_base = ptr;
75: fp->_IO_read_base = ptr;
76: fp->_IO_read_ptr = ptr;
77: if (pstart)
78: {
79: fp->_IO_write_ptr = pstart;
80: fp->_IO_write_end = ptr+size;
81: fp->_IO_read_end = pstart;
82: }
83: else
84: {
85: fp->_IO_write_ptr = ptr;
86: fp->_IO_write_end = ptr;
87: fp->_IO_read_end = ptr+size;
88: }
89: LEN(fp) = size;
90: /* A null _allocate_buffer function flags the strfile as being static. */
91: (((_IO_strfile*)(fp))->_s._allocate_buffer) = (_IO_alloc_type)0;
92: }
93:
94: void
95: _IO_str_init_readonly (fp, ptr, size)
96: _IO_FILE *fp;
97: const char *ptr;
98: int size;
99: {
100: _IO_str_init_static (fp, (char*)ptr, size, NULL);
101: fp->_IO_file_flags |= _IO_NO_WRITES;
102: }
103:
104: int _IO_str_overflow (fp, c)
105: register _IO_FILE* fp;
106: int c;
107: {
108: int flush_only = c == EOF;
109: _IO_size_t pos = fp->_IO_write_ptr - fp->_IO_write_base;
110: _IO_size_t get_pos = fp->_IO_read_ptr - fp->_IO_read_base;
111: if (fp->_flags & _IO_NO_WRITES)
112: return flush_only ? 0 : EOF;
113: if (pos > LEN(fp)) LEN(fp) = pos;
114: if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
115: {
116: pos = get_pos;
117: fp->_flags |= _IO_CURRENTLY_PUTTING;
118: get_pos = LEN(fp);
119: }
120: if (pos >= _IO_blen(fp) + flush_only)
121: {
122: if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
123: {
124: #ifdef TODO
125: if (indefinite size)
126: {
127: fp->_IO_buf_end += 512;
128: }
129: else
130: #endif
131: return EOF;
132: }
133: else
134: {
135: char *new_buf;
136: _IO_size_t new_size = 2 * _IO_blen(fp);
137: new_buf
138: = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
139: if (new_buf == NULL)
140: {
141: /* __ferror(fp) = 1; */
142: return EOF;
143: }
144: memcpy(new_buf, fp->_IO_buf_base, _IO_blen(fp));
145: #if 0
146: if (lenp == &LEN(fp)) /* use '\0'-filling */
147: memset(new_buf + pos, 0, blen() - pos);
148: #endif
149: if (fp->_IO_buf_base)
150: {
151: (*((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
152: /* Make sure _IO_setb won't try to delete _IO_buf_base. */
153: fp->_IO_buf_base = NULL;
154: }
155: _IO_setb(fp, new_buf, new_buf + new_size, 1);
156: fp->_IO_write_base = new_buf;
157: }
158: fp->_IO_write_end = fp->_IO_buf_end;
159: }
160:
161: fp->_IO_write_ptr = fp->_IO_buf_base + pos;
162:
163: fp->_IO_read_base = fp->_IO_buf_base;
164: fp->_IO_read_ptr = fp->_IO_buf_base + get_pos;;
165: fp->_IO_read_end = fp->_IO_buf_base + LEN(fp);;
166:
167: if (!flush_only)
168: *fp->_IO_write_ptr++ = (unsigned char) c;
169: return c;
170: }
171:
172: int
173: _IO_str_underflow (fp)
174: register _IO_FILE* fp;
175: {
176: _IO_size_t ppos = fp->_IO_write_ptr - fp->_IO_write_base;
177: if (ppos > LEN(fp)) LEN(fp) = ppos;
178: if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
179: {
180: fp->_flags &= ~_IO_CURRENTLY_PUTTING;
181: fp->_IO_write_ptr = fp->_IO_write_end;
182: }
183: fp->_IO_read_end = fp->_IO_read_base + LEN(fp);
184: if (fp->_IO_read_ptr < fp->_IO_read_end)
185: return *fp->_IO_read_ptr;
186: else
187: return EOF;
188: }
189:
190: _IO_ssize_t
191: _IO_str_count (fp)
192: register _IO_FILE *fp;
193: {
194: _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
195: if (put_len < ((_IO_strfile*)fp)->_s._len)
196: put_len = ((_IO_strfile*)fp)->_s._len;
197: return put_len;
198: }
199:
200: _IO_pos_t
201: _IO_str_seekoff(fp, offset, mode)
202: register _IO_FILE *fp;
203: _IO_off_t offset;
204: _IO_seekflags mode;
205: {
206: _IO_ssize_t cur_size = _IO_str_count(fp);
207: _IO_pos_t new_pos = EOF;
208: int dir = mode & 3;
209:
210: /* Move the get pointer, if requested. */
211: if (!(mode & _IO_seek_not_in))
212: {
213: switch (dir)
214: {
215: case _IO_seek_end:
216: offset += cur_size;
217: break;
218: case _IO_seek_cur:
219: offset += fp->_IO_read_ptr - fp->_IO_read_base;
220: break;
221: default: /* case _IO_seek_set: */
222: break;
223: }
224: if (offset < 0 || (_IO_size_t)offset > cur_size)
225: return EOF;
226: fp->_IO_read_ptr = fp->_IO_read_base + offset;
227: fp->_IO_read_end = fp->_IO_read_base + cur_size;
228: new_pos = offset;
229: }
230:
231: /* Move the put pointer, if requested. */
232: if (!(mode & _IO_seek_not_out))
233: {
234: switch (dir)
235: {
236: case _IO_seek_end:
237: offset += cur_size;
238: break;
239: case _IO_seek_cur:
240: offset += fp->_IO_write_ptr - fp->_IO_write_base;
241: break;
242: default: /* case _IO_seek_set: */
243: break;
244: }
245: if (offset < 0 || (_IO_size_t)offset > cur_size)
246: return EOF;
247: fp->_IO_write_ptr = fp->_IO_write_base + offset;
248: new_pos = offset;
249: }
250: return new_pos;
251: }
252:
253: int
254: _IO_str_pbackfail(fp, c)
255: register _IO_FILE *fp;
256: int c;
257: {
258: if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
259: return EOF;
260: return _IO_default_pbackfail(fp, c);
261: }
262:
263: void
264: _IO_str_finish(fp)
265: register _IO_FILE* fp;
266: {
267: if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
268: (((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
269: fp->_IO_buf_base = NULL;
270:
271: _IO_default_finish(fp);
272: }
273:
274: struct _IO_jump_t _IO_str_jumps = {
275: _IO_str_overflow,
276: _IO_str_underflow,
277: _IO_default_xsputn,
278: _IO_default_xsgetn,
279: _IO_default_read,
280: _IO_default_write,
281: _IO_default_doallocate,
282: _IO_str_pbackfail,
283: _IO_default_setbuf,
284: _IO_default_sync,
285: _IO_str_finish,
286: _IO_default_close,
287: _IO_default_stat,
288: _IO_default_seek,
289: _IO_str_seekoff,
290: _IO_default_seekpos,
291: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.