memstream.c
来自「一个C源代码分析器」· C语言 代码 · 共 178 行
C
178 行
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with the GNU C Library; see the file COPYING.LIB. Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA. */#include <ansidecl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>struct memstream_info { char **buffer; size_t *bufsize; };/* Enlarge STREAM's buffer. */static voidDEFUN(enlarge_buffer, (stream, c), register FILE *stream AND int c){ struct memstream_info *info = (struct memstream_info *) stream->__cookie; size_t need; if (stream->__put_limit != stream->__buffer) /* Record how much has actually been written into the buffer. */ *info->bufsize = stream->__bufp - stream->__buffer; if (stream->__target != -1 && stream->__target > *info->bufsize) /* Our target (where the buffer maps to) is always zero except when the user just did a SEEK_END fseek. If he sought within the buffer, we need do nothing and will zero the target below. If he sought past the end of the object, grow and zero-fill the buffer up to the target address. */ need = stream->__target; else need = *info->bufsize + (c == EOF ? 0 : 1); if (stream->__bufsize < need) { /* Enlarge the buffer. */ char *newbuf; if (stream->__bufsize * 2 < need) stream->__bufsize = need; else stream->__bufsize *= 2; newbuf = (char *) realloc ((PTR) stream->__buffer, stream->__bufsize); *info->buffer = newbuf; if (newbuf == NULL) { free ((PTR) stream->__buffer); stream->__buffer = stream->__bufp = stream->__put_limit = stream->__get_limit = NULL; stream->__error = 1; return; } stream->__buffer = newbuf; } stream->__target = stream->__offset = 0; stream->__get_limit = stream->__bufp = stream->__buffer + *info->bufsize; stream->__put_limit = stream->__buffer + stream->__bufsize; need -= stream->__bufp - stream->__buffer; if (c != EOF) --need; if (need > 0) { /* We are extending the buffer after an fseek; zero-fill new space. */ bzero (stream->__bufp, need); stream->__bufp += need; } if (c != EOF) *stream->__bufp++ = (unsigned char) c; else *stream->__bufp = '\0';}/* Seek function for memstreams. There is no external state to munge. */static intDEFUN(seek, (cookie, pos, whence), PTR cookie AND fpos_t *pos AND int whence){ switch (whence) { case SEEK_SET: case SEEK_CUR: return 0; case SEEK_END: /* Return the position relative to the end of the object. fseek has just flushed us, so the info is consistent. */ *pos += *((struct memstream_info *) cookie)->bufsize; return 0; default: __libc_fatal ("memstream::seek called with bogus WHENCE\n"); return -1; }}static intDEFUN(free_info, (cookie), PTR cookie){#if 0 struct memstream_info *info = (struct memstream_info *) cookie; char *buf; buf = (char *) realloc ((PTR) *info->buffer, *info->bufsize); if (buf != NULL) *info->buffer = buf;#endif free (cookie); return 0;}/* Open a stream that writes into a malloc'd buffer that is expanded as necessary. *BUFLOC and *SIZELOC are updated with the buffer's location and the number of characters written on fflush or fclose. */FILE *DEFUN(open_memstream, (bufloc, sizeloc), char **bufloc AND size_t *sizeloc){ FILE *stream; struct memstream_info *info; if (bufloc == NULL || sizeloc == NULL) { errno = EINVAL; return NULL; } stream = fmemopen ((char *) NULL, BUFSIZ, "w+"); if (stream == NULL) return NULL; info = (struct memstream_info *) malloc (sizeof (struct memstream_info)); if (info == NULL) { int save = errno; (void) fclose (stream); errno = save; return NULL; } stream->__room_funcs.__output = enlarge_buffer; stream->__io_funcs.__seek = seek; stream->__io_funcs.__close = free_info; stream->__cookie = (PTR) info; stream->__userbuf = 1; info->buffer = bufloc; info->bufsize = sizeloc; *bufloc = stream->__buffer; return stream;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?