Hi, Here's one more module in the "stdio internals" series. freadptr (stream) returns a pointer to the read buffer of stream.
For example, if you want to read the contents of the stream up to but not including the next newline into an obstack, here's the naïve code: struct obstack *obs = ...; FILE *fp = ...; for (;;) { int ch = getc_unlocked (fp); if (ch == EOF || ch == '\n') break; obstack_1grow (obs, ch); } Optimization using fread_unlocked is not possible, because we cannot push back the read bytes after the newline back to the stream. And here's the code with freadptr. It does a maximum of operations "en bloc": memchr and obstack_grow (which expands into a memcpy call). struct obstack *obs = ...; FILE *fp = ...; for (;;) { size_t available = freadahead (fp); if (available > 0) { const char *buf = freadptr (fp); const char *nl = (const char *) memchr (buf, '\n', n); if (nl != NULL) { obstack_grow (obs, buf, nl - buf); fseek (fp, nl - buf + 1, SEEK_CUR); } else { obstack_grow (obs, buf, available); fseek (fp, available, SEEK_CUR); } } else { int ch = getc (fp); if (ch == EOF || ch == '\n') break; obstack_1grow (obs, ch); } } 2008-02-28 Bruno Haible <[EMAIL PROTECTED]> New module 'freadptr'. * modules/freadptr: New file. * lib/freadptr.h: New file. * lib/freadptr.c: New file. * MODULES.html.sh (File stream based Input/Output): Add freadptr. ============================ modules/freadptr ============================== Description: freadptr() function: Pointer to the input buffer of a stream. Files: lib/freadptr.h lib/freadptr.c Depends-on: configure.ac: Makefile.am: lib_SOURCES += freadptr.c Include: "freadptr.h" License: LGPL Maintainer: Bruno Haible ============================= lib/freadptr.h =============================== /* Retrieve information about a FILE stream. Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stddef.h> #include <stdio.h> #ifdef __cplusplus extern "C" { #endif /* Assuming the stream STREAM is open for reading: Return a pointer to the input buffer of STREAM. If freadahead (STREAM) > 0, the result is a pointer to freadahead (STREAM) bytes. If freadahead (STREAM) == 0, the result is not usable; it may be NULL. In this case, you should use getc (STREAM), fgetc (STREAM), or fread (..., STREAM) to access the input from STREAM. The resulting pointer becomes invalid upon any operation on STREAM. STREAM must not be wide-character oriented. */ extern const char * freadptr (FILE *stream); #ifdef __cplusplus } #endif ============================= lib/freadptr.c =============================== /* Retrieve information about a FILE stream. Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <config.h> /* Specification. */ #include "freadahead.h" const char * freadptr (FILE *fp) { /* Keep this code in sync with freadahead! */ #if defined _IO_ferror_unlocked /* GNU libc, BeOS */ return (const char *) fp->_IO_read_ptr; #elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ return (const char *) fp->_p; #elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */ # if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ # define fp_ ((struct { unsigned char *_ptr; \ unsigned char *_base; \ unsigned char *_end; \ long _cnt; \ int _file; \ unsigned int _flag; \ } *) fp) return (const char *) fp_->_ptr; # else return (const char *) fp->_ptr; # endif #elif defined __UCLIBC__ /* uClibc */ # ifdef __STDIO_BUFFERS return (const char *) fp->__bufpos; # else return NULL; # endif #elif defined __QNX__ /* QNX */ return (const char *) fp->_Next; #else #error "Please port gnulib freadptr.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib." #endif } ============================================================================ *** MODULES.html.sh.orig 2008-02-28 13:00:54.000000000 +0100 --- MODULES.html.sh 2008-02-28 12:59:02.000000000 +0100 *************** *** 2282,2287 **** --- 2282,2288 ---- func_module freadable func_module freadahead func_module freading + func_module freadptr func_module fwritable func_module fwriting func_module getpass