File Coverage

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