[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: new module 'freadptr'
From: |
Jim Meyering |
Subject: |
Re: new module 'freadptr' |
Date: |
Thu, 28 Feb 2008 13:29:13 +0100 |
Bruno Haible <address@hidden> wrote:
> 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).
Looks useful.
> 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);
Surely you meant this:
const char *nl = (const char *) memchr (buf, '\n', available);
> 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);
> }
> }