Skip to content

Commit

Permalink
vcs-svn: teach line_buffer about temporary files
Browse files Browse the repository at this point in the history
It can sometimes be useful to write information temporarily to file,
to read back later.  These functions allow a program to use the
line_buffer facilities when doing so.

It works like this:

 1. find a unique filename with buffer_tmpfile_init.
 2. rewind with buffer_tmpfile_rewind.  This returns a stdio
    handle for writing.
 3. when finished writing, declare so with
    buffer_tmpfile_prepare_to_read.  The return value indicates
    how many bytes were written.
 4. read whatever portion of the file is needed.
 5. if finished, remove the temporary file with buffer_deinit.
    otherwise, go back to step 2,

The svn support would use this to buffer the postimage from delta
application until the length is known and fast-import can receive
the resulting blob.

Based-on-patch-by: David Barr <david.barr@cordelta.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
  • Loading branch information
Jonathan Nieder committed Feb 26, 2011
1 parent cb3f87c commit b1c9b79
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
24 changes: 24 additions & 0 deletions vcs-svn/line_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ int buffer_fdinit(struct line_buffer *buf, int fd)
return 0;
}

int buffer_tmpfile_init(struct line_buffer *buf)
{
buf->infile = tmpfile();
if (!buf->infile)
return -1;
return 0;
}

int buffer_deinit(struct line_buffer *buf)
{
int err;
Expand All @@ -35,6 +43,22 @@ int buffer_deinit(struct line_buffer *buf)
return err;
}

FILE *buffer_tmpfile_rewind(struct line_buffer *buf)
{
rewind(buf->infile);
return buf->infile;
}

long buffer_tmpfile_prepare_to_read(struct line_buffer *buf)
{
long pos = ftell(buf->infile);
if (pos < 0)
return error("ftell error: %s", strerror(errno));
if (fseek(buf->infile, 0, SEEK_SET))
return error("seek error: %s", strerror(errno));
return pos;
}

int buffer_read_char(struct line_buffer *buf)
{
return fgetc(buf->infile);
Expand Down
7 changes: 6 additions & 1 deletion vcs-svn/line_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ struct line_buffer {
int buffer_init(struct line_buffer *buf, const char *filename);
int buffer_fdinit(struct line_buffer *buf, int fd);
int buffer_deinit(struct line_buffer *buf);
void buffer_reset(struct line_buffer *buf);

int buffer_tmpfile_init(struct line_buffer *buf);
FILE *buffer_tmpfile_rewind(struct line_buffer *buf); /* prepare to write. */
long buffer_tmpfile_prepare_to_read(struct line_buffer *buf);

char *buffer_read_line(struct line_buffer *buf);
char *buffer_read_string(struct line_buffer *buf, uint32_t len);
int buffer_read_char(struct line_buffer *buf);
void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t len);
void buffer_copy_bytes(struct line_buffer *buf, uint32_t len);
void buffer_skip_bytes(struct line_buffer *buf, uint32_t len);
void buffer_reset(struct line_buffer *buf);

#endif
22 changes: 22 additions & 0 deletions vcs-svn/line_buffer.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,28 @@ The calling program:
When finished, the caller can use `buffer_reset` to deallocate
resources.

Using temporary files
---------------------

Temporary files provide a place to store data that should not outlive
the calling program. A program

- initializes a `struct line_buffer` to LINE_BUFFER_INIT
- requests a temporary file with `buffer_tmpfile_init`
- acquires an output handle by calling `buffer_tmpfile_rewind`
- uses standard I/O functions like `fprintf` and `fwrite` to fill
the temporary file
- declares writing is over with `buffer_tmpfile_prepare_to_read`
- can re-read what was written with `buffer_read_line`,
`buffer_read_string`, and so on
- can reuse the temporary file by calling `buffer_tmpfile_rewind`
again
- removes the temporary file with `buffer_deinit`, perhaps to
reuse the line_buffer for some other file.

When finished, the calling program can use `buffer_reset` to deallocate
resources.

Functions
---------

Expand Down

0 comments on commit b1c9b79

Please sign in to comment.