[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gnulib] strfile: new module
From: |
Bruno Haible |
Subject: |
Re: [bug-gnulib] strfile: new module |
Date: |
Tue, 30 May 2006 21:59:52 +0200 |
User-agent: |
KMail/1.5 |
Simon Josefsson wrote:
> This is used in GnuTLS, and I need it in Shishi now, so I thought that
> it should be a module. What do you think?
I agree it's common enough that we can use it in gnulib.
> Possibly, there should be a xstrfile too, that uses xrealloc...
Yes.
> Index: modules/strfile
I would call the module 'read-file' and the function 'read_file'. So that it's
possible to add a module 'write_file' if needed, and for consistency with the
'copy-file' module.
> + do {
In GNU style the brace goes on the next line.
> + tmp = realloc (out, pos + BUFSIZ);
Quadratic runtime behaviour: if you don't have particular luck with the
realloc()
implementation, for large files, this loop will spend most of its time in
realloc(), copying memory around.
> + if (!(feof (fh) && fclose (fh)))
Missing treatment of the ferror (fh) case.
As additional input, find attached some similar (unpolished) code I wrote long
ago
in the past. The good point about a function that takes a FILE stream rather
than a filename as argument is that the caller has more liberty to decide
about O_TEXT / O_BINARY and about what to do when the file does not exist. The
downside is, of course, that it's not so immediate to use this function. But
maybe the module can provide both: fread_file that reads from a stream, and
read_file that takes a filename?
Bruno
=============================================================================
/* Read the contents of an input stream, and return it, terminated with a NUL
byte. */
char* fread_file (FILE* stream)
{
#define BUFSIZE 4096
char* buf = NULL;
int alloc = 0;
int size = 0;
int count;
while (!feof(stream))
{
if (size + BUFSIZE > alloc)
{
alloc = alloc + alloc/2;
if (alloc < size + BUFSIZE)
alloc = size + BUFSIZE;
buf = realloc(buf,alloc);
if (buf == NULL)
{
fprintf(stderr,"out of memory\n");
exit(1);
}
}
count = fread(buf+size,1,BUFSIZE,stream);
if (count == 0)
{
if (ferror(stream))
{
perror("fread");
exit(1);
}
}
else
{
size += count;
}
}
buf = realloc(buf,size+1);
if (buf == NULL)
{
fprintf(stderr,"out of memory\n");
exit(1);
}
buf[size] = '\0';
return buf;
#undef BUFSIZE
}
/* Write a piece of memory to an output stream. */
void fwrite_file (FILE* stream, char* buf, int size)
{
while (size > 0)
{
int count = fwrite(buf,1,size,stream);
if (count == 0)
{
perror("fwrite");
exit(1);
}
buf += count; size -= count;
}
}
Re: [bug-gnulib] strfile: new module,
Bruno Haible <=
Re: strfile: new module, Simon Josefsson, 2006/05/31
Re: strfile: new module, Jim Meyering, 2006/05/31