Chandra

 view release on metacpan or  search on metacpan

xs/assets.xs  view on Meta::CPAN


    if (!full_path) {
        RETVAL = &PL_sv_undef;
    } else {
        /* Call File::Raw::slurp($path) */
        ENTER; SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(sv_2mortal(full_path));
        PUTBACK;
        count = call_pv("File::Raw::slurp", G_SCALAR);
        SPAGAIN;
        RETVAL = (count > 0) ? newSVsv(POPs) : &PL_sv_undef;
        PUTBACK; FREETMPS; LEAVE;
    }
}
OUTPUT:
    RETVAL

SV *
exists(self, rel_sv)
    SV *self
    SV *rel_sv
CODE:
{
    SV *full_path;
    int count;
    dSP;

    ENTER; SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(self);
    XPUSHs(rel_sv);
    PUTBACK;
    count = call_method("_resolve_path", G_SCALAR | G_EVAL);
    SPAGAIN;
    full_path = (count > 0 && !SvTRUE(ERRSV)) ? newSVsv(POPs) : NULL;
    PUTBACK; FREETMPS; LEAVE;

    if (!full_path) {
        RETVAL = &PL_sv_no;
    } else {
        ENTER; SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(sv_2mortal(full_path));
        PUTBACK;
        count = call_pv("File::Raw::exists", G_SCALAR);
        SPAGAIN;
        {
            SV *result = (count > 0) ? POPs : NULL;
            RETVAL = (result && SvTRUE(result)) ? &PL_sv_yes : &PL_sv_no;
        }
        PUTBACK; FREETMPS; LEAVE;
    }
}
OUTPUT:
    RETVAL

void
list(self, ...)
    SV *self
PPCODE:
{
    HV *hv = (HV *)SvRV(self);
    SV **root_svp = hv_fetchs(hv, "root", 0);
    SV *pattern_sv = (items > 1 && SvOK(ST(1))) ? ST(1) : NULL;
    AV *result_av = NULL;

    if (!root_svp || !SvOK(*root_svp)) XSRETURN(0);

    /* Call File::Raw::readdir($root) - capture result before returning to our stack */
    {
        dSP;
        int count;
        ENTER; SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(*root_svp);
        PUTBACK;
        count = call_pv("File::Raw::readdir", G_SCALAR);
        SPAGAIN;
        if (count > 0) {
            SV *entries_sv = POPs;
            if (SvROK(entries_sv) && SvTYPE(SvRV(entries_sv)) == SVt_PVAV) {
                /* Copy the array so it survives FREETMPS */
                AV *src = (AV *)SvRV(entries_sv);
                SSize_t len = av_len(src) + 1;
                SSize_t i;
                result_av = newAV();
                av_extend(result_av, len - 1);
                for (i = 0; i < len; i++) {
                    SV **svp = av_fetch(src, i, 0);
                    if (svp && SvOK(*svp))
                        av_push(result_av, newSVsv(*svp));
                }
            }
        }
        PUTBACK; FREETMPS; LEAVE;
    }

    if (result_av) {
        SSize_t len = av_len(result_av) + 1;
        SSize_t i;
        for (i = 0; i < len; i++) {
            SV **entry_svp = av_fetch(result_av, i, 0);
            if (entry_svp && SvOK(*entry_svp)) {
                int push_it = 1;
                if (pattern_sv) {
                    STRLEN plen, elen;
                    const char *pat = SvPV(pattern_sv, plen);
                    const char *ent = SvPV(*entry_svp, elen);
                    push_it = 0;
                    if (plen >= 2 && pat[0] == '*' && pat[1] == '.') {
                        const char *ext = pat + 1;
                        STRLEN ext_len = plen - 1;
                        if (elen >= ext_len &&
                            memcmp(ent + elen - ext_len, ext, ext_len) == 0) {
                            push_it = 1;
                        }
                    } else if (elen >= plen && memcmp(ent, pat, plen) == 0) {
                        push_it = 1;
                    }
                }



( run in 0.686 second using v1.01-cache-2.11-cpan-71847e10f99 )