Sync with 'maint'
[alt-git.git] / reftable / blocksource.c
blob52e0915a67bee310637e5d16d9ad69aa50420c7b
1 /*
2 Copyright 2020 Google LLC
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 */
9 #include "system.h"
11 #include "basics.h"
12 #include "blocksource.h"
13 #include "reftable-blocksource.h"
14 #include "reftable-error.h"
16 static void reftable_buf_return_block(void *b UNUSED, struct reftable_block *dest)
18 if (dest->len)
19 memset(dest->data, 0xff, dest->len);
20 reftable_free(dest->data);
23 static void reftable_buf_close(void *b UNUSED)
27 static int reftable_buf_read_block(void *v, struct reftable_block *dest,
28 uint64_t off, uint32_t size)
30 struct reftable_buf *b = v;
31 assert(off + size <= b->len);
32 REFTABLE_CALLOC_ARRAY(dest->data, size);
33 if (!dest->data)
34 return -1;
35 memcpy(dest->data, b->buf + off, size);
36 dest->len = size;
37 return size;
40 static uint64_t reftable_buf_size(void *b)
42 return ((struct reftable_buf *)b)->len;
45 static struct reftable_block_source_vtable reftable_buf_vtable = {
46 .size = &reftable_buf_size,
47 .read_block = &reftable_buf_read_block,
48 .return_block = &reftable_buf_return_block,
49 .close = &reftable_buf_close,
52 void block_source_from_buf(struct reftable_block_source *bs,
53 struct reftable_buf *buf)
55 assert(!bs->ops);
56 bs->ops = &reftable_buf_vtable;
57 bs->arg = buf;
60 struct file_block_source {
61 uint64_t size;
62 unsigned char *data;
65 static uint64_t file_size(void *b)
67 return ((struct file_block_source *)b)->size;
70 static void file_return_block(void *b UNUSED, struct reftable_block *dest UNUSED)
74 static void file_close(void *v)
76 struct file_block_source *b = v;
77 munmap(b->data, b->size);
78 reftable_free(b);
81 static int file_read_block(void *v, struct reftable_block *dest, uint64_t off,
82 uint32_t size)
84 struct file_block_source *b = v;
85 assert(off + size <= b->size);
86 dest->data = b->data + off;
87 dest->len = size;
88 return size;
91 static struct reftable_block_source_vtable file_vtable = {
92 .size = &file_size,
93 .read_block = &file_read_block,
94 .return_block = &file_return_block,
95 .close = &file_close,
98 int reftable_block_source_from_file(struct reftable_block_source *bs,
99 const char *name)
101 struct file_block_source *p;
102 struct stat st;
103 int fd, err;
105 fd = open(name, O_RDONLY);
106 if (fd < 0) {
107 if (errno == ENOENT)
108 return REFTABLE_NOT_EXIST_ERROR;
109 err = -1;
110 goto out;
113 if (fstat(fd, &st) < 0) {
114 err = REFTABLE_IO_ERROR;
115 goto out;
118 REFTABLE_CALLOC_ARRAY(p, 1);
119 if (!p) {
120 err = REFTABLE_OUT_OF_MEMORY_ERROR;
121 goto out;
124 p->size = st.st_size;
125 p->data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
127 assert(!bs->ops);
128 bs->ops = &file_vtable;
129 bs->arg = p;
131 err = 0;
133 out:
134 if (fd >= 0)
135 close(fd);
136 if (err < 0)
137 reftable_free(p);
138 return 0;