File Coverage

lib/UUID.xs
Criterion Covered Total %
statement 253 271 93.3
branch 478 1220 39.1
condition n/a
subroutine n/a
pod n/a
total 731 1491 49.0


line stmt bran cond sub pod time code
1             #ifdef __cplusplus
2             extern "C" {
3             #endif
4              
5             /*
6             ** It seems that perfection is attained
7             ** not when there is nothing more to add,
8             ** but when there is nothing more to remove.
9             ** -- Antoine de Saint Exupery
10             */
11              
12             #define NO_XSLOCKS
13             #include "ulib/UUID.h"
14             #include "XSUB.h"
15             #include "ulib/chacha.h"
16             #include "ulib/clock.h"
17             #include "ulib/compare.h"
18             #include "ulib/gen.h"
19             #include "ulib/gettime.h"
20             #include "ulib/hash.h"
21             #include "ulib/pack.h"
22             #include "ulib/parse.h"
23             #include "ulib/splitmix.h"
24             #include "ulib/util.h"
25             #include "ulib/xoshiro.h"
26              
27             #ifdef __cplusplus
28             }
29             #endif
30              
31             /* 2 hex digits per byte + 4 separators */
32             #define UUID_BUFFSZ 36
33              
34              
35             #define MY_CXT_KEY "UUID::_guts" XS_VERSION
36             /* my_cxt_t global typedef lives in TYPE.h */
37             START_MY_CXT
38              
39              
40             #ifdef PERL_IMPLICIT_CONTEXT
41             # define dUCXT dMY_CXT
42             # define UCXT_INIT MY_CXT_INIT
43             #else
44             # define dUCXT my_cxt_t *my_cxtp = &my_cxt;
45             # define UCXT_INIT my_cxt_t *my_cxtp = &my_cxt;
46             #endif
47              
48             #define UU_GEN_TMPL(ver, out, su, dptr) \
49             SV_CHECK_THINKFIRST_COW_DROP(out); \
50             if (isGV_with_GP(out)) \
51             croak("%s", PL_no_modify); \
52             SvUPGRADE(out, SVt_PV); \
53             UMTX_LOCK { \
54             uu_gen_v##ver(aUCXT, &su, dptr); \
55             } UMTX_UNLOCK \
56             dptr = SvGROW(out, sizeof(uu_t)+1); \
57             uu_pack_v##ver(&su, (U8*)dptr); \
58             dptr[sizeof(uu_t)] = '\0'; \
59             SvCUR_set(out, sizeof(uu_t)); \
60             (void)SvPOK_only(out); \
61             if (SvTYPE(out) == SVt_PVCV) \
62             CvAUTOLOAD_off(out);
63              
64             #define UU_ALIAS_GEN_V0(out, su, dptr) UU_GEN_TMPL(0, out, su, dptr)
65             #define UU_ALIAS_GEN_V1(out, su, dptr) UU_GEN_TMPL(1, out, su, dptr)
66             #define UU_ALIAS_GEN_V3(out, su, dptr) UU_GEN_TMPL(3, out, su, dptr)
67             #define UU_ALIAS_GEN_V4(out, su, dptr) UU_GEN_TMPL(4, out, su, dptr)
68             #define UU_ALIAS_GEN_V5(out, su, dptr) UU_GEN_TMPL(5, out, su, dptr)
69             #define UU_ALIAS_GEN_V6(out, su, dptr) UU_GEN_TMPL(6, out, su, dptr)
70             #define UU_ALIAS_GEN_V7(out, su, dptr) UU_GEN_TMPL(7, out, su, dptr)
71              
72              
73             #define UU_UNPARSE_TMPL(case, in, out, su, dptr) \
74             if (SvPOK(in)) { \
75             dptr = SvGROW(in, sizeof(uu_t)); \
76             uu_pack_unpack((unsigned char*)dptr, &su); \
77             SV_CHECK_THINKFIRST_COW_DROP(out); \
78             if (isGV_with_GP(out)) \
79             croak("%s", PL_no_modify); \
80             SvUPGRADE(out, SVt_PV); \
81             SvPOK_only(out); \
82             dptr = SvGROW(out, UUID_BUFFSZ+1); \
83             uu_parse_unparse_ ## case ## er1(&su, dptr); \
84             dptr[UUID_BUFFSZ] = '\0'; \
85             SvCUR_set(out, UUID_BUFFSZ); \
86             (void)SvPOK_only(out); \
87             if (SvTYPE(out) == SVt_PVCV) \
88             CvAUTOLOAD_off(out); \
89             }
90              
91             #define UU_ALIAS_UNPARSE_LOWER(in, out, su, dptr) UU_UNPARSE_TMPL(low, in, out, su, dptr)
92             #define UU_ALIAS_UNPARSE_UPPER(in, out, su, dptr) UU_UNPARSE_TMPL(upp, in, out, su, dptr)
93              
94              
95             #define UU_UUID_TMPL(ver, su, dptr) \
96             UMTX_LOCK { \
97             uu_gen_v##ver(aUCXT, &su, dptr); \
98             } UMTX_UNLOCK \
99             RETVAL = newSV(UUID_BUFFSZ+1); \
100             dptr = SvPVX(RETVAL); \
101             uu_parse_unparse_v##ver(&su, dptr); \
102             dptr[UUID_BUFFSZ] = '\0'; \
103             SvCUR_set(RETVAL, UUID_BUFFSZ); \
104             SvPOK_only(RETVAL);
105              
106             #define UU_ALIAS_UUID0(su, dptr) UU_UUID_TMPL(0, su, dptr)
107             #define UU_ALIAS_UUID1(su, dptr) UU_UUID_TMPL(1, su, dptr)
108             #define UU_ALIAS_UUID3(su, dptr) UU_UUID_TMPL(3, su, dptr)
109             #define UU_ALIAS_UUID4(su, dptr) UU_UUID_TMPL(4, su, dptr)
110             #define UU_ALIAS_UUID5(su, dptr) UU_UUID_TMPL(5, su, dptr)
111             #define UU_ALIAS_UUID6(su, dptr) UU_UUID_TMPL(6, su, dptr)
112             #define UU_ALIAS_UUID7(su, dptr) UU_UUID_TMPL(7, su, dptr)
113              
114              
115             #define UU_ALIAS_VERSION(in, su, str, len) \
116             RETVAL = -1; \
117             if (SvPOK(in)) { \
118             str = SvPV(in, len); \
119             if (len == sizeof(uu_t)) { \
120             uu_pack_unpack((unsigned char*)str, &su); \
121             RETVAL = uu_type(&su); \
122             } \
123             }
124              
125             const struct_uu_t UU_namespace_dns = {{ 0x6ba7b810, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}};
126             const struct_uu_t UU_namespace_url = {{ 0x6ba7b811, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}};
127             const struct_uu_t UU_namespace_oid = {{ 0x6ba7b812, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}};
128             const struct_uu_t UU_namespace_x500 = {{ 0x6ba7b814, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}};
129              
130 264           static void smem_init(pUCXT) {
131             #if defined(USE_WIN32_NATIVE) || defined(USE_WIN32_ALIEN)
132             IV size = sizeof(shared_mem_t);
133             SMEM = VirtualAlloc(NULL, size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
134             if (!SMEM) croak("VirtualAlloc: %li\n", GetLastError());
135             UCXT.shared_len = size;
136             #else
137 264           IV pagesz = sysconf(_SC_PAGESIZE);
138 264           IV npages = sizeof(shared_mem_t) / pagesz;
139 264 50         if (sizeof(shared_mem_t) % pagesz) ++npages;
140 264           IV nbytes = npages * pagesz;
141 264           SMEM = (shared_mem_t*)mmap(NULL, nbytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
142 264 50         if (SMEM == MAP_FAILED) croak("mmap: %s\n", strerror((IV)SMEM));
143 264           UCXT.shared_len = nbytes;
144             #endif
145 264           }
146              
147              
148             MODULE = UUID PACKAGE = UUID
149              
150              
151             BOOT:
152 264           UCXT_INIT;
153 264           smem_init(aUCXT);
154 264           UMTX_INIT;
155 264 50         UMTX_LOCK {
    0          
    0          
    50          
156              
157             /* order important */
158 264           uu_gettime_init(aUCXT);
159 264           uu_clock_init(aUCXT);
160 264           uu_chacha_srand(aUCXT); /* must be before gen_init, but after clock_init */
161 264           uu_gen_init(aUCXT);
162              
163 264           uu_chacha_rand16(aUCXT, &SMEM->clock_seq);
164              
165 264 50         } UMTX_UNLOCK
    50          
    0          
    0          
166              
167              
168             void
169             _hide_always()
170             PROTOTYPE:
171             PREINIT:
172 2           dUCXT;
173             PPCODE:
174 2 50         UMTX_LOCK {
    0          
    0          
    50          
175 2           uu_gen_setuniq(aUCXT);
176 2 50         } UMTX_UNLOCK
    50          
    0          
    0          
177              
178             void
179             _hide_mac()
180             PROTOTYPE:
181             PREINIT:
182 8           dUCXT;
183             PPCODE:
184 8 50         UMTX_LOCK {
    0          
    0          
    50          
185 8           uu_gen_setrand(aUCXT);
186 8 50         } UMTX_UNLOCK
    50          
    0          
    0          
187              
188             SV *
189             _persist(...)
190             PROTOTYPE: @
191             PREINIT:
192 41           dUCXT;
193             INIT:
194             char *ptr;
195             SV *sv;
196             persist_t persist;
197             CODE:
198 41 100         if (items > 1)
199 1           croak("Usage: _persist([path/to/file])");
200 40 100         if (items == 0) {
201 10 50         UMTX_LOCK {
    0          
    0          
    50          
202 10           uu_clock_getpath(aUCXT, &persist);
203 10 50         } UMTX_UNLOCK
    50          
    0          
    0          
204 10 100         if (persist.len)
205 8           RETVAL = newSVpvn((char*)persist.path, persist.len);
206             else
207 2           RETVAL = newSV(0);
208             }
209             else { /* items == 1 */
210 30           Zero(&persist, 1, persist_t);
211 30 100         if (SvTRUE(ST(0))) {
212 20           sv = ST(0);
213 20           ptr = SvPV(sv, persist.len);
214              
215 20 50         if (persist.len > MAX_PERSIST_LEN)
216 0           croak("Persist path too long. (max %" UVuf ")", (UV)MAX_PERSIST_LEN); /* XXX croak() or croak_caller() ? */
217              
218             /* includes null */
219 20           Copy(ptr, persist.path, persist.len+1, UCHAR);
220              
221 20 50         UMTX_LOCK {
    0          
    0          
    50          
222 20           uu_clock_setpath(aUCXT, &persist);
223 20 50         } UMTX_UNLOCK
    50          
    0          
    0          
224             }
225             else {
226 10 50         UMTX_LOCK {
    0          
    0          
    50          
227 10           uu_clock_setpath(aUCXT, &persist);
228 10 50         } UMTX_UNLOCK
    50          
    0          
    0          
229             }
230 30           RETVAL = &PL_sv_yes;
231             }
232             OUTPUT:
233             RETVAL
234              
235             SV *
236             _realnode()
237             PROTOTYPE:
238             PREINIT:
239 261           dUCXT;
240             INIT:
241             int rv;
242             char *dptr;
243             struct_uu_t su;
244             CODE:
245 261 50         UMTX_LOCK {
    0          
    0          
    50          
246 261           rv = uu_gen_realnode(aUCXT, &su);
247 261 50         } UMTX_UNLOCK
    50          
    0          
    0          
248 261 50         if (rv) {
249 261           RETVAL = newSV(UUID_BUFFSZ+1);
250 261           dptr = SvPVX(RETVAL);
251 261           uu_parse_unparse_v0(&su, dptr);
252 261           dptr[UUID_BUFFSZ] = '\0';
253 261           SvCUR_set(RETVAL, UUID_BUFFSZ);
254 261           SvPOK_only(RETVAL);
255             }
256             else
257 0           RETVAL = &PL_sv_no;
258             OUTPUT:
259             RETVAL
260              
261             SV *
262             _defer(...)
263             PROTOTYPE: @
264             PREINIT:
265 15           dUCXT;
266             INIT:
267             SV *duration;
268             CODE:
269 15 100         if (items == 0) {
270 6           RETVAL = newSVnv(SMEM->clock_defer_100ns / 10000000.0);
271             }
272 9 100         else if (items == 1) {
273 8           duration = ST(0);
274 8 100         if (!looks_like_number(duration))
275 1           croak_caller("Non-numeric :defer argument");
276 7 50         UMTX_LOCK {
    0          
    0          
    50          
277 7           SMEM->clock_defer_100ns = (U64)(SvNV(duration) * 10000000.0);
278 7 50         } UMTX_UNLOCK
    50          
    0          
    0          
279 7           RETVAL = &PL_sv_yes;
280             }
281             else
282 1           croak("Too many arguments for _defer()");
283             OUTPUT:
284             RETVAL
285              
286             void
287             clear(io)
288             SV * io
289             PROTOTYPE: $
290             PREINIT:
291 9           dUCXT;
292             INIT:
293             struct_uu_t su;
294 9           char *dptr = NULL;
295             CODE:
296 9 100         UU_ALIAS_GEN_V0(io, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
297              
298             IV
299             compare(in1, in2)
300             SV * in1
301             SV * in2
302             PROTOTYPE: $$
303             PREINIT:
304 417 50         dUCXT;
305             INIT:
306             STRLEN len1, len2;
307             CODE:
308             (void)my_cxtp; /* silence warning */
309 417 100         if (SvPOK(in1) && SvPOK(in2)
    100          
310 403 100         && SvCUR(in1) == sizeof(uu_t)
311 300 100         && SvCUR(in2) == sizeof(uu_t))
312 296           RETVAL = uu_compare_binary(
313 296           (U8*)SvPV_force(in1, len1),
314 296           (U8*)SvPV_force(in2, len2)
315             );
316 121 100         else if (!SvOK(in1))
317 7 100         RETVAL = SvOK(in2) ? -1 : 0;
318 114 100         else if (!SvOK(in2))
319 5           RETVAL = 1;
320             else
321 109           RETVAL = sv_cmp(in1, in2);
322             OUTPUT:
323             RETVAL
324              
325             void
326             copy(out, in)
327             SV * out
328             SV * in
329             PROTOTYPE: $$
330             PREINIT:
331 13           dUCXT;
332             INIT:
333             struct_uu_t su;
334             STRLEN len;
335             char *dptr;
336             CODE:
337             (void)my_cxtp; /* silence warning */
338 13 100         if (!SvPOK(in) || SvCUR(in) != sizeof(uu_t))
    100          
339 6           uu_clear(&su);
340             else
341 7           uu_pack_unpack((U8*)SvPV_force(in, len), &su);
342 13 100         SV_CHECK_THINKFIRST_COW_DROP(out);
343 13 50         if (isGV_with_GP(out))
    0          
    0          
344 0           croak("%s", PL_no_modify);
345 13 100         SvUPGRADE(out, SVt_PV);
346 13 50         dptr = SvGROW(out, sizeof(uu_t)+1);
    100          
347 13           uu_pack_v1(&su, (U8*)dptr);
348 13           dptr[sizeof(uu_t)] = '\0';
349 13           SvCUR_set(out, sizeof(uu_t));
350 13           (void)SvPOK_only(out);
351 13 50         if (SvTYPE(out) == SVt_PVCV)
352 0           CvAUTOLOAD_off(out);
353              
354             void
355             generate(out)
356             SV * out
357             PROTOTYPE: $
358             PREINIT:
359 13           dUCXT;
360             INIT:
361 13           char *dptr = NULL;
362             struct_uu_t su;
363             CODE:
364 13 100         UU_ALIAS_GEN_V4(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
365              
366             void
367             generate_random(out)
368             SV * out
369             PROTOTYPE: $
370             PREINIT:
371 6           dUCXT;
372             INIT:
373 6           char *dptr = NULL;
374             struct_uu_t su;
375             CODE:
376 6 50         UU_ALIAS_GEN_V4(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
377              
378             void
379             generate_time(out)
380             SV * out
381             PROTOTYPE: $
382             PREINIT:
383 14           dUCXT;
384             INIT:
385 14           char *dptr = NULL;
386             struct_uu_t su;
387             CODE:
388 14 50         UU_ALIAS_GEN_V1(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
389              
390             void
391             generate_v0(out)
392             SV * out
393             PROTOTYPE: $
394             PREINIT:
395 17           dUCXT;
396             INIT:
397 17           char *dptr = NULL;
398             struct_uu_t su;
399             CODE:
400 17 50         UU_ALIAS_GEN_V0(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
401              
402             void
403             generate_v1(out)
404             SV * out
405             PROTOTYPE: $
406             PREINIT:
407 200020           dUCXT;
408             INIT:
409 200020           char *dptr = NULL;
410             struct_uu_t su;
411             CODE:
412 200020 50         UU_ALIAS_GEN_V1(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
413              
414             void
415             generate_v3(out, namespace, name)
416             SV * out
417             SV * namespace
418             SV * name
419             PROTOTYPE: $$$
420             PREINIT:
421 200025           dUCXT;
422             INIT:
423             char *dptr, *sptr;
424             STRLEN dlen, slen;
425             struct_uu_t su;
426             CODE:
427 200025 50         SvUPGRADE(namespace, SVt_PV);
428 200025 50         SvUPGRADE(name, SVt_PV);
429 200025           sptr = SvPV(namespace, slen);
430 200025           dptr = SvPV(name, dlen);
431              
432 200028 100         if (slen == 36 && !uu_parse(sptr, &su)) {
    50          
433             /* uuid string */
434 3 50         UU_ALIAS_GEN_V3(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
435             }
436 200022 50         else if (slen == 16) {
437             /* assume binary uuid */
438 0           uu_pack_unpack((unsigned char*)sptr, &su);
439 0 0         UU_ALIAS_GEN_V3(out, su, dptr);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
440             }
441 200022 100         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
442 200021 50         && ( (slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t))
    100          
    50          
443 1 50         || (slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t))
    50          
    50          
444 0 0         || (slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t))
    0          
    0          
445 0 0         || (slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t))
    0          
    0          
446             )
447 200021           ) {
448 200021 50         UU_ALIAS_GEN_V3(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
449             }
450             else { /* slen == 0 ; assume url type */
451 1           CopyD(&UU_namespace_url, &su, 1, struct_uu_t);
452 1 50         UU_ALIAS_GEN_V3(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
453             }
454              
455             void
456             generate_v4(out)
457             SV * out
458             PROTOTYPE: $
459             PREINIT:
460 200018           dUCXT;
461             INIT:
462 200018           char *dptr = NULL;
463             struct_uu_t su;
464             CODE:
465 200018 50         UU_ALIAS_GEN_V4(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
466              
467             void
468             generate_v5(out, namespace, name)
469             SV * out
470             SV * namespace
471             SV * name
472             PROTOTYPE: $$$
473             PREINIT:
474 200025           dUCXT;
475             INIT:
476             char *dptr, *sptr;
477             STRLEN dlen, slen;
478             struct_uu_t su;
479             CODE:
480 200025 50         SvUPGRADE(namespace, SVt_PV);
481 200025 50         SvUPGRADE(name, SVt_PV);
482 200025           sptr = SvPV(namespace, slen);
483 200025           dptr = SvPV(name, dlen);
484              
485 200028 100         if (slen == 36 && !uu_parse(sptr, &su)) {
    50          
486             /* uuid string */
487 3 50         UU_ALIAS_GEN_V5(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
488             }
489 200022 50         else if (slen == 16) {
490             /* assume binary uuid */
491 0           uu_pack_unpack((unsigned char*)sptr, &su);
492 0 0         UU_ALIAS_GEN_V5(out, su, dptr);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
493             }
494 200022 100         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
495 200021 50         && ( (slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t))
    100          
    50          
496 1 50         || (slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t))
    50          
    50          
497 0 0         || (slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t))
    0          
    0          
498 0 0         || (slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t))
    0          
    0          
499             )
500 200021           ) {
501 200021 50         UU_ALIAS_GEN_V5(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
502             }
503             else { /* slen == 0 ; assume url type */
504 1           CopyD(&UU_namespace_url, &su, 1, struct_uu_t);
505 1 50         UU_ALIAS_GEN_V5(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
506             }
507              
508             void
509             generate_v6(out)
510             SV * out
511             PROTOTYPE: $
512             PREINIT:
513 200018           dUCXT;
514             INIT:
515 200018           char *dptr = NULL;
516             struct_uu_t su;
517             CODE:
518 200018 50         UU_ALIAS_GEN_V6(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
519              
520             void
521             generate_v7(out)
522             SV * out
523             PROTOTYPE: $
524             PREINIT:
525 200018           dUCXT;
526             INIT:
527 200018           char *dptr = NULL;
528             struct_uu_t su;
529             CODE:
530 200018 50         UU_ALIAS_GEN_V7(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    50          
    100          
    50          
531              
532             IV
533             is_null(in)
534             SV * in
535             PROTOTYPE: $
536             PREINIT:
537 120 50         dUCXT;
538             INIT:
539             STRLEN len;
540             CODE:
541             (void)my_cxtp; /* silence warning */
542 120 100         if (!SvPOK(in))
543 2           RETVAL = 0;
544 118 100         else if (SvCUR(in) != sizeof(uu_t))
545 5           RETVAL = 0;
546             else
547 113           RETVAL = uu_compare_isnull_binary((U8*)SvPV(in, len));
548             OUTPUT:
549             RETVAL
550              
551             IV
552             parse(in, out)
553             SV * in
554             SV * out
555             PROTOTYPE: $$
556             PREINIT:
557 50 50         dUCXT;
558             INIT:
559             char *dptr;
560             struct_uu_t su;
561             CODE:
562             (void)my_cxtp; /* silence warning */
563             /* XXX might see uninitialized data */
564 50           RETVAL = -1;
565 50 100         if (SvPOK(in) && !uu_parse(SvGROW(in, UUID_BUFFSZ+1), &su)) {
    100          
    50          
    100          
566 40 100         SV_CHECK_THINKFIRST_COW_DROP(out);
567 40 50         if (isGV_with_GP(out))
    0          
    0          
568 0           croak("%s", PL_no_modify);
569 40 100         SvUPGRADE(out, SVt_PV);
570 40 50         dptr = SvGROW(out, sizeof(uu_t)+1);
    100          
571 40           uu_pack_v1(&su, (U8*)dptr);
572 40           dptr[sizeof(uu_t)] = '\0';
573 40           SvCUR_set(out, sizeof(uu_t));
574 40           (void)SvPOK_only(out);
575 40 50         if (SvTYPE(out) == SVt_PVCV)
576 0           CvAUTOLOAD_off(out);
577 40           RETVAL = 0;
578             }
579             OUTPUT:
580             RETVAL
581              
582             NV
583             time(in)
584             SV * in
585             PROTOTYPE: $
586             PREINIT:
587 9 50         dUCXT;
588             INIT:
589             struct_uu_t su;
590             char *str;
591             STRLEN len;
592             CODE:
593             (void)my_cxtp; /* silence warning */
594 9           RETVAL = 0;
595 9 50         if (SvPOK(in)) {
596 9           str = SvPV(in, len);
597 9 50         if (len == sizeof(uu_t)) {
598 9           uu_pack_unpack((U8*)str, &su);
599 9           RETVAL = uu_time(&su);
600             }
601             }
602             OUTPUT:
603             RETVAL
604              
605             IV
606             type(in)
607             SV * in
608             PROTOTYPE: $
609             PREINIT:
610 118 50         dUCXT;
611             INIT:
612             struct_uu_t su;
613             char *str;
614             STRLEN len;
615             CODE:
616             (void)my_cxtp; /* silence warning */
617 118 100         UU_ALIAS_VERSION(in, su, str, len);
    100          
618             OUTPUT:
619             RETVAL
620              
621             void
622             unparse(in, out)
623             SV * in
624             SV * out
625             PROTOTYPE: $$
626             PREINIT:
627 1200038           dUCXT;
628             INIT:
629             struct_uu_t su;
630 1200038           char *dptr = NULL;
631             CODE:
632             (void)my_cxtp; /* silence warning */
633 1200038 100         UU_ALIAS_UNPARSE_LOWER(in, out, su, dptr);
    50          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    100          
    50          
634              
635             void
636             unparse_lower(in, out)
637             SV * in
638             SV * out
639             PROTOTYPE: $$
640             PREINIT:
641 4           dUCXT;
642             INIT:
643             struct_uu_t su;
644 4           char *dptr = NULL;
645             CODE:
646             (void)my_cxtp; /* silence warning */
647 4 50         UU_ALIAS_UNPARSE_LOWER(in, out, su, dptr);
    100          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    100          
    50          
648              
649             void
650             unparse_upper(in, out)
651             SV * in
652             SV * out
653             PROTOTYPE: $$
654             PREINIT:
655 4           dUCXT;
656             INIT:
657             struct_uu_t su;
658 4           char *dptr = NULL;
659             CODE:
660             (void)my_cxtp; /* silence warning */
661 4 50         UU_ALIAS_UNPARSE_UPPER(in, out, su, dptr);
    50          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    100          
    50          
662              
663             SV *
664             uuid()
665             PROTOTYPE:
666             PREINIT:
667 4           dUCXT;
668             INIT:
669 4           char *dptr = NULL;
670             struct_uu_t su;
671             CODE:
672 4 50         UU_ALIAS_UUID4(su, dptr);
    0          
    0          
    50          
    50          
    50          
    0          
    0          
673             OUTPUT:
674             RETVAL
675              
676             SV *
677             uuid0()
678             PROTOTYPE:
679             PREINIT:
680 14           dUCXT;
681             INIT:
682 14           char *dptr = NULL;
683             struct_uu_t su;
684             CODE:
685 14 50         UU_ALIAS_UUID0(su, dptr);
    0          
    0          
    50          
    50          
    50          
    0          
    0          
686             OUTPUT:
687             RETVAL
688              
689             SV *
690             uuid1()
691             PROTOTYPE:
692             PREINIT:
693 520048           dUCXT;
694             INIT:
695 520048           char *dptr = NULL;
696             struct_uu_t su;
697             CODE:
698 675680 100         UU_ALIAS_UUID1(su, dptr);
    100          
    100          
    50          
    100          
    50          
    0          
    0          
699             OUTPUT:
700             RETVAL
701              
702             SV *
703             uuid3(namespace, name)
704             SV * namespace
705             SV * name
706             PROTOTYPE: $$
707             PREINIT:
708 520029           dUCXT;
709             INIT:
710             char *dptr, *sptr;
711             STRLEN dlen, slen;
712             struct_uu_t su;
713             CODE:
714 520029 50         SvUPGRADE(namespace, SVt_PV);
715 520029 50         SvUPGRADE(name, SVt_PV);
716 520029           sptr = SvPV(namespace, slen);
717 520029           dptr = SvPV(name, dlen);
718              
719 520029 50         if (slen == 36 && !uu_parse(sptr, &su)) {
    0          
720             /* uuid string */
721 0 0         UU_ALIAS_UUID3(su, dptr);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
722             }
723 520029 100         else if (slen == 16) {
724             /* assume binary uuid */
725 3           uu_pack_unpack((unsigned char*)sptr, &su);
726 3 50         UU_ALIAS_UUID3(su, dptr);
    0          
    0          
    50          
    50          
    50          
    0          
    0          
727             }
728 520026 100         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
729 520025 100         && ( (slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t))
    100          
    50          
730 4 100         || (slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t))
    100          
    50          
731 2 100         || (slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t))
    50          
    50          
732 1 50         || (slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t))
    50          
    50          
733             )
734 520025           ) {
735 904536 100         UU_ALIAS_UUID3(su, dptr);
    100          
    100          
    50          
    100          
    50          
    0          
    0          
736             }
737             else { /* slen == 0 ; assume url type */
738 1           CopyD(&UU_namespace_url, &su, 1, struct_uu_t);
739 1 50         UU_ALIAS_UUID3(su, dptr);
    0          
    0          
    50          
    50          
    50          
    0          
    0          
740             }
741             OUTPUT:
742             RETVAL
743              
744             SV *
745             uuid4()
746             PROTOTYPE:
747             PREINIT:
748 520015           dUCXT;
749             INIT:
750 520015           char *dptr = NULL;
751             struct_uu_t su;
752             CODE:
753 584314 100         UU_ALIAS_UUID4(su, dptr);
    100          
    100          
    50          
    100          
    50          
    0          
    0          
754             OUTPUT:
755             RETVAL
756              
757             SV *
758             uuid5(namespace, name)
759             SV * namespace
760             SV * name
761             PROTOTYPE: $$
762             PREINIT:
763 520023           dUCXT;
764             INIT:
765             char *dptr, *sptr;
766             STRLEN dlen, slen;
767             struct_uu_t su;
768             CODE:
769 520023 50         SvUPGRADE(namespace, SVt_PV);
770 520023 50         SvUPGRADE(name, SVt_PV);
771 520023           sptr = SvPV(namespace, slen);
772 520023           dptr = SvPV(name, dlen);
773              
774 520023 50         if (slen == 36 && !uu_parse(sptr, &su)) {
    0          
775             /* uuid string */
776 0 0         UU_ALIAS_UUID5(su, dptr);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
777             }
778 520023 100         else if (slen == 16) {
779             /* assume binary uuid */
780 3           uu_pack_unpack((unsigned char*)sptr, &su);
781 3 50         UU_ALIAS_UUID5(su, dptr);
    0          
    0          
    50          
    50          
    50          
    0          
    0          
782             }
783 520020 100         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
784 520019 50         && ( (slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t))
    100          
    50          
785 1 50         || (slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t))
    50          
    50          
786 0 0         || (slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t))
    0          
    0          
787 0 0         || (slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t))
    0          
    0          
788             )
789 520019           ) {
790 871166 100         UU_ALIAS_UUID5(su, dptr);
    100          
    100          
    50          
    100          
    50          
    0          
    0          
791             }
792             else { /* slen == 0 ; assume url type */
793 1           CopyD(&UU_namespace_url, &su, 1, struct_uu_t);
794 1 50         UU_ALIAS_UUID5(su, dptr);
    0          
    0          
    50          
    50          
    50          
    0          
    0          
795             }
796             OUTPUT:
797             RETVAL
798              
799             SV *
800             uuid6()
801             PROTOTYPE:
802             PREINIT:
803 520036           dUCXT;
804             INIT:
805 520036           char *dptr = NULL;
806             struct_uu_t su;
807             CODE:
808 691392 100         UU_ALIAS_UUID6(su, dptr);
    100          
    100          
    50          
    100          
    50          
    0          
    0          
809             OUTPUT:
810             RETVAL
811              
812             SV *
813             uuid7()
814             PROTOTYPE:
815             PREINIT:
816 520017           dUCXT;
817             INIT:
818 520017           char *dptr = NULL;
819             struct_uu_t su;
820             CODE:
821 688456 100         UU_ALIAS_UUID7(su, dptr);
    100          
    100          
    50          
    100          
    50          
    0          
    0          
822             OUTPUT:
823             RETVAL
824              
825             UV
826             variant(in)
827             SV * in
828             PROTOTYPE: $
829             PREINIT:
830 128 50         dUCXT;
831             INIT:
832             struct_uu_t su;
833             char *str;
834             STRLEN len;
835             CODE:
836             (void)my_cxtp; /* silence warning */
837 128           RETVAL = 0;
838 128 50         if (SvPOK(in)) {
839 128           str = SvPV(in, len);
840 128 50         if (len == sizeof(uu_t)) {
841 128           uu_pack_unpack((unsigned char*)str, &su);
842 128           RETVAL = uu_variant(&su);
843             }
844             }
845             OUTPUT:
846             RETVAL
847              
848             IV
849             version(in)
850             SV * in
851             PROTOTYPE: $
852             PREINIT:
853 11 50         dUCXT;
854             INIT:
855             struct_uu_t su;
856             char *str;
857             STRLEN len;
858             CODE:
859             (void)my_cxtp; /* silence warning */
860 11 100         UU_ALIAS_VERSION(in, su, str, len);
    100          
861             OUTPUT:
862             RETVAL
863              
864              
865             #ifdef ONLY_FOR_DEV
866             void
867             _dump_struct()
868             PROTOTYPE:
869             PREINIT:
870             dUCXT;
871             INIT:
872             my_cxt_t *cxt = my_cxtp;
873             shared_mem_t *smem = cxt->shared;
874             PPCODE:
875             UV o = PTR2UV(&smem->LOCK);
876             warn("============== shared_mem_t ==============\n");
877              
878             warn("LOCK .................. 0x%p %" UVuf "\n", &smem->LOCK , PTR2UV(&smem->LOCK ) - o);
879             warn("__pad0 ................ 0x%p %" UVuf "\n", &smem->__pad0 , PTR2UV(&smem->__pad0 ) - o);
880             UV len0 = sizeof(smem->LOCK) + sizeof(smem->__pad0);
881             UV pages0 = len0 / 64; if (len0 % 64) ++pages0;
882             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len0, pages0, pages0*64);
883              
884             warn("clock_last ............ 0x%p %" UVuf "\n", &smem->clock_last , PTR2UV(&smem->clock_last ) - o);
885             warn(" clock_last.tv_sec ... 0x%p %" UVuf "\n", &smem->clock_last.tv_sec , PTR2UV(&smem->clock_last.tv_sec ) - o);
886             warn(" clock_last.tv_usec .. 0x%p %" UVuf "\n", &smem->clock_last.tv_usec , PTR2UV(&smem->clock_last.tv_usec) - o);
887             warn("clock_prev_reg ........ 0x%p %" UVuf "\n", &smem->clock_prev_reg , PTR2UV(&smem->clock_prev_reg ) - o);
888             warn("clock_defer_100ns ..... 0x%p %" UVuf "\n", &smem->clock_defer_100ns , PTR2UV(&smem->clock_defer_100ns ) - o);
889             warn("clock_adj ............. 0x%p %" UVuf "\n", &smem->clock_adj , PTR2UV(&smem->clock_adj ) - o);
890             warn("clock_seq ............. 0x%p %" UVuf "\n", &smem->clock_seq , PTR2UV(&smem->clock_seq ) - o);
891             warn("__pad1 ................ 0x%p %" UVuf "\n", &smem->__pad1 , PTR2UV(&smem->__pad1 ) - o);
892             UV len1 = sizeof(smem->clock_last) + sizeof(smem->clock_prev_reg) + sizeof(smem->clock_defer_100ns)
893             + sizeof(smem->clock_adj) + sizeof(smem->clock_seq) + sizeof(smem->__pad1);
894             UV pages1 = len1 / 64; if (len1 % 64) ++pages1;
895             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len1, pages1, pages1*64);
896              
897             warn("gen_epoch ............. 0x%p %" UVuf "\n", &smem->gen_epoch , PTR2UV(&smem->gen_epoch ) - o);
898             warn("gen_node .............. 0x%p %" UVuf "\n", &smem->gen_node , PTR2UV(&smem->gen_node ) - o);
899             warn("gen_has_real_node ..... 0x%p %" UVuf "\n", &smem->gen_has_real_node , PTR2UV(&smem->gen_has_real_node ) - o);
900             warn("gen_real_node ......... 0x%p %" UVuf "\n", &smem->gen_real_node , PTR2UV(&smem->gen_real_node ) - o);
901             warn("gen_use_unique ........ 0x%p %" UVuf "\n", &smem->gen_use_unique , PTR2UV(&smem->gen_use_unique ) - o);
902             warn("__pad2 ................ 0x%p %" UVuf "\n", &smem->__pad2 , PTR2UV(&smem->__pad2 ) - o);
903             UV len2 = sizeof(smem->gen_epoch) + sizeof(smem->gen_node) + sizeof(smem->gen_has_real_node)
904             + sizeof(smem->gen_real_node) + sizeof(smem->gen_use_unique) + sizeof(smem->__pad2);
905             UV pages2 = len2 / 64; if (len2 % 64) ++pages2;
906             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len2, pages2, pages2*64);
907              
908             warn("cc .................... 0x%p %" UVuf "\n", &smem->cc , PTR2UV(&smem->cc ) - o);
909             warn(" cc.state ............ 0x%p %" UVuf "\n", &smem->cc.state , PTR2UV(&smem->cc.state ) - o);
910             warn(" cc.buf .............. 0x%p %" UVuf "\n", &smem->cc.buf , PTR2UV(&smem->cc.buf ) - o);
911             warn(" cc.have ............. 0x%p %" UVuf "\n", &smem->cc.have , PTR2UV(&smem->cc.have ) - o);
912             warn(" cc.__align .......... 0x%p %" UVuf "\n", &smem->cc.__align , PTR2UV(&smem->cc.__align ) - o);
913             warn("xo_s .................. 0x%p %" UVuf "\n", &smem->xo_s , PTR2UV(&smem->xo_s ) - o);
914             warn("sm_x .................. 0x%p %" UVuf "\n", &smem->sm_x , PTR2UV(&smem->sm_x ) - o);
915             warn("__pad3 ................ 0x%p %" UVuf "\n", &smem->__pad3 , PTR2UV(&smem->__pad3 ) - o);
916             UV len3 = sizeof(smem->cc) + sizeof(smem->xo_s) + sizeof(smem->sm_x) + sizeof(smem->__pad3);
917             UV pages3 = len3 / 64; if (len3 % 64) ++pages3;
918             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len3, pages3, pages3*64);
919              
920             warn("clock_persist ......... 0x%p %" UVuf "\n", &smem->clock_persist , PTR2UV(&smem->clock_persist ) - o);
921             warn(" clock_persist.len ... 0x%p %" UVuf "\n", &smem->clock_persist.len , PTR2UV(&smem->clock_persist.len ) - o);
922             warn(" clock_persist.path .. 0x%p %" UVuf "\n", &smem->clock_persist.path , PTR2UV(&smem->clock_persist.path) - o);
923             UV len4 = sizeof(smem->clock_persist);
924             UV pages4 = len4 / 64; if (len4 % 64) ++pages4;
925             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len4, pages4, pages4*64);
926              
927             warn("shared_mem_t size : %lu\n\n", sizeof(shared_mem_t));
928              
929             warn("============== my_cxt_t ==============\n");
930             o = PTR2UV(&cxt->shared);
931             warn("shared ................ 0x%p %" UVuf "\n", &cxt->shared , PTR2UV(&cxt->shared ) - o);
932             warn("shared_len ............ 0x%p %" UVuf "\n", &cxt->shared_len , PTR2UV(&cxt->shared_len ) - o);
933             warn("clock_state_f ......... 0x%p %" UVuf "\n", &cxt->clock_state_f , PTR2UV(&cxt->clock_state_f ) - o);
934             warn("clock_state_fd ........ 0x%p %" UVuf "\n", &cxt->clock_state_fd , PTR2UV(&cxt->clock_state_fd ) - o);
935             warn("__pad5 ................ 0x%p %" UVuf "\n", &cxt->__pad5 , PTR2UV(&cxt->__pad5 ) - o);
936             UV len5 = sizeof(cxt->shared) + sizeof(cxt->shared_len) + sizeof(cxt->clock_state_f)
937             + sizeof(cxt->clock_state_fd) + sizeof(cxt->__pad5);
938             UV pages5 = len5 / 64; if (len5 % 64) ++pages5;
939             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len5, pages5, pages5*64);
940              
941             warn("clock_persist ......... 0x%p %" UVuf "\n", &cxt->clock_persist , PTR2UV(&cxt->clock_persist ) - o);
942             warn(" clock_persist.len ... 0x%p %" UVuf "\n", &cxt->clock_persist.len , PTR2UV(&cxt->clock_persist.len ) - o);
943             warn(" clock_persist.path .. 0x%p %" UVuf "\n", &cxt->clock_persist.path , PTR2UV(&cxt->clock_persist.path) - o);
944             UV len6 = sizeof(cxt->clock_persist);
945             UV pages6 = len6 / 64; if (len6 % 64) ++pages6;
946             warn("---- %" UVuf " bytes ; %" UVuf " * 64 = %" UVuf " bytes ----\n", len6, pages6, pages6*64);
947              
948             warn("my_cxt_t size : %lu\n\n", sizeof(my_cxt_t));
949             warn("uu_mutex: %lu\n", sizeof(uu_mutex));
950              
951             #endif