14 #define MAX_BUF ((512 * 1024) - 1)
16 int lparse_fd(int fd
, uint64_t size
, int (*parse
)(char *, uint
))
20 if (!buf
&& !(buf
= calloc(1, MAX_BUF
+ 1)))
23 while (tot_rd
< size
) {
25 int blkparsed
, bytes_rd
;
27 bytes_rd
= read(fd
, buf
, MAX_BUF
< size
? MAX_BUF
: size
);
31 if (tot_rd
+ bytes_rd
< size
) {
32 /* rewind the file to the last found newline */
33 while (buf
[bytes_rd
- 1] != '\n')
35 lseek(fd
, tot_rd
+ bytes_rd
, SEEK_SET
);
39 /* set a sentinel for memchr() */
43 for (blkparsed
= 0; blkparsed
< bytes_rd
; cur
= next
+ 1) {
45 next
= memchr(cur
, '\n', bytes_rd
+ 1 - blkparsed
);
57 int lparse_rev_fd(int fd
, uint64_t size
, int (*parse
)(char *, uint
))
59 uint64_t tot_rd
= 0, parsed
= 0, reads
= 0;
61 if (!buf
&& !(buf
= calloc(1, MAX_BUF
+ 1)))
64 while (tot_rd
< size
) {
65 char *cur
, *first
, *eol
, *last
;
66 int blkparsed
, bytes_rd
;
70 * First we figure out where to start reading
71 * and how much to read. Then we lseek() to that
72 * position and actually read it in (works)
74 if (tot_rd
+ MAX_BUF
< size
) {
77 to_read
= size
- tot_rd
;
79 lseek(fd
, size
- tot_rd
- to_read
, SEEK_SET
);
81 bytes_rd
= read(fd
, buf
, to_read
);
85 if (tot_rd
+ bytes_rd
< size
) {
88 * set 'first' to just after first newline or,
89 * failing that, to the start of the buffer itself
91 first
= memchr(buf
, '\n', bytes_rd
);
97 /* remember the position of the first found newline */
98 bytes_rd
-= first
- buf
;
105 * if the buffer we just read ends with a newline, we must
106 * discard it from the first round of parsing, or we'll add
107 * one line for each time we read.
109 if (first
[bytes_rd
- 1] == '\n')
112 eol
= last
= first
+ bytes_rd
;
113 for (blkparsed
= 0; blkparsed
< bytes_rd
; cur
= eol
- 1) {
118 * set 'cur' to first newline befor 'eol', and set
119 * 'line' to first char after it
121 cur
= memrchr(first
, '\n', bytes_rd
- blkparsed
);
129 blkparsed
+= len
+ 1;
141 int lparse_path_real(int rev
, const char *path
, uint64_t size
, int (*parse
)(char *, uint
))
145 /* zero size files are never interesting */
149 if ((fd
= open(path
, O_RDONLY
)) < 0)
153 result
= lparse_rev_fd(fd
, size
, parse
);
155 result
= lparse_fd(fd
, size
, parse
);