File Coverage

xs/str.xs
Criterion Covered Total %
statement 99 133 74.4
branch 89 248 35.8
condition n/a
subroutine n/a
pod n/a
total 188 381 49.3


line stmt bran cond sub pod time code
1             MODULE = Data::Buffer::Shared PACKAGE = Data::Buffer::Shared::Str
2             PROTOTYPES: DISABLE
3              
4             SV*
5             new(char* class, char* path, UV capacity, UV str_len, UV file_mode = 0600)
6             CODE:
7             char errbuf[BUF_ERR_BUFLEN];
8 4           BufHandle* buf = buf_str_create(path, (uint64_t)capacity, (uint32_t)str_len, (mode_t)file_mode, errbuf);
9 4 50         if (!buf) croak("Data::Buffer::Shared::Str: %s", errbuf[0] ? errbuf : "unknown error");
    0          
10 4           RETVAL = sv_setref_pv(newSV(0), class, (void*)buf);
11             OUTPUT:
12             RETVAL
13              
14             void
15             DESTROY(SV* self_sv)
16             CODE:
17 15 50         if (!SvROK(self_sv)) return;
18 15           BufHandle* h = INT2PTR(BufHandle*, SvIV(SvRV(self_sv)));
19 15 50         if (!h) return;
20 15           sv_setiv(SvRV(self_sv), 0);
21 15           buf_close_map(h);
22              
23             SV*
24             get(SV* self_sv, UV idx)
25             CODE:
26 22 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
27 22           uint32_t esz = h->hdr->elem_size;
28             char *tmp;
29 22           Newx(tmp, esz + 1, char);
30 22           SAVEFREEPV(tmp);
31             uint32_t out_len;
32 22 50         if (!buf_str_get(h, (uint64_t)idx, tmp, &out_len)) XSRETURN_UNDEF;
33 22           RETVAL = newSVpvn(tmp, out_len);
34             OUTPUT:
35             RETVAL
36              
37             bool
38             set(SV* self_sv, UV idx, SV* val_sv)
39             CODE:
40 521 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
41             STRLEN vlen;
42 521           const char *vstr = SvPV(val_sv, vlen);
43 521 50         RETVAL = buf_str_set(h, (uint64_t)idx, vstr, (uint32_t)vlen);
44             OUTPUT:
45             RETVAL
46              
47             void
48             slice(SV* self_sv, UV from, UV count)
49             PPCODE:
50 2 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
51 2 50         if (count == 0) XSRETURN_EMPTY;
52 2           uint32_t esz = h->hdr->elem_size;
53             char *tmp;
54 2           Newx(tmp, count * esz, char);
55 2           SAVEFREEPV(tmp);
56 2 50         if (!buf_str_get_slice(h, (uint64_t)from, (uint64_t)count, tmp))
57 0           croak("Data::Buffer::Shared::Str: slice out of bounds");
58 2 50         EXTEND(SP, count);
59 6 100         for (UV i = 0; i < count; i++) {
60 4           char *elem = tmp + i * esz;
61 4           uint32_t len = esz;
62 54 50         while (len > 0 && elem[len - 1] == '\0') len--;
    100          
63 4 50         mXPUSHp(elem, len);
64             }
65              
66             bool
67             set_slice(SV* self_sv, UV from, ...)
68             CODE:
69 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
70 1           UV count = items - 2;
71 1 50         if (count == 0) XSRETURN(1);
72 1           uint32_t esz = h->hdr->elem_size;
73             char *tmp;
74 1           Newxz(tmp, count * esz, char);
75 1           SAVEFREEPV(tmp);
76 4 100         for (UV i = 0; i < count; i++) {
77             STRLEN vlen;
78 3           const char *vstr = SvPV(ST(i + 2), vlen);
79 3 50         uint32_t copy_len = (uint32_t)(vlen < esz ? vlen : esz);
80 3           memcpy(tmp + i * esz, vstr, copy_len);
81             }
82 1 50         RETVAL = buf_str_set_slice(h, (uint64_t)from, (uint64_t)count, tmp);
83             OUTPUT:
84             RETVAL
85              
86             void
87             fill(SV* self_sv, SV* val_sv)
88             CODE:
89 2 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
90             STRLEN vlen;
91 2           const char *vstr = SvPV(val_sv, vlen);
92 2           buf_str_fill(h, vstr, (uint32_t)vlen);
93              
94             UV
95             capacity(SV* self_sv)
96             CODE:
97 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
98 1           RETVAL = (UV)buf_str_capacity(h);
99             OUTPUT:
100             RETVAL
101              
102             UV
103             mmap_size(SV* self_sv)
104             CODE:
105 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
106 0           RETVAL = (UV)buf_str_mmap_size(h);
107             OUTPUT:
108             RETVAL
109              
110             UV
111             elem_size(SV* self_sv)
112             CODE:
113 3 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
114 3 50         RETVAL = (UV)buf_str_elem_size(h);
115             OUTPUT:
116             RETVAL
117              
118             SV*
119             path(SV* self_sv)
120             CODE:
121 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
122 0 0         if (h->path) RETVAL = newSVpv(h->path, 0); else XSRETURN_UNDEF;
123             OUTPUT:
124             RETVAL
125              
126             void
127             lock_wr(SV* self_sv)
128             CODE:
129 2 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
130 2           buf_str_lock_wr(h);
131              
132             void
133             unlock_wr(SV* self_sv)
134             CODE:
135 2 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
136 2           buf_str_unlock_wr(h);
137              
138             void
139             lock_rd(SV* self_sv)
140             CODE:
141 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
142 0           buf_str_lock_rd(h);
143              
144             void
145             unlock_rd(SV* self_sv)
146             CODE:
147 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
148 0           buf_str_unlock_rd(h);
149              
150             void
151             unlink(SV* self_or_class, ...)
152             CODE:
153             const char *p;
154 0 0         if (SvROK(self_or_class)) {
155 0           BufHandle* h = INT2PTR(BufHandle*, SvIV(SvRV(self_or_class)));
156 0 0         if (h) { if (!h->path) croak("cannot unlink anonymous buffer"); p = h->path; }
    0          
157 0           else croak("Data::Buffer::Shared::Str: destroyed object");
158             } else {
159 0 0         if (items < 2) croak("Usage: Data::Buffer::Shared::Str->unlink($path)");
160 0           p = SvPV_nolen(ST(1));
161             }
162 0 0         if (unlink(p) != 0) croak("unlink(%s): %s", p, strerror(errno));
163              
164             UV
165             ptr(SV* self_sv)
166             CODE:
167 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
168 0 0         RETVAL = PTR2UV(buf_str_ptr(h));
169             OUTPUT:
170             RETVAL
171              
172             UV
173             ptr_at(SV* self_sv, UV idx)
174             CODE:
175 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
176 0           void *p = buf_str_ptr_at(h, (uint64_t)idx);
177 0 0         if (!p) croak("Data::Buffer::Shared::Str: index out of bounds");
178 0 0         RETVAL = PTR2UV(p);
179             OUTPUT:
180             RETVAL
181              
182             SV*
183             new_anon(char* class, UV capacity, UV str_len)
184             CODE:
185             char errbuf[BUF_ERR_BUFLEN];
186 8           BufHandle* buf = buf_str_create_anon((uint64_t)capacity, (uint32_t)str_len, errbuf);
187 8 50         if (!buf) croak("Data::Buffer::Shared::Str: %s", errbuf[0] ? errbuf : "unknown error");
    0          
188 8           RETVAL = sv_setref_pv(newSV(0), class, (void*)buf);
189             OUTPUT:
190             RETVAL
191              
192             void
193             clear(SV* self_sv)
194             CODE:
195 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
196 1           buf_str_clear(h);
197              
198             SV*
199             get_raw(SV* self_sv, UV byte_off, UV nbytes)
200             CODE:
201 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
202 1 50         RETVAL = newSV(nbytes ? nbytes : 1);
203 1           SvPOK_on(RETVAL);
204 1           SvCUR_set(RETVAL, nbytes);
205 1 50         if (nbytes) SvPVX(RETVAL)[nbytes] = '\0'; /* NUL-terminate; newSV reserved nbytes+1 */
206 1 50         if (!buf_str_get_raw(h, (uint64_t)byte_off, (uint64_t)nbytes, SvPVX(RETVAL))) {
207 0           SvREFCNT_dec(RETVAL);
208 0           croak("Data::Buffer::Shared::Str: get_raw out of bounds");
209             }
210             OUTPUT:
211             RETVAL
212              
213             bool
214             set_raw(SV* self_sv, UV byte_off, SV* data_sv)
215             CODE:
216 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
217             STRLEN dlen;
218 1           const char *dptr = SvPV(data_sv, dlen);
219 1 50         RETVAL = buf_str_set_raw(h, (uint64_t)byte_off, (uint64_t)dlen, dptr);
220             OUTPUT:
221             RETVAL
222              
223             SV*
224             new_memfd(char* class, char* name, UV capacity, UV str_len)
225             CODE:
226             char errbuf[BUF_ERR_BUFLEN];
227 2           BufHandle* buf = buf_str_create_memfd(name, (uint64_t)capacity, (uint32_t)str_len, errbuf);
228 2 50         if (!buf) croak("Data::Buffer::Shared::Str: %s", errbuf[0] ? errbuf : "unknown error");
    0          
229 2           RETVAL = sv_setref_pv(newSV(0), class, (void*)buf);
230             OUTPUT:
231             RETVAL
232              
233             SV*
234             new_from_fd(char* class, int fd, UV str_len)
235             CODE:
236             char errbuf[BUF_ERR_BUFLEN];
237 1           BufHandle* buf = buf_str_open_fd(fd, (uint32_t)str_len, errbuf);
238 1 50         if (!buf) croak("Data::Buffer::Shared::Str: %s", errbuf[0] ? errbuf : "unknown error");
    0          
239 1           RETVAL = sv_setref_pv(newSV(0), class, (void*)buf);
240             OUTPUT:
241             RETVAL
242              
243             SV*
244             fd(SV* self_sv)
245             CODE:
246 2 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
247 2 50         if (h->fd < 0) XSRETURN_UNDEF;
248 2           RETVAL = newSViv(h->fd);
249             OUTPUT:
250             RETVAL
251              
252             SV*
253             as_scalar(SV* self_sv)
254             CODE:
255 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
256 1           size_t len = (size_t)(h->hdr->capacity * h->hdr->elem_size);
257 1           SV *inner = newSV_type(SVt_PV);
258 1           SvPV_set(inner, (char *)h->data);
259 1           SvCUR_set(inner, len);
260 1           SvLEN_set(inner, 0);
261 1           SvPOK_on(inner);
262 1           SvREADONLY_on(inner);
263 1           MAGIC *mg = sv_magicext(inner, NULL, PERL_MAGIC_ext, &buf_scalar_magic_vtbl, NULL, 0);
264 1           mg->mg_obj = SvREFCNT_inc_simple_NN(self_sv);
265 1           RETVAL = newRV_noinc(inner);
266             OUTPUT:
267             RETVAL
268              
269             IV
270             create_eventfd(SV* self_sv)
271             CODE:
272 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
273 1           RETVAL = (IV)buf_create_eventfd(h);
274 1 50         if (RETVAL < 0) croak("Data::Buffer::Shared::Str: eventfd: %s", strerror(errno));
275             OUTPUT:
276             RETVAL
277              
278             void
279             attach_eventfd(SV* self_sv, int efd)
280             CODE:
281 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
282 1           buf_attach_eventfd(h, efd);
283              
284             SV*
285             eventfd(SV* self_sv)
286             CODE:
287 2 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
288 2 50         if (h->efd < 0) XSRETURN_UNDEF;
289 2           RETVAL = newSViv(h->efd);
290             OUTPUT:
291             RETVAL
292              
293             bool
294             notify(SV* self_sv)
295             CODE:
296 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
297 1 50         RETVAL = buf_notify(h);
298             OUTPUT:
299             RETVAL
300              
301             SV*
302             wait_notify(SV* self_sv)
303             CODE:
304 1 50         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    50          
    50          
305 1           int64_t val = buf_wait_notify(h);
306 1 50         if (val < 0) XSRETURN_UNDEF;
307 1           RETVAL = newSViv(val);
308             OUTPUT:
309             RETVAL
310              
311             void
312             sync(SV* self_sv)
313             CODE:
314 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
315 0 0         if (buf_msync(h) != 0) croak("Data::Buffer::Shared::Str sync: %s", strerror(errno));
316              
317             SV*
318             stats(SV* self_sv)
319             CODE:
320 0 0         EXTRACT_BUF("Data::Buffer::Shared::Str", self_sv);
    0          
    0          
321 0           HV *hv = newHV();
322 0           hv_store(hv, "capacity", 8, newSVuv((UV)h->hdr->capacity), 0);
323 0           hv_store(hv, "elem_size", 9, newSVuv((UV)h->hdr->elem_size), 0);
324 0           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
325 0           hv_store(hv, "variant_id",10, newSVuv((UV)h->hdr->variant_id), 0);
326 0           hv_store(hv, "recoveries",10, newSVuv((UV)__atomic_load_n(&h->hdr->stat_recoveries, __ATOMIC_RELAXED)), 0);
327 0           RETVAL = newRV_noinc((SV*)hv);
328             OUTPUT:
329             RETVAL