Coverage Report

Created: 2020-05-07 18:36

/proc/self/cwd/c/slice.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 "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
}