File Coverage

UUID.xs
Criterion Covered Total %
statement 241 259 93.0
branch 351 850 41.2
condition n/a
subroutine n/a
pod n/a
total 592 1109 53.3


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