Horus

 view release on metacpan or  search on metacpan

Horus.xs  view on Meta::CPAN

SV *
uuid_v7(fmt = HORUS_FMT_STR)
        int fmt
    CODE:
    {
        dMY_CXT;
        unsigned char uuid[16];
        horus_uuid_v7(uuid, &MY_CXT.v7_state);
        RETVAL = horus_uuid_to_sv(aTHX_ uuid, fmt);
    }
    OUTPUT:
        RETVAL

SV *
uuid_v8(custom_data, fmt = HORUS_FMT_STR)
        SV *custom_data
        int fmt
    CODE:
    {
        unsigned char uuid[16];
        STRLEN data_len;
        const char *data_str = SvPV(custom_data, data_len);

        if (data_len < 16)
            croak("Horus: uuid_v8 requires 16 bytes of custom data");

        horus_uuid_v8(uuid, (const unsigned char *)data_str);
        RETVAL = horus_uuid_to_sv(aTHX_ uuid, fmt);
    }
    OUTPUT:
        RETVAL

SV *
uuid_nil(fmt = HORUS_FMT_STR)
        int fmt
    CODE:
    {
        unsigned char uuid[16];
        horus_uuid_nil(uuid);
        RETVAL = horus_uuid_to_sv(aTHX_ uuid, fmt);
    }
    OUTPUT:
        RETVAL

SV *
uuid_max(fmt = HORUS_FMT_STR)
        int fmt
    CODE:
    {
        unsigned char uuid[16];
        horus_uuid_max(uuid);
        RETVAL = horus_uuid_to_sv(aTHX_ uuid, fmt);
    }
    OUTPUT:
        RETVAL

void
uuid_v4_bulk(count, fmt = HORUS_FMT_STR)
        int count
        int fmt
    PPCODE:
    {
        int i;
        if (count <= 0)
            XSRETURN_EMPTY;

        if (count <= 256) {
            for (i = 0; i < count; i++) {
                unsigned char uuid[16];
                horus_uuid_v4(uuid);
                mXPUSHs(horus_uuid_to_sv(aTHX_ uuid, fmt));
            }
        } else {
            unsigned char *buf;
            Newx(buf, (STRLEN)count * 16, unsigned char);
            horus_random_bulk(buf, (size_t)count * 16);

            for (i = 0; i < count; i++) {
                unsigned char *uuid = buf + i * 16;
                horus_stamp_version_variant(uuid, 4);
                mXPUSHs(horus_uuid_to_sv(aTHX_ uuid, fmt));
            }

            Safefree(buf);
        }
        XSRETURN(count);
    }

SV *
uuid_parse(input)
        SV *input
    CODE:
    {
        unsigned char uuid[16];
        STRLEN in_len;
        const char *in_str = SvPV(input, in_len);

        if (horus_parse_uuid(uuid, in_str, in_len) != HORUS_PARSE_OK)
            croak("Horus: cannot parse UUID string");

        RETVAL = newSVpvn((const char *)uuid, 16);
    }
    OUTPUT:
        RETVAL

int
uuid_validate(input)
        SV *input
    CODE:
    {
        STRLEN in_len;
        const char *in_str = SvPV(input, in_len);
        RETVAL = horus_uuid_validate(in_str, in_len);
    }
    OUTPUT:
        RETVAL

int
uuid_version(input)
        SV *input
    CODE:

Horus.xs  view on Meta::CPAN

        int default_ver = 4;

        for (i = 1; i + 1 < items; i += 2) {
            STRLEN klen;
            const char *key = SvPV(ST(i), klen);
            SV *val = ST(i + 1);

            if (klen == 6 && memcmp(key, "format", 6) == 0)
                default_fmt = SvIV(val);
            else if (klen == 7 && memcmp(key, "version", 7) == 0)
                default_ver = SvIV(val);
        }

        (void)hv_store(self, "format", 6, newSViv(default_fmt), 0);
        (void)hv_store(self, "version", 7, newSViv(default_ver), 0);

        RETVAL = sv_bless(newRV_noinc((SV *)self), gv_stashpv(class, GV_ADD));
    }
    OUTPUT:
        RETVAL

SV *
generate(self)
        SV *self
    CODE:
    {
        dMY_CXT;
        HV *hv;
        SV **svp;
        int fmt, ver;
        unsigned char uuid[16];

        if (!SvROK(self) || SvTYPE(SvRV(self)) != SVt_PVHV)
            croak("Horus: generate called on non-object");
        hv = (HV *)SvRV(self);

        svp = hv_fetch(hv, "format", 6, 0);
        fmt = svp ? SvIV(*svp) : HORUS_FMT_STR;

        svp = hv_fetch(hv, "version", 7, 0);
        ver = svp ? SvIV(*svp) : 4;

        switch (ver) {
            case 1:  horus_uuid_v1(uuid, &MY_CXT.v1_state); break;
            case 4:  horus_uuid_v4(uuid); break;
            case 6:  horus_uuid_v6(uuid, &MY_CXT.v1_state, &MY_CXT.v6_state); break;
            case 7:  horus_uuid_v7(uuid, &MY_CXT.v7_state); break;
            default:
                croak("Horus: generate() supports versions 1, 4, 6, 7 (use functional API for v2/v3/v5/v8)");
        }

        RETVAL = horus_uuid_to_sv(aTHX_ uuid, fmt);
    }
    OUTPUT:
        RETVAL

void
bulk(self, count)
        SV *self
        int count
    PPCODE:
    {
        dMY_CXT;
        HV *hv;
        SV **svp;
        int fmt, ver, i;

        if (!SvROK(self) || SvTYPE(SvRV(self)) != SVt_PVHV)
            croak("Horus: bulk called on non-object");
        hv = (HV *)SvRV(self);

        svp = hv_fetch(hv, "format", 6, 0);
        fmt = svp ? SvIV(*svp) : HORUS_FMT_STR;

        svp = hv_fetch(hv, "version", 7, 0);
        ver = svp ? SvIV(*svp) : 4;

        if (count <= 0)
            XSRETURN_EMPTY;

        EXTEND(SP, count);

        if (ver == 4 && count > 256) {
            unsigned char *buf;
            Newx(buf, (STRLEN)count * 16, unsigned char);
            horus_random_bulk(buf, (size_t)count * 16);
            for (i = 0; i < count; i++) {
                unsigned char *uuid = buf + i * 16;
                horus_stamp_version_variant(uuid, 4);
                mXPUSHs(horus_uuid_to_sv(aTHX_ uuid, fmt));
            }
            Safefree(buf);
        } else {
            for (i = 0; i < count; i++) {
                unsigned char uuid[16];
                switch (ver) {
                    case 1:  horus_uuid_v1(uuid, &MY_CXT.v1_state); break;
                    case 4:  horus_uuid_v4(uuid); break;
                    case 6:  horus_uuid_v6(uuid, &MY_CXT.v1_state, &MY_CXT.v6_state); break;
                    case 7:  horus_uuid_v7(uuid, &MY_CXT.v7_state); break;
                    default:
                        croak("Horus: bulk() supports versions 1, 4, 6, 7");
                }
                mXPUSHs(horus_uuid_to_sv(aTHX_ uuid, fmt));
            }
        }

        XSRETURN(count);
    }



( run in 3.757 seconds using v1.01-cache-2.11-cpan-71847e10f99 )