Chandra
view release on metacpan or search on metacpan
xs/protocol.xs view on Meta::CPAN
scheme = SvPV(scheme_sv, scheme_len);
clean_len = scheme_len;
if (clean_len > 3 && scheme[clean_len - 3] == ':' && scheme[clean_len - 2] == '/' && scheme[clean_len - 1] == '/') {
clean_len -= 3;
} else if (clean_len > 1 && scheme[clean_len - 1] == ':') {
clean_len -= 1;
}
if (clean_len >= sizeof(clean_scheme)) {
clean_len = sizeof(clean_scheme) - 1;
}
Copy(scheme, clean_scheme, clean_len, char);
clean_scheme[clean_len] = '\0';
/* Store handler in protocols hash */
protocols_svp = hv_fetchs(hv, "protocols", 0);
if (protocols_svp && SvROK(*protocols_svp)) {
protocols_hv = (HV *)SvRV(*protocols_svp);
(void)hv_store(protocols_hv, clean_scheme, clean_len, newSVsv(handler), 0);
}
/* Create XS callback with CvXSUBANY for handler + JSON encoder */
{
SV **app_svp = hv_fetchs(hv, "app", 0);
if (app_svp && SvOK(*app_svp)) {
ProtocolBindCtx *ctx;
CV *wrapper_cv;
SV *json_enc;
SV *bind_name = sv_2mortal(newSVpvf("__protocol_%s", clean_scheme));
json_enc = get_sv("Chandra::Protocol::_xs_json", 0);
Newxz(ctx, 1, ProtocolBindCtx);
ctx->handler = SvREFCNT_inc(handler);
ctx->json_encoder = SvREFCNT_inc(json_enc);
wrapper_cv = newXS(NULL, xs_protocol_bound_callback, __FILE__);
CvXSUBANY(wrapper_cv).any_ptr = (void *)ctx;
{
dSP;
ENTER; SAVETMPS;
PUSHMARK(SP);
XPUSHs(*app_svp);
XPUSHs(bind_name);
XPUSHs(sv_2mortal(newRV_noinc((SV *)wrapper_cv)));
PUTBACK;
call_method("bind", G_DISCARD);
FREETMPS; LEAVE;
}
}
}
RETVAL = SvREFCNT_inc(self);
}
OUTPUT:
RETVAL
void
schemes(self)
SV *self
PPCODE:
{
HV *hv = (HV *)SvRV(self);
SV **protocols_svp;
protocols_svp = hv_fetchs(hv, "protocols", 0);
if (protocols_svp && SvROK(*protocols_svp)) {
HV *protocols_hv = (HV *)SvRV(*protocols_svp);
I32 num_keys = hv_iterinit(protocols_hv);
if (GIMME_V == G_SCALAR) {
mXPUSHi(num_keys);
XSRETURN(1);
} else {
HE *entry;
while ((entry = hv_iternext(protocols_hv)) != NULL) {
XPUSHs(sv_2mortal(newSVhek(HeKEY_hek(entry))));
}
}
} else {
if (GIMME_V == G_SCALAR) {
mXPUSHi(0);
XSRETURN(1);
}
}
}
SV *
is_registered(self, scheme_sv)
SV *self
SV *scheme_sv
CODE:
{
HV *hv = (HV *)SvRV(self);
SV **protocols_svp;
char *scheme;
STRLEN scheme_len;
char clean_scheme[256];
STRLEN clean_len;
scheme = SvPV(scheme_sv, scheme_len);
clean_len = scheme_len;
if (clean_len > 3 && scheme[clean_len - 3] == ':' && scheme[clean_len - 2] == '/' && scheme[clean_len - 1] == '/') {
clean_len -= 3;
} else if (clean_len > 1 && scheme[clean_len - 1] == ':') {
clean_len -= 1;
}
if (clean_len >= sizeof(clean_scheme)) {
clean_len = sizeof(clean_scheme) - 1;
}
Copy(scheme, clean_scheme, clean_len, char);
clean_scheme[clean_len] = '\0';
protocols_svp = hv_fetchs(hv, "protocols", 0);
if (protocols_svp && SvROK(*protocols_svp)) {
HV *protocols_hv = (HV *)SvRV(*protocols_svp);
RETVAL = hv_exists(protocols_hv, clean_scheme, clean_len) ? &PL_sv_yes : &PL_sv_no;
} else {
RETVAL = &PL_sv_no;
}
}
( run in 1.039 second using v1.01-cache-2.11-cpan-71847e10f99 )