[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
new module 'freadptr'
From: |
Bruno Haible |
Subject: |
new module 'freadptr' |
Date: |
Thu, 28 Feb 2008 13:18:51 +0100 |
User-agent: |
KMail/1.5.4 |
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 <address@hidden>
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
- new module 'freadptr',
Bruno Haible <=