Affix

 view release on metacpan or  search on metacpan

lib/Affix.c  view on Meta::CPAN

    sv_setuv(dual, (UV)err_code);

    char * buf = nullptr;
    DWORD len =
        FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                       nullptr,
                       err_code,
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                       (LPSTR)&buf,
                       0,
                       nullptr);

    if (buf) {
        while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r'))
            buf[--len] = '\0';
        sv_setpvn(dual, buf, len);
        LocalFree(buf);
    }
    else
        sv_setpvn(dual, "Unknown system error", 20);

    SvIOK_on(dual);
    SvIsUV_on(dual);  // Mark as unsigned for DWORD
#else
    int err_code = errno;
    sv_setiv(dual, err_code);

    const char * msg = strerror(err_code);
    if (msg)
        sv_setpv(dual, msg);
    else
        sv_setpv(dual, "Unknown system error");

    SvIV_set(dual, (IV)err_code);
    SvIOK_on(dual);
#endif

    ST(0) = sv_2mortal(dual);
    XSRETURN(1);
}

XS_INTERNAL(Affix_dump) {
    dVAR;
    dXSARGS;
    if (items != 2)
        croak_xs_usage(cv, "scalar, length_in_bytes");
    Affix_Pin * pin = _get_pin_from_sv(aTHX_ ST(0));
    if (!pin) {
        warn("scalar is not a valid pointer");
        XSRETURN_EMPTY;
    }
    if (!pin->pointer) {
        warn("Cannot dump a nullptr pointer");
        XSRETURN_EMPTY;
    }
    UV length = SvUV(ST(1));
    if (length == 0) {
        warn("Dump length cannot be zero");
        XSRETURN_EMPTY;
    }
    // PL_curcop may be nullptr during thread destruction or callbacks?
    const char * file = "Unknown";
    int line = 0;
    if (LIKELY(PL_curcop)) {
        file = OutCopFILE(PL_curcop);
        line = CopLINE(PL_curcop);
    }
    _DumpHex(aTHX_ pin->pointer, length, file, line);
    ST(0) = ST(0);
    XSRETURN(1);
}

static void * _resolve_writable_ptr(pTHX_ SV * sv) {
    if (is_pin(aTHX_ sv)) {
        Affix_Pin * p = _get_pin_from_sv(aTHX_ sv);
        return p ? p->pointer : nullptr;
    }
    if (SvIOK(sv))
        return INT2PTR(void *, SvUV(sv));
    return nullptr;
}

static const void * _resolve_readable_ptr(pTHX_ SV * sv) {
    if (is_pin(aTHX_ sv)) {
        Affix_Pin * p = _get_pin_from_sv(aTHX_ sv);
        return p ? p->pointer : nullptr;
    }
    if (SvIOK(sv))
        return INT2PTR(void *, SvUV(sv));
    if (SvPOK(sv))
        return (const void *)SvPV_nolen(sv);
    return nullptr;
}

XS_INTERNAL(Affix_memcpy) {
    dXSARGS;
    if (items != 3)
        croak_xs_usage(cv, "dest, src, n");
    void * dest = _resolve_writable_ptr(aTHX_ ST(0));
    if (!dest) {
        warn("dest must be a pinned pointer or address");
        XSRETURN_UNDEF;
    }
    const void * src = _resolve_readable_ptr(aTHX_ ST(1));
    if (!src) {
        warn("src must be a pinned pointer, address, or string");
        XSRETURN_UNDEF;
    }
    size_t n = (size_t)SvUV(ST(2));
    memcpy(dest, src, n);
    XSRETURN(1);
}

XS_INTERNAL(Affix_memmove) {
    dXSARGS;
    if (items != 3)
        croak_xs_usage(cv, "dest, src, n");
    void * dest = _resolve_writable_ptr(aTHX_ ST(0));
    if (!dest) {
        warn("dest must be a pinned pointer or address");
        XSRETURN_UNDEF;



( run in 0.538 second using v1.01-cache-2.11-cpan-39bf76dae61 )