vcs-svn / line_buffer.con commit Merge branch 'sn/doc-update-index-assume-unchanged' into maint-1.7.3 (eb4e672)
   1/*
   2 * Licensed under a two-clause BSD-style license.
   3 * See LICENSE for details.
   4 */
   5
   6#include "git-compat-util.h"
   7#include "line_buffer.h"
   8#include "obj_pool.h"
   9
  10#define LINE_BUFFER_LEN 10000
  11#define COPY_BUFFER_LEN 4096
  12
  13/* Create memory pool for char sequence of known length */
  14obj_pool_gen(blob, char, 4096)
  15
  16static char line_buffer[LINE_BUFFER_LEN];
  17static char byte_buffer[COPY_BUFFER_LEN];
  18static FILE *infile;
  19
  20int buffer_init(const char *filename)
  21{
  22        infile = filename ? fopen(filename, "r") : stdin;
  23        if (!infile)
  24                return -1;
  25        return 0;
  26}
  27
  28int buffer_deinit(void)
  29{
  30        int err;
  31        if (infile == stdin)
  32                return ferror(infile);
  33        err = ferror(infile);
  34        err |= fclose(infile);
  35        return err;
  36}
  37
  38/* Read a line without trailing newline. */
  39char *buffer_read_line(void)
  40{
  41        char *end;
  42        if (!fgets(line_buffer, sizeof(line_buffer), infile))
  43                /* Error or data exhausted. */
  44                return NULL;
  45        end = line_buffer + strlen(line_buffer);
  46        if (end[-1] == '\n')
  47                end[-1] = '\0';
  48        else if (feof(infile))
  49                ; /* No newline at end of file.  That's fine. */
  50        else
  51                /*
  52                 * Line was too long.
  53                 * There is probably a saner way to deal with this,
  54                 * but for now let's return an error.
  55                 */
  56                return NULL;
  57        return line_buffer;
  58}
  59
  60char *buffer_read_string(uint32_t len)
  61{
  62        char *s;
  63        blob_free(blob_pool.size);
  64        s = blob_pointer(blob_alloc(len + 1));
  65        s[fread(s, 1, len, infile)] = '\0';
  66        return ferror(infile) ? NULL : s;
  67}
  68
  69void buffer_copy_bytes(uint32_t len)
  70{
  71        uint32_t in;
  72        while (len > 0 && !feof(infile) && !ferror(infile)) {
  73                in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
  74                in = fread(byte_buffer, 1, in, infile);
  75                len -= in;
  76                fwrite(byte_buffer, 1, in, stdout);
  77                if (ferror(stdout)) {
  78                        buffer_skip_bytes(len);
  79                        return;
  80                }
  81        }
  82}
  83
  84void buffer_skip_bytes(uint32_t len)
  85{
  86        uint32_t in;
  87        while (len > 0 && !feof(infile) && !ferror(infile)) {
  88                in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
  89                in = fread(byte_buffer, 1, in, infile);
  90                len -= in;
  91        }
  92}
  93
  94void buffer_reset(void)
  95{
  96        blob_reset();
  97}