/src/git/reftable/blocksource.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright 2020 Google LLC |
3 | | |
4 | | Use of this source code is governed by a BSD-style |
5 | | license that can be found in the LICENSE file or at |
6 | | https://developers.google.com/open-source/licenses/bsd |
7 | | */ |
8 | | |
9 | | #include "system.h" |
10 | | |
11 | | #include "basics.h" |
12 | | #include "blocksource.h" |
13 | | #include "reftable-blocksource.h" |
14 | | #include "reftable-error.h" |
15 | | |
16 | | static void strbuf_return_block(void *b UNUSED, struct reftable_block *dest) |
17 | 0 | { |
18 | 0 | if (dest->len) |
19 | 0 | memset(dest->data, 0xff, dest->len); |
20 | 0 | reftable_free(dest->data); |
21 | 0 | } |
22 | | |
23 | | static void strbuf_close(void *b UNUSED) |
24 | 0 | { |
25 | 0 | } |
26 | | |
27 | | static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off, |
28 | | uint32_t size) |
29 | 0 | { |
30 | 0 | struct strbuf *b = v; |
31 | 0 | assert(off + size <= b->len); |
32 | 0 | REFTABLE_CALLOC_ARRAY(dest->data, size); |
33 | 0 | memcpy(dest->data, b->buf + off, size); |
34 | 0 | dest->len = size; |
35 | 0 | return size; |
36 | 0 | } |
37 | | |
38 | | static uint64_t strbuf_size(void *b) |
39 | 0 | { |
40 | 0 | return ((struct strbuf *)b)->len; |
41 | 0 | } |
42 | | |
43 | | static struct reftable_block_source_vtable strbuf_vtable = { |
44 | | .size = &strbuf_size, |
45 | | .read_block = &strbuf_read_block, |
46 | | .return_block = &strbuf_return_block, |
47 | | .close = &strbuf_close, |
48 | | }; |
49 | | |
50 | | void block_source_from_strbuf(struct reftable_block_source *bs, |
51 | | struct strbuf *buf) |
52 | 0 | { |
53 | 0 | assert(!bs->ops); |
54 | 0 | bs->ops = &strbuf_vtable; |
55 | 0 | bs->arg = buf; |
56 | 0 | } |
57 | | |
58 | | struct file_block_source { |
59 | | uint64_t size; |
60 | | unsigned char *data; |
61 | | }; |
62 | | |
63 | | static uint64_t file_size(void *b) |
64 | 0 | { |
65 | 0 | return ((struct file_block_source *)b)->size; |
66 | 0 | } |
67 | | |
68 | | static void file_return_block(void *b UNUSED, struct reftable_block *dest UNUSED) |
69 | 0 | { |
70 | 0 | } |
71 | | |
72 | | static void file_close(void *v) |
73 | 0 | { |
74 | 0 | struct file_block_source *b = v; |
75 | 0 | munmap(b->data, b->size); |
76 | 0 | reftable_free(b); |
77 | 0 | } |
78 | | |
79 | | static int file_read_block(void *v, struct reftable_block *dest, uint64_t off, |
80 | | uint32_t size) |
81 | 0 | { |
82 | 0 | struct file_block_source *b = v; |
83 | 0 | assert(off + size <= b->size); |
84 | 0 | dest->data = b->data + off; |
85 | 0 | dest->len = size; |
86 | 0 | return size; |
87 | 0 | } |
88 | | |
89 | | static struct reftable_block_source_vtable file_vtable = { |
90 | | .size = &file_size, |
91 | | .read_block = &file_read_block, |
92 | | .return_block = &file_return_block, |
93 | | .close = &file_close, |
94 | | }; |
95 | | |
96 | | int reftable_block_source_from_file(struct reftable_block_source *bs, |
97 | | const char *name) |
98 | 0 | { |
99 | 0 | struct file_block_source *p; |
100 | 0 | struct stat st; |
101 | 0 | int fd; |
102 | |
|
103 | 0 | fd = open(name, O_RDONLY); |
104 | 0 | if (fd < 0) { |
105 | 0 | if (errno == ENOENT) |
106 | 0 | return REFTABLE_NOT_EXIST_ERROR; |
107 | 0 | return -1; |
108 | 0 | } |
109 | | |
110 | 0 | if (fstat(fd, &st) < 0) { |
111 | 0 | close(fd); |
112 | 0 | return REFTABLE_IO_ERROR; |
113 | 0 | } |
114 | | |
115 | 0 | REFTABLE_CALLOC_ARRAY(p, 1); |
116 | 0 | p->size = st.st_size; |
117 | 0 | p->data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
118 | 0 | close(fd); |
119 | |
|
120 | 0 | assert(!bs->ops); |
121 | 0 | bs->ops = &file_vtable; |
122 | 0 | bs->arg = p; |
123 | 0 | return 0; |
124 | 0 | } |