chiark / gitweb /
597337519e8d6e647be0be54f0e184fe38bb08db
[disorder] / lib / hreader.c
1 /*
2  * This file is part of DisOrder
3  * Copyright (C) 2010 Richard Kettlewell
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 /** @file lib/hreader.c
19  * @brief Hands-off reader - read files without keeping them open
20  */
21 #include "hreader.h"
22 #include "mem.h"
23 #include <string.h>
24 #include <fcntl.h>
25
26 void hreader_init(const char *path, struct hreader *h) {
27   memset(h, 0, sizeof *h);
28   h->path = xstrdup(path);
29   h->bufsize = 65536;
30   h->buffer = xmalloc_noptr(h->bufsize);
31 }
32
33 int hreader_read(struct hreader *h, void *buffer, size_t n) {
34   if(h->consumed == h->bytes) {
35     int r;
36
37     if((r = hreader_fill(h)) <= 0)
38       return r;
39   }
40   if(n > h->bytes - h->consumed)
41     n = h->bytes - h->consumed;
42   memcpy(buffer, h->buffer + h->consumed, n);
43   h->consumed += n;
44   return n;
45 }
46
47 int hreader_fill(struct hreader *h) {
48   if(h->consumed < h->bytes)
49     return h->bytes - h->consumed;
50   h->bytes = h->consumed = 0;
51   int fd = open(h->path, O_RDONLY);
52   if(fd < 0)
53     return -1;
54   if(lseek(fd, h->offset, SEEK_SET) < 0) {
55     close(fd);
56     return -1;
57   }
58   int n = read(fd, h->buffer, h->bufsize);
59   close(fd);
60   if(n < 0)
61     return -1;
62   h->bytes = n;
63   h->offset += n;
64   return n;
65 }
66
67 void hreader_consume(struct hreader *h, size_t n) {
68   h->consumed += n;
69 }
70
71 /*
72 Local Variables:
73 c-basic-offset:2
74 comment-column:40
75 fill-column:79
76 indent-tabs-mode:nil
77 End:
78 */