File Coverage

UUID.xs
Criterion Covered Total %
statement 216 233 92.7
branch 283 560 50.5
condition n/a
subroutine n/a
pod n/a
total 499 793 62.9


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             #include "ulib/UUID.h"
13             #include "XSUB.h"
14             #include "ulib/chacha.h"
15             #include "ulib/clear.h"
16             #include "ulib/clock.h"
17             #include "ulib/compare.h"
18             #include "ulib/gen.h"
19             #include "ulib/isnull.h"
20             #include "ulib/md5.h"
21             #include "ulib/pack.h"
22             #include "ulib/parse.h"
23             #include "ulib/sha1.h"
24             #include "ulib/splitmix.h"
25             #include "ulib/unpack.h"
26             #include "ulib/unparse.h"
27             #include "ulib/util.h"
28             #include "ulib/xoshiro.h"
29              
30             #ifdef __cplusplus
31             }
32             #endif
33              
34             /* 2 hex digits per byte + 4 separators */
35             #define UUID_BUFFSZ 36
36              
37              
38             #define MY_CXT_KEY "UUID::_guts" XS_VERSION
39             /* my_cxt_t global typedef lives in TYPE.h */
40             START_MY_CXT
41              
42              
43             #ifdef USE_ITHREADS
44             # define UMTX_DECL STATIC perl_mutex UU_LOCK
45             # define UMTX_INIT MUTEX_INIT(&UU_LOCK)
46             # define UMTX_LOCK MUTEX_LOCK(&UU_LOCK)
47             # define UMTX_UNLOCK MUTEX_UNLOCK(&UU_LOCK)
48             #else
49             # define UMTX_DECL dNOOP
50             # define UMTX_INIT NOOP
51             # define UMTX_LOCK NOOP
52             # define UMTX_UNLOCK NOOP
53             #endif
54             UMTX_DECL;
55              
56              
57             #ifdef PERL_IMPLICIT_CONTEXT
58             # define dUCXT dMY_CXT
59             # define UCXT_INIT MY_CXT_INIT
60             #else
61             # define dUCXT my_cxt_t *my_cxtp = &my_cxt;
62             # define UCXT_INIT my_cxt_t *my_cxtp = &my_cxt;
63             #endif
64              
65             #define UU_GEN_TMPL(ver, out, su, dptr) \
66             SV_CHECK_THINKFIRST_COW_DROP(out); \
67             if (isGV_with_GP(out)) \
68             croak("%s", PL_no_modify); \
69             SvUPGRADE(out, SVt_PV); \
70             UMTX_LOCK; \
71             uu_v ## ver ## gen(aUCXT, &su, dptr); \
72             UMTX_UNLOCK; \
73             dptr = SvGROW(out, sizeof(uu_t)+1); \
74             uu_pack##ver(&su, (U8*)dptr); \
75             dptr[sizeof(uu_t)] = '\0'; \
76             SvCUR_set(out, sizeof(uu_t)); \
77             (void)SvPOK_only(out); \
78             if (SvTYPE(out) == SVt_PVCV) \
79             CvAUTOLOAD_off(out);
80              
81             #define UU_ALIAS_GEN_V0(out, su, dptr) UU_GEN_TMPL(0, out, su, dptr)
82             #define UU_ALIAS_GEN_V1(out, su, dptr) UU_GEN_TMPL(1, out, su, dptr)
83             #define UU_ALIAS_GEN_V3(out, su, dptr) UU_GEN_TMPL(3, out, su, dptr)
84             #define UU_ALIAS_GEN_V4(out, su, dptr) UU_GEN_TMPL(4, out, su, dptr)
85             #define UU_ALIAS_GEN_V5(out, su, dptr) UU_GEN_TMPL(5, out, su, dptr)
86             #define UU_ALIAS_GEN_V6(out, su, dptr) UU_GEN_TMPL(6, out, su, dptr)
87             #define UU_ALIAS_GEN_V7(out, su, dptr) UU_GEN_TMPL(7, out, su, dptr)
88              
89              
90             #define UU_UNPARSE_TMPL(case, in, out, su, dptr) \
91             if (SvPOK(in)) { \
92             dptr = SvGROW(in, sizeof(uu_t)); \
93             uu_unpack((unsigned char*)dptr, &su); \
94             SV_CHECK_THINKFIRST_COW_DROP(out); \
95             if (isGV_with_GP(out)) \
96             croak("%s", PL_no_modify); \
97             SvUPGRADE(out, SVt_PV); \
98             SvPOK_only(out); \
99             dptr = SvGROW(out, UUID_BUFFSZ+1); \
100             uu_unparse_ ## case ## er1(&su, dptr); \
101             dptr[UUID_BUFFSZ] = '\0'; \
102             SvCUR_set(out, UUID_BUFFSZ); \
103             (void)SvPOK_only(out); \
104             if (SvTYPE(out) == SVt_PVCV) \
105             CvAUTOLOAD_off(out); \
106             }
107              
108             #define UU_ALIAS_UNPARSE_LOWER(in, out, su, dptr) UU_UNPARSE_TMPL(low, in, out, su, dptr)
109             #define UU_ALIAS_UNPARSE_UPPER(in, out, su, dptr) UU_UNPARSE_TMPL(upp, in, out, su, dptr)
110              
111              
112             #define UU_UUID_TMPL(ver, su, dptr) \
113             UMTX_LOCK; \
114             uu_v ## ver ## gen(aUCXT, &su, dptr); \
115             UMTX_UNLOCK; \
116             RETVAL = newSV(UUID_BUFFSZ+1); \
117             dptr = SvPVX(RETVAL); \
118             uu_unparse##ver(&su, dptr); \
119             dptr[UUID_BUFFSZ] = '\0'; \
120             SvCUR_set(RETVAL, UUID_BUFFSZ); \
121             SvPOK_only(RETVAL);
122              
123             #define UU_ALIAS_UUID0(su, dptr) UU_UUID_TMPL(0, su, dptr)
124             #define UU_ALIAS_UUID1(su, dptr) UU_UUID_TMPL(1, su, dptr)
125             #define UU_ALIAS_UUID3(su, dptr) UU_UUID_TMPL(3, su, dptr)
126             #define UU_ALIAS_UUID4(su, dptr) UU_UUID_TMPL(4, su, dptr)
127             #define UU_ALIAS_UUID5(su, dptr) UU_UUID_TMPL(5, su, dptr)
128             #define UU_ALIAS_UUID6(su, dptr) UU_UUID_TMPL(6, su, dptr)
129             #define UU_ALIAS_UUID7(su, dptr) UU_UUID_TMPL(7, su, dptr)
130              
131              
132             #define UU_ALIAS_VERSION(in, su, str, len) \
133             RETVAL = -1; \
134             if (SvPOK(in)) { \
135             str = SvPV(in, len); \
136             if (len == sizeof(uu_t)) { \
137             uu_unpack((unsigned char*)str, &su); \
138             RETVAL = uu_type(&su); \
139             } \
140             }
141              
142             const struct_uu_t UU_namespace_dns = { 0x6ba7b810, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
143             const struct_uu_t UU_namespace_url = { 0x6ba7b811, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
144             const struct_uu_t UU_namespace_oid = { 0x6ba7b812, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
145             const struct_uu_t UU_namespace_x500 = { 0x6ba7b814, 0x9dad, 0x11d1, 0x80b4, {0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}};
146              
147              
148             MODULE = UUID PACKAGE = UUID
149              
150              
151             BOOT:
152             UMTX_INIT;
153             UMTX_LOCK;
154             {
155 156           UCXT_INIT;
156             SV **svp;
157              
158 156           UCXT.cc.pid = 0;
159 156           UCXT.thread_id = 0;
160              
161 156           svp = hv_fetchs(PL_modglobal, "Time::U2time", 0);
162 156 50         if (!svp) croak("Time::HiRes is required");
163 156 50         if (!SvIOK(*svp)) croak("Time::U2time isn't a function pointer");
164 156           UCXT.myU2time = INT2PTR(void(*)(pTHX_ UV ret[2]), SvIV(*svp));
165             if (0) { /* test */
166             UV xx[2];
167             (*UCXT.myU2time)(aTHX_ (UV*)&xx);
168             printf("The current seconds are: %" UVuf ".%06" UVuf "\n", xx[0], xx[1]);
169             exit(0);
170             }
171              
172 156           uu_clock_init(aUCXT);
173 156           uu_gen_init(aUCXT);
174             }
175             UMTX_UNLOCK;
176              
177              
178             void
179             _hide_always()
180             PROTOTYPE:
181             PREINIT:
182 2           dUCXT;
183             PPCODE:
184             UMTX_LOCK;
185 2           uu_gen_setuniq(aUCXT);
186             UMTX_UNLOCK;
187              
188             void
189             _hide_mac()
190             PROTOTYPE:
191             PREINIT:
192 8           dUCXT;
193             PPCODE:
194             UMTX_LOCK;
195 8           uu_gen_setrand(aUCXT);
196             UMTX_UNLOCK;
197              
198             SV *
199             _persist(...)
200             PROTOTYPE: @
201             PREINIT:
202 27           dUCXT;
203             INIT:
204             struct_pathlen_t sp;
205             char *ptr;
206             SV *sv;
207             CODE:
208 27 100         if (items > 1)
209 1           croak("Usage: _persist([path/to/file])");
210 26 100         if (items == 0) {
211             UMTX_LOCK;
212 6           uu_clock_getpath(aUCXT, &sp);
213             UMTX_UNLOCK;
214 6           RETVAL = newSVpvn(sp.path, sp.len);
215             }
216             else { /* items == 1 */
217 20 100         if (SvTRUE(ST(0))) {
218 14           sv = ST(0);
219 14           ptr = SvPV(sv, sp.len);
220 14           Newz(0, sp.path, sp.len+1, char);
221 14           Copy(ptr, sp.path, sp.len, char);
222             UMTX_LOCK;
223 14           uu_clock_setpath(aUCXT, &sp);
224             UMTX_UNLOCK;
225             }
226             else {
227 6           sp.path = NULL;
228 6           sp.len = 0;
229             UMTX_LOCK;
230 6           uu_clock_setpath(aUCXT, &sp);
231             UMTX_UNLOCK;
232             }
233 20           RETVAL = &PL_sv_yes;
234             }
235             OUTPUT:
236             RETVAL
237              
238             SV *
239             _realnode()
240             PROTOTYPE:
241             PREINIT:
242 154           dUCXT;
243             INIT:
244             int rv;
245             char *dptr;
246             struct_uu_t su;
247             CODE:
248             UMTX_LOCK;
249 154           rv = uu_realnode(aUCXT, &su);
250             UMTX_UNLOCK;
251 154 50         if (rv) {
252 154           RETVAL = newSV(UUID_BUFFSZ+1);
253 154           dptr = SvPVX(RETVAL);
254 154           uu_unparse0(&su, dptr);
255 154           dptr[UUID_BUFFSZ] = '\0';
256 154           SvCUR_set(RETVAL, UUID_BUFFSZ);
257 154           SvPOK_only(RETVAL);
258             }
259             else
260 0           RETVAL = &PL_sv_no;
261             OUTPUT:
262             RETVAL
263              
264             SV *
265             _defer(...)
266             PROTOTYPE: @
267             PREINIT:
268 15           dUCXT;
269             INIT:
270             SV *duration;
271             CODE:
272 15 100         if (items == 0) {
273 6           RETVAL = newSVnv(UCXT.clock_defer_100ns / 10000000.0);
274             }
275 9 100         else if (items == 1) {
276 8           duration = ST(0);
277 8 100         if (!looks_like_number(duration))
278 1           croak_caller("Non-numeric :defer argument");
279             UMTX_LOCK;
280 7           UCXT.clock_defer_100ns = (U64)(SvNV(duration) * 10000000.0);
281             UMTX_UNLOCK;
282 7           RETVAL = &PL_sv_yes;
283             }
284             else
285 1           croak("Too many arguments for _defer()");
286             OUTPUT:
287             RETVAL
288              
289             void
290             clear(io)
291             SV * io
292             PROTOTYPE: $
293             PREINIT:
294 9           dUCXT;
295             INIT:
296             struct_uu_t su;
297 9           char *dptr = NULL;
298             CODE:
299 9 100         UU_ALIAS_GEN_V0(io, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
300              
301             IV
302             compare(in1, in2)
303             SV * in1
304             SV * in2
305             PROTOTYPE: $$
306             PREINIT:
307 417 50         dUCXT;
308             INIT:
309             STRLEN len1, len2;
310             CODE:
311 417 100         if (SvPOK(in1) && SvPOK(in2)
    100          
312 403 100         && SvCUR(in1) == sizeof(uu_t)
313 300 100         && SvCUR(in2) == sizeof(uu_t))
314 296           RETVAL = uu_cmp_binary(
315 296           (U8*)SvPV_force(in1, len1),
316 296           (U8*)SvPV_force(in2, len2)
317             );
318 121 100         else if (!SvOK(in1))
319 7 100         RETVAL = SvOK(in2) ? -1 : 0;
320 114 100         else if (!SvOK(in2))
321 5           RETVAL = 1;
322             else
323 109           RETVAL = sv_cmp(in1, in2);
324             OUTPUT:
325             RETVAL
326              
327             void
328             copy(out, in)
329             SV * out
330             SV * in
331             PROTOTYPE: $$
332             PREINIT:
333 13           dUCXT;
334             INIT:
335             struct_uu_t su;
336             STRLEN len;
337             char *dptr;
338             CODE:
339 13 100         if (!SvPOK(in) || SvCUR(in) != sizeof(uu_t))
    100          
340 6           uu_clear(&su);
341             else
342 7           uu_unpack((U8*)SvPV_force(in, len), &su);
343 13 100         SV_CHECK_THINKFIRST_COW_DROP(out);
344 13 50         if (isGV_with_GP(out))
    0          
    0          
345 0           croak("%s", PL_no_modify);
346 13 100         SvUPGRADE(out, SVt_PV);
347 13 50         dptr = SvGROW(out, sizeof(uu_t)+1);
    100          
348 13           uu_pack1(&su, (U8*)dptr);
349 13           dptr[sizeof(uu_t)] = '\0';
350 13           SvCUR_set(out, sizeof(uu_t));
351 13           (void)SvPOK_only(out);
352 13 50         if (SvTYPE(out) == SVt_PVCV)
353 0           CvAUTOLOAD_off(out);
354              
355             void
356             generate(out)
357             SV * out
358             PROTOTYPE: $
359             PREINIT:
360 13           dUCXT;
361             INIT:
362 13           char *dptr = NULL;
363             struct_uu_t su;
364             CODE:
365 13 100         UU_ALIAS_GEN_V4(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
366              
367             void
368             generate_random(out)
369             SV * out
370             PROTOTYPE: $
371             PREINIT:
372 6           dUCXT;
373             INIT:
374 6           char *dptr = NULL;
375             struct_uu_t su;
376             CODE:
377 6 50         UU_ALIAS_GEN_V4(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
378              
379             void
380             generate_time(out)
381             SV * out
382             PROTOTYPE: $
383             PREINIT:
384 14           dUCXT;
385             INIT:
386 14           char *dptr = NULL;
387             struct_uu_t su;
388             CODE:
389 14 50         UU_ALIAS_GEN_V1(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
390              
391             void
392             generate_v0(out)
393             SV * out
394             PROTOTYPE: $
395             PREINIT:
396 17           dUCXT;
397             INIT:
398 17           char *dptr = NULL;
399             struct_uu_t su;
400             CODE:
401 17 50         UU_ALIAS_GEN_V0(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    50          
    50          
402              
403             void
404             generate_v1(out)
405             SV * out
406             PROTOTYPE: $
407             PREINIT:
408 120           dUCXT;
409             INIT:
410 120           char *dptr = NULL;
411             struct_uu_t su;
412             CODE:
413 120 50         UU_ALIAS_GEN_V1(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
414              
415             void
416             generate_v3(out, namespace, name)
417             SV * out
418             SV * namespace
419             SV * name
420             PROTOTYPE: $$$
421             PREINIT:
422 124           dUCXT;
423             INIT:
424             char *dptr, *sptr;
425             STRLEN dlen, slen;
426             struct_uu_t su;
427             CODE:
428 124 50         SvUPGRADE(namespace, SVt_PV);
429 124 50         SvUPGRADE(name, SVt_PV);
430 124           sptr = SvPV(namespace, slen);
431 124           dptr = SvPV(name, dlen);
432              
433 124 100         if (slen == 36 && !uu_parse(sptr, &su)) {
    50          
434             /* uuid string */
435 3 50         UU_ALIAS_GEN_V3(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    50          
    50          
436             }
437 121 50         else if (slen == 16) {
438             /* assume binary uuid */
439 0           uu_unpack((unsigned char*)sptr, &su);
440 0 0         UU_ALIAS_GEN_V3(out, su, dptr);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
441             }
442 121 50         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
443 121 50         && ( slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t)
    100          
    50          
444 1 50         || slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t)
    50          
    50          
445 0 0         || slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t)
    0          
    0          
446 0 0         || slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t)
    0          
    0          
447             )
448             ) {
449 121 50         UU_ALIAS_GEN_V3(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
450             }
451              
452             void
453             generate_v4(out)
454             SV * out
455             PROTOTYPE: $
456             PREINIT:
457 118           dUCXT;
458             INIT:
459 118           char *dptr = NULL;
460             struct_uu_t su;
461             CODE:
462 118 50         UU_ALIAS_GEN_V4(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
463              
464             void
465             generate_v5(out, namespace, name)
466             SV * out
467             SV * namespace
468             SV * name
469             PROTOTYPE: $$$
470             PREINIT:
471 124           dUCXT;
472             INIT:
473             char *dptr, *sptr;
474             STRLEN dlen, slen;
475             struct_uu_t su;
476             CODE:
477 124 50         SvUPGRADE(namespace, SVt_PV);
478 124 50         SvUPGRADE(name, SVt_PV);
479 124           sptr = SvPV(namespace, slen);
480 124           dptr = SvPV(name, dlen);
481              
482 124 100         if (slen == 36 && !uu_parse(sptr, &su)) {
    50          
483             /* uuid string */
484 3 50         UU_ALIAS_GEN_V5(out, su, dptr);
    50          
    0          
    0          
    50          
    50          
    50          
    50          
485             }
486 121 50         else if (slen == 16) {
487             /* assume binary uuid */
488 0           uu_unpack((unsigned char*)sptr, &su);
489 0 0         UU_ALIAS_GEN_V5(out, su, dptr);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
490             }
491 121 50         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
492 121 50         && ( slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t)
    100          
    50          
493 1 50         || slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t)
    50          
    50          
494 0 0         || slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t)
    0          
    0          
495 0 0         || slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t)
    0          
    0          
496             )
497             ) {
498 121 50         UU_ALIAS_GEN_V5(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
499             }
500              
501             void
502             generate_v6(out)
503             SV * out
504             PROTOTYPE: $
505             PREINIT:
506 118           dUCXT;
507             INIT:
508 118           char *dptr = NULL;
509             struct_uu_t su;
510             CODE:
511 118 50         UU_ALIAS_GEN_V6(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
512              
513             void
514             generate_v7(out)
515             SV * out
516             PROTOTYPE: $
517             PREINIT:
518 118           dUCXT;
519             INIT:
520 118           char *dptr = NULL;
521             struct_uu_t su;
522             CODE:
523 118 50         UU_ALIAS_GEN_V7(out, su, dptr);
    50          
    0          
    0          
    100          
    50          
    100          
    50          
524              
525             IV
526             is_null(in)
527             SV * in
528             PROTOTYPE: $
529             PREINIT:
530 120 50         dUCXT;
531             INIT:
532             STRLEN len;
533             CODE:
534 120 100         if (!SvPOK(in))
535 2           RETVAL = 0;
536 118 100         else if (SvCUR(in) != sizeof(uu_t))
537 5           RETVAL = 0;
538             else
539 113           RETVAL = uu_isnull_binary((U8*)SvPV(in, len));
540             OUTPUT:
541             RETVAL
542              
543             IV
544             parse(in, out)
545             SV * in
546             SV * out
547             PROTOTYPE: $$
548             PREINIT:
549 48 50         dUCXT;
550             INIT:
551             char *dptr;
552             struct_uu_t su;
553             CODE:
554             /* XXX might see uninitialized data */
555 48           RETVAL = -1;
556 48 100         if (SvPOK(in) && !uu_parse(SvGROW(in, UUID_BUFFSZ+1), &su)) {
    100          
    50          
    100          
557 38 100         SV_CHECK_THINKFIRST_COW_DROP(out);
558 38 50         if (isGV_with_GP(out))
    0          
    0          
559 0           croak("%s", PL_no_modify);
560 38 100         SvUPGRADE(out, SVt_PV);
561 38 50         dptr = SvGROW(out, sizeof(uu_t)+1);
    100          
562 38           uu_pack1(&su, (U8*)dptr);
563 38           dptr[sizeof(uu_t)] = '\0';
564 38           SvCUR_set(out, sizeof(uu_t));
565 38           (void)SvPOK_only(out);
566 38 50         if (SvTYPE(out) == SVt_PVCV)
567 0           CvAUTOLOAD_off(out);
568 38           RETVAL = 0;
569             }
570             OUTPUT:
571             RETVAL
572              
573             NV
574             time(in)
575             SV * in
576             PROTOTYPE: $
577             PREINIT:
578 9 50         dUCXT;
579             INIT:
580             struct_uu_t su;
581             char *str;
582             STRLEN len;
583             CODE:
584 9           RETVAL = 0;
585 9 50         if (SvPOK(in)) {
586 9           str = SvPV(in, len);
587 9 50         if (len == sizeof(uu_t)) {
588 9           uu_unpack((U8*)str, &su);
589 9           RETVAL = uu_time(&su);
590             }
591             }
592             OUTPUT:
593             RETVAL
594              
595             IV
596             type(in)
597             SV * in
598             PROTOTYPE: $
599             PREINIT:
600 112 50         dUCXT;
601             INIT:
602             struct_uu_t su;
603             char *str;
604             STRLEN len;
605             CODE:
606 112 100         UU_ALIAS_VERSION(in, su, str, len);
    100          
607             OUTPUT:
608             RETVAL
609              
610             void
611             unparse(in, out)
612             SV * in
613             SV * out
614             PROTOTYPE: $$
615             PREINIT:
616 632           dUCXT;
617             INIT:
618             struct_uu_t su;
619 632           char *dptr = NULL;
620             CODE:
621 632 100         UU_ALIAS_UNPARSE_LOWER(in, out, su, dptr);
    50          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    100          
    50          
622              
623             void
624             unparse_lower(in, out)
625             SV * in
626             SV * out
627             PROTOTYPE: $$
628             PREINIT:
629 4           dUCXT;
630             INIT:
631             struct_uu_t su;
632 4           char *dptr = NULL;
633             CODE:
634 4 50         UU_ALIAS_UNPARSE_LOWER(in, out, su, dptr);
    100          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    100          
    50          
635              
636             void
637             unparse_upper(in, out)
638             SV * in
639             SV * out
640             PROTOTYPE: $$
641             PREINIT:
642 4           dUCXT;
643             INIT:
644             struct_uu_t su;
645 4           char *dptr = NULL;
646             CODE:
647 4 50         UU_ALIAS_UNPARSE_UPPER(in, out, su, dptr);
    50          
    50          
    100          
    50          
    0          
    0          
    100          
    50          
    100          
    50          
648              
649             SV *
650             uuid()
651             PROTOTYPE:
652             PREINIT:
653 4           dUCXT;
654             INIT:
655 4           char *dptr = NULL;
656             struct_uu_t su;
657             CODE:
658 4           UU_ALIAS_UUID4(su, dptr);
659             OUTPUT:
660             RETVAL
661              
662             SV *
663             uuid0()
664             PROTOTYPE:
665             PREINIT:
666 14           dUCXT;
667             INIT:
668 14           char *dptr = NULL;
669             struct_uu_t su;
670             CODE:
671 14           UU_ALIAS_UUID0(su, dptr);
672             OUTPUT:
673             RETVAL
674              
675             SV *
676             uuid1()
677             PROTOTYPE:
678             PREINIT:
679 48           dUCXT;
680             INIT:
681 48           char *dptr = NULL;
682             struct_uu_t su;
683             CODE:
684 48           UU_ALIAS_UUID1(su, dptr);
685             OUTPUT:
686             RETVAL
687              
688             SV *
689             uuid3(namespace, name)
690             SV * namespace
691             SV * name
692             PROTOTYPE: $$
693             PREINIT:
694 28           dUCXT;
695             INIT:
696             char *dptr, *sptr;
697             STRLEN dlen, slen;
698             struct_uu_t su;
699             CODE:
700 28 50         SvUPGRADE(namespace, SVt_PV);
701 28 50         SvUPGRADE(name, SVt_PV);
702 28           sptr = SvPV(namespace, slen);
703 28           dptr = SvPV(name, dlen);
704              
705 28 50         if (slen == 36 && !uu_parse(sptr, &su)) {
    0          
706             /* uuid string */
707 0           UU_ALIAS_UUID3(su, dptr);
708             }
709 28 100         else if (slen == 16) {
710             /* assume binary uuid */
711 3           uu_unpack((unsigned char*)sptr, &su);
712 3           UU_ALIAS_UUID3(su, dptr);
713             }
714 25 50         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
715 25 100         && ( slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t)
    100          
    50          
716 4 100         || slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t)
    100          
    50          
717 2 100         || slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t)
    50          
    50          
718 1 50         || slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t)
    50          
    50          
719             )
720             ) {
721 25           UU_ALIAS_UUID3(su, dptr);
722             }
723             OUTPUT:
724             RETVAL
725              
726             SV *
727             uuid4()
728             PROTOTYPE:
729             PREINIT:
730 1315           dUCXT;
731             INIT:
732 1315           char *dptr = NULL;
733             struct_uu_t su;
734             CODE:
735 1315           UU_ALIAS_UUID4(su, dptr);
736             OUTPUT:
737             RETVAL
738              
739             SV *
740             uuid5(namespace, name)
741             SV * namespace
742             SV * name
743             PROTOTYPE: $$
744             PREINIT:
745 22           dUCXT;
746             INIT:
747             char *dptr, *sptr;
748             STRLEN dlen, slen;
749             struct_uu_t su;
750             CODE:
751 22 50         SvUPGRADE(namespace, SVt_PV);
752 22 50         SvUPGRADE(name, SVt_PV);
753 22           sptr = SvPV(namespace, slen);
754 22           dptr = SvPV(name, dlen);
755              
756 22 50         if (slen == 36 && !uu_parse(sptr, &su)) {
    0          
757             /* uuid string */
758 0           UU_ALIAS_UUID5(su, dptr);
759             }
760 22 100         else if (slen == 16) {
761             /* assume binary uuid */
762 3           uu_unpack((unsigned char*)sptr, &su);
763 3           UU_ALIAS_UUID5(su, dptr);
764             }
765 19 50         else if (slen > 0 /* ibcmp first appears in v5.7.3 */
766 19 50         && ( slen == 3 && !ibcmp(sptr, "dns", (I32)slen) && CopyD(&UU_namespace_dns, &su, 1, struct_uu_t)
    100          
    50          
767 1 50         || slen == 3 && !ibcmp(sptr, "url", (I32)slen) && CopyD(&UU_namespace_url, &su, 1, struct_uu_t)
    50          
    50          
768 0 0         || slen == 3 && !ibcmp(sptr, "oid", (I32)slen) && CopyD(&UU_namespace_oid, &su, 1, struct_uu_t)
    0          
    0          
769 0 0         || slen == 4 && !ibcmp(sptr, "x500", (I32)slen) && CopyD(&UU_namespace_x500, &su, 1, struct_uu_t)
    0          
    0          
770             )
771             ) {
772 19           UU_ALIAS_UUID5(su, dptr);
773             }
774             OUTPUT:
775             RETVAL
776              
777             SV *
778             uuid6()
779             PROTOTYPE:
780             PREINIT:
781 36           dUCXT;
782             INIT:
783 36           char *dptr = NULL;
784             struct_uu_t su;
785             CODE:
786 36           UU_ALIAS_UUID6(su, dptr);
787             OUTPUT:
788             RETVAL
789              
790             SV *
791             uuid7()
792             PROTOTYPE:
793             PREINIT:
794 17           dUCXT;
795             INIT:
796 17           char *dptr = NULL;
797             struct_uu_t su;
798             CODE:
799 17           UU_ALIAS_UUID7(su, dptr);
800             OUTPUT:
801             RETVAL
802              
803             UV
804             variant(in)
805             SV * in
806             PROTOTYPE: $
807             PREINIT:
808 122 50         dUCXT;
809             INIT:
810             struct_uu_t su;
811             char *str;
812             STRLEN len;
813             CODE:
814 122           RETVAL = 0;
815 122 50         if (SvPOK(in)) {
816 122           str = SvPV(in, len);
817 122 50         if (len == sizeof(uu_t)) {
818 122           uu_unpack((unsigned char*)str, &su);
819 122           RETVAL = uu_variant(&su);
820             }
821             }
822             OUTPUT:
823             RETVAL
824              
825             IV
826             version(in)
827             SV * in
828             PROTOTYPE: $
829             PREINIT:
830 11 50         dUCXT;
831             INIT:
832             struct_uu_t su;
833             char *str;
834             STRLEN len;
835             CODE:
836 11 100         UU_ALIAS_VERSION(in, su, str, len);
    100          
837             OUTPUT:
838             RETVAL
839              
840             #ifdef WE_DONT_NEED_NO_STINKIN_BADGES
841             #
842             # CLONE'ing.
843             # It has been deemed appropriate to maintain the
844             # default behavior, which is to share the initial
845             # context between all threads.
846             #
847             # Without sharing the context, each thread becomes an
848             # independent generator and would need some other
849             # (shared) method to keep it from trampling on the
850             # others.
851             #
852             #if defined(USE_ITHREADS) && defined(MY_CXT_KEY)
853              
854             void
855             CLONE(...)
856             CODE:
857             MY_CXT_CLONE;
858             ++UCXT.thread_id;
859              
860             #endif
861             #endif
862