vcs-svn: eliminate global byte_buffer
[git] / vcs-svn / line_buffer.c
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 */
14 obj_pool_gen(blob, char, 4096)
15
16 static char line_buffer[LINE_BUFFER_LEN];
17 static FILE *infile;
18
19 int buffer_init(const char *filename)
20 {
21         infile = filename ? fopen(filename, "r") : stdin;
22         if (!infile)
23                 return -1;
24         return 0;
25 }
26
27 int buffer_deinit(void)
28 {
29         int err;
30         if (infile == stdin)
31                 return ferror(infile);
32         err = ferror(infile);
33         err |= fclose(infile);
34         return err;
35 }
36
37 /* Read a line without trailing newline. */
38 char *buffer_read_line(void)
39 {
40         char *end;
41         if (!fgets(line_buffer, sizeof(line_buffer), infile))
42                 /* Error or data exhausted. */
43                 return NULL;
44         end = line_buffer + strlen(line_buffer);
45         if (end[-1] == '\n')
46                 end[-1] = '\0';
47         else if (feof(infile))
48                 ; /* No newline at end of file.  That's fine. */
49         else
50                 /*
51                  * Line was too long.
52                  * There is probably a saner way to deal with this,
53                  * but for now let's return an error.
54                  */
55                 return NULL;
56         return line_buffer;
57 }
58
59 char *buffer_read_string(uint32_t len)
60 {
61         char *s;
62         blob_free(blob_pool.size);
63         s = blob_pointer(blob_alloc(len + 1));
64         s[fread(s, 1, len, infile)] = '\0';
65         return ferror(infile) ? NULL : s;
66 }
67
68 void buffer_copy_bytes(uint32_t len)
69 {
70         char byte_buffer[COPY_BUFFER_LEN];
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
84 void buffer_skip_bytes(uint32_t len)
85 {
86         char byte_buffer[COPY_BUFFER_LEN];
87         uint32_t in;
88         while (len > 0 && !feof(infile) && !ferror(infile)) {
89                 in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
90                 in = fread(byte_buffer, 1, in, infile);
91                 len -= in;
92         }
93 }
94
95 void buffer_reset(void)
96 {
97         blob_reset();
98 }