2  * Licensed under a two-clause BSD-style license.
 
   3  * See LICENSE for details.
 
   6 #include "git-compat-util.h"
 
   7 #include "line_buffer.h"
 
  10 #define COPY_BUFFER_LEN 4096
 
  12 int buffer_init(struct line_buffer *buf, const char *filename)
 
  14         buf->infile = filename ? fopen(filename, "r") : stdin;
 
  20 int buffer_fdinit(struct line_buffer *buf, int fd)
 
  22         buf->infile = fdopen(fd, "r");
 
  28 int buffer_tmpfile_init(struct line_buffer *buf)
 
  30         buf->infile = tmpfile();
 
  36 int buffer_deinit(struct line_buffer *buf)
 
  39         if (buf->infile == stdin)
 
  40                 return ferror(buf->infile);
 
  41         err = ferror(buf->infile);
 
  42         err |= fclose(buf->infile);
 
  46 FILE *buffer_tmpfile_rewind(struct line_buffer *buf)
 
  52 long buffer_tmpfile_prepare_to_read(struct line_buffer *buf)
 
  54         long pos = ftell(buf->infile);
 
  56                 return error_errno("ftell error");
 
  57         if (fseek(buf->infile, 0, SEEK_SET))
 
  58                 return error_errno("seek error");
 
  62 int buffer_ferror(struct line_buffer *buf)
 
  64         return ferror(buf->infile);
 
  67 int buffer_read_char(struct line_buffer *buf)
 
  69         return fgetc(buf->infile);
 
  72 /* Read a line without trailing newline. */
 
  73 char *buffer_read_line(struct line_buffer *buf)
 
  76         if (!fgets(buf->line_buffer, sizeof(buf->line_buffer), buf->infile))
 
  77                 /* Error or data exhausted. */
 
  79         end = buf->line_buffer + strlen(buf->line_buffer);
 
  82         else if (feof(buf->infile))
 
  83                 ; /* No newline at end of file.  That's fine. */
 
  87                  * There is probably a saner way to deal with this,
 
  88                  * but for now let's return an error.
 
  91         return buf->line_buffer;
 
  94 size_t buffer_read_binary(struct line_buffer *buf,
 
  95                                 struct strbuf *sb, size_t size)
 
  97         return strbuf_fread(sb, size, buf->infile);
 
 100 off_t buffer_copy_bytes(struct line_buffer *buf, off_t nbytes)
 
 102         char byte_buffer[COPY_BUFFER_LEN];
 
 104         while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
 
 105                 off_t len = nbytes - done;
 
 106                 size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
 
 107                 in = fread(byte_buffer, 1, in, buf->infile);
 
 109                 fwrite(byte_buffer, 1, in, stdout);
 
 111                         return done + buffer_skip_bytes(buf, nbytes - done);
 
 116 off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes)
 
 118         char byte_buffer[COPY_BUFFER_LEN];
 
 120         while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
 
 121                 off_t len = nbytes - done;
 
 122                 size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
 
 123                 done += fread(byte_buffer, 1, in, buf->infile);