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 "slice.h" |
10 | | |
11 | | #include "system.h" |
12 | | |
13 | | #include "reftable.h" |
14 | | |
15 | | void slice_set_string(struct slice *s, const char *str) |
16 | 18.2k | { |
17 | 18.2k | if (str == NULL) { |
18 | 0 | s->len = 0; |
19 | 0 | return; |
20 | 0 | } |
21 | 18.2k | |
22 | 18.2k | { |
23 | 18.2k | int l = strlen(str); |
24 | 18.2k | l++; /* \0 */ |
25 | 18.2k | slice_resize(s, l); |
26 | 18.2k | memcpy(s->buf, str, l); |
27 | 18.2k | s->len = l - 1; |
28 | 18.2k | } |
29 | 18.2k | } |
30 | | |
31 | | void slice_resize(struct slice *s, int l) |
32 | 78.6k | { |
33 | 78.6k | if (s->cap < l) { |
34 | 44.6k | int c = s->cap * 2; |
35 | 44.6k | if (c < l) { |
36 | 36.0k | c = l; |
37 | 36.0k | } |
38 | 44.6k | s->cap = c; |
39 | 44.6k | s->buf = reftable_realloc(s->buf, s->cap); |
40 | 44.6k | } |
41 | 78.6k | s->len = l; |
42 | 78.6k | } |
43 | | |
44 | | void slice_append_string(struct slice *d, const char *s) |
45 | 3.52k | { |
46 | 3.52k | int l1 = d->len; |
47 | 3.52k | int l2 = strlen(s); |
48 | 3.52k | |
49 | 3.52k | slice_resize(d, l2 + l1); |
50 | 3.52k | memcpy(d->buf + l1, s, l2); |
51 | 3.52k | } |
52 | | |
53 | | void slice_append(struct slice *s, struct slice a) |
54 | 465 | { |
55 | 465 | int end = s->len; |
56 | 465 | slice_resize(s, s->len + a.len); |
57 | 465 | memcpy(s->buf + end, a.buf, a.len); |
58 | 465 | } |
59 | | |
60 | | void slice_consume(struct slice *s, int n) |
61 | 98.8k | { |
62 | 98.8k | s->buf += n; |
63 | 98.8k | s->len -= n; |
64 | 98.8k | } |
65 | | |
66 | | byte *slice_yield(struct slice *s) |
67 | 30.7k | { |
68 | 30.7k | byte *p = s->buf; |
69 | 30.7k | s->buf = NULL; |
70 | 30.7k | s->cap = 0; |
71 | 30.7k | s->len = 0; |
72 | 30.7k | return p; |
73 | 30.7k | } |
74 | | |
75 | | void slice_clear(struct slice *s) |
76 | 30.5k | { |
77 | 30.5k | reftable_free(slice_yield(s)); |
78 | 30.5k | } |
79 | | |
80 | | void slice_copy(struct slice *dest, struct slice src) |
81 | 27.4k | { |
82 | 27.4k | slice_resize(dest, src.len); |
83 | 27.4k | memcpy(dest->buf, src.buf, src.len); |
84 | 27.4k | } |
85 | | |
86 | | /* return the underlying data as char*. len is left unchanged, but |
87 | | a \0 is added at the end. */ |
88 | | const char *slice_as_string(struct slice *s) |
89 | 9.32k | { |
90 | 9.32k | if (s->cap == s->len) { |
91 | 7.07k | int l = s->len; |
92 | 7.07k | slice_resize(s, l + 1); |
93 | 7.07k | s->len = l; |
94 | 7.07k | } |
95 | 9.32k | s->buf[s->len] = 0; |
96 | 9.32k | return (const char *)s->buf; |
97 | 9.32k | } |
98 | | |
99 | | /* return a newly malloced string for this slice */ |
100 | | char *slice_to_string(struct slice in) |
101 | 144 | { |
102 | 144 | struct slice s = { 0 }; |
103 | 144 | slice_resize(&s, in.len + 1); |
104 | 144 | s.buf[in.len] = 0; |
105 | 144 | memcpy(s.buf, in.buf, in.len); |
106 | 144 | return (char *)slice_yield(&s); |
107 | 144 | } |
108 | | |
109 | | bool slice_equal(struct slice a, struct slice b) |
110 | 1 | { |
111 | 1 | if (a.len != b.len) { |
112 | 0 | return 0; |
113 | 0 | } |
114 | 1 | return memcmp(a.buf, b.buf, a.len) == 0; |
115 | 1 | } |
116 | | |
117 | | int slice_compare(struct slice a, struct slice b) |
118 | 27.5k | { |
119 | 27.5k | int min = a.len < b.len ? a.len : b.len; |
120 | 27.5k | int res = memcmp(a.buf, b.buf, min); |
121 | 27.5k | if (res != 0) { |
122 | 25.5k | return res; |
123 | 25.5k | } |
124 | 2.03k | if (a.len < b.len) { |
125 | 993 | return -1; |
126 | 1.04k | } else if (a.len > b.len) { |
127 | 614 | return 1; |
128 | 614 | } else { |
129 | 428 | return 0; |
130 | 428 | } |
131 | 2.03k | } |
132 | | |
133 | | int slice_write(struct slice *b, byte *data, size_t sz) |
134 | 310 | { |
135 | 310 | if (b->len + sz > b->cap) { |
136 | 63 | int newcap = 2 * b->cap + 1; |
137 | 63 | if (newcap < b->len + sz) { |
138 | 25 | newcap = (b->len + sz); |
139 | 25 | } |
140 | 63 | b->buf = reftable_realloc(b->buf, newcap); |
141 | 63 | b->cap = newcap; |
142 | 63 | } |
143 | 310 | |
144 | 310 | memcpy(b->buf + b->len, data, sz); |
145 | 310 | b->len += sz; |
146 | 310 | return sz; |
147 | 310 | } |
148 | | |
149 | | int slice_write_void(void *b, byte *data, size_t sz) |
150 | 309 | { |
151 | 309 | return slice_write((struct slice *)b, data, sz); |
152 | 309 | } |
153 | | |
154 | | static uint64_t slice_size(void *b) |
155 | 17 | { |
156 | 17 | return ((struct slice *)b)->len; |
157 | 17 | } |
158 | | |
159 | | static void slice_return_block(void *b, struct reftable_block *dest) |
160 | 774 | { |
161 | 774 | memset(dest->data, 0xff, dest->len); |
162 | 774 | reftable_free(dest->data); |
163 | 774 | } |
164 | | |
165 | | static void slice_close(void *b) |
166 | 17 | { |
167 | 17 | } |
168 | | |
169 | | static int slice_read_block(void *v, struct reftable_block *dest, uint64_t off, |
170 | | uint32_t size) |
171 | 774 | { |
172 | 774 | struct slice *b = (struct slice *)v; |
173 | 774 | assert(off + size <= b->len); |
174 | 774 | dest->data = reftable_calloc(size); |
175 | 774 | memcpy(dest->data, b->buf + off, size); |
176 | 774 | dest->len = size; |
177 | 774 | return size; |
178 | 774 | } |
179 | | |
180 | | struct reftable_block_source_vtable slice_vtable = { |
181 | | .size = &slice_size, |
182 | | .read_block = &slice_read_block, |
183 | | .return_block = &slice_return_block, |
184 | | .close = &slice_close, |
185 | | }; |
186 | | |
187 | | void block_source_from_slice(struct reftable_block_source *bs, |
188 | | struct slice *buf) |
189 | 17 | { |
190 | 17 | assert(bs->ops == NULL); |
191 | 17 | bs->ops = &slice_vtable; |
192 | 17 | bs->arg = buf; |
193 | 17 | } |
194 | | |
195 | | static void malloc_return_block(void *b, struct reftable_block *dest) |
196 | 46 | { |
197 | 46 | memset(dest->data, 0xff, dest->len); |
198 | 46 | reftable_free(dest->data); |
199 | 46 | } |
200 | | |
201 | | struct reftable_block_source_vtable malloc_vtable = { |
202 | | .return_block = &malloc_return_block, |
203 | | }; |
204 | | |
205 | | struct reftable_block_source malloc_block_source_instance = { |
206 | | .ops = &malloc_vtable, |
207 | | }; |
208 | | |
209 | | struct reftable_block_source malloc_block_source(void) |
210 | 46 | { |
211 | 46 | return malloc_block_source_instance; |
212 | 46 | } |
213 | | |
214 | | int common_prefix_size(struct slice a, struct slice b) |
215 | 2.19k | { |
216 | 2.19k | int p = 0; |
217 | 17.3k | while (p < a.len && p < b.len) { |
218 | 16.9k | if (a.buf[p] != b.buf[p]) { |
219 | 1.75k | break; |
220 | 1.75k | } |
221 | 15.1k | p++; |
222 | 15.1k | } |
223 | 2.19k | |
224 | 2.19k | return p; |
225 | 2.19k | } |