|
|
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.