// SLP.xs // XS file for Net::SLP // Author: Mike McCauley (mikem@open.com.au) // Copyright (C) 2004 Mike McCauley // $Id: SLP.xs,v 1.3 2007/06/20 22:46:15 mikem Exp mikem $ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include #define SLP_FALSE 0 #define SLP_TRUE 1 #include "const-c.inc" // Callback when a URL is available from SLPFindSrvs // cookie is a perl closure, which is expected to be called SLPBoolean slp_url_callback_glue(SLPHandle hSLP, const char* pcSrvURL, unsigned short sLifetime, SLPError errCode, void *pvCookie) { dSP; int count; SLPBoolean result; if (pvCookie == NULL) croak ("Net::SLP: slp_url_callback_glue called without a callback function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); if (pcSrvURL) XPUSHs(sv_2mortal(newSVpv(pcSrvURL, 0))); else XPUSHs(sv_2mortal(newSVsv(&PL_sv_undef))); // Nothing there XPUSHs(sv_2mortal(newSViv(sLifetime))); XPUSHs(sv_2mortal(newSViv(errCode))); PUTBACK; count = call_sv(pvCookie, G_SCALAR); SPAGAIN; if (count != 1) croak ("Net::SLP: slp_url_callback_glue callback did not return a scalar.\n"); // The return code from the closure is important // Returning SLP_TRUE asks for more data. SLP_FALSE means no more data please result = POPi; PUTBACK; FREETMPS; LEAVE; return result; } // Callback when a service type is available from SLPFindSrvTypes // cookie is a perl closure, which is expected to be called SLPBoolean slp_srvtype_callback_glue(SLPHandle hSLP, const char* pcSrvTypes, SLPError errCode, void *pvCookie) { dSP; int count; SLPBoolean result; if (pvCookie == NULL) croak ("Net::SLP: slp_srvtype_callback_glue called without a callback function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); if (pcSrvTypes) XPUSHs(sv_2mortal(newSVpv(pcSrvTypes, 0))); else XPUSHs(sv_2mortal(newSVsv(&PL_sv_undef))); // Nothing there XPUSHs(sv_2mortal(newSViv(errCode))); PUTBACK; count = call_sv(pvCookie, G_SCALAR); SPAGAIN; if (count != 1) croak ("Net::SLP: slp_srvtype_callback_glue callback did not return a scalar.\n"); // The return code from the closure is important // Returning SLP_TRUE asks for more data. SLP_FALSE means no more data please result = POPi; PUTBACK; FREETMPS; LEAVE; return result; } // Callback when a service type is available from SLPFindAttrs // cookie is a perl closure, which is expected to be called SLPBoolean slp_attr_callback_glue(SLPHandle hSLP, const char* pcAttrList, SLPError errCode, void *pvCookie) { dSP; int count; SLPBoolean result = SLP_TRUE; if (pvCookie == NULL) croak ("Net::SLP: slp_attr_callback_glue called without a callback function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); if (pcAttrList) XPUSHs(sv_2mortal(newSVpv(pcAttrList, 0))); else XPUSHs(sv_2mortal(newSVsv(&PL_sv_undef))); // Nothing there XPUSHs(sv_2mortal(newSViv(errCode))); PUTBACK; count = call_sv(pvCookie, G_SCALAR); SPAGAIN; PUTBACK; FREETMPS; LEAVE; return result; } // Callback when a service is registered or deregisted with // SLPReg(), SLPDeReg() and SLPDelAttrs() functions. // cookie is a perl closure, which is expected to be called void slp_reg_callback_glue(SLPHandle hSLP, SLPError errCode, void *pvCookie) { dSP; int count; SLPBoolean result; if (pvCookie == NULL) croak ("Net::SLP: slp_reg_callback_glue called without a callback function.\n"); ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSViv(errCode))); PUTBACK; count = call_sv(pvCookie, G_SCALAR); SPAGAIN; if (count != 1) croak ("Net::SLP: slp_reg_callback_glue callback did not return a scalar.\n"); // The return code from the closure is important // Returning SLP_TRUE asks for more data. SLP_FALSE means no more data please result = POPi; PUTBACK; FREETMPS; LEAVE; return; } MODULE = Net::SLP PACKAGE = Net::SLP INCLUDE: const-xs.inc PROTOTYPES: ENABLE SLPError SLPOpen(const char *pcLang, SLPBoolean isAsync, OUT SLPHandle phSLP); void SLPClose(SLPHandle hSLP); SLPError SLPFindSrvs(SLPHandle handle, const char *servicetype, const char *scopelist, const char *searchfilter, SV* callback) CODE: RETVAL = SLPFindSrvs(handle, servicetype, scopelist, searchfilter, &slp_url_callback_glue, (void*)newSVsv(callback)); OUTPUT: RETVAL SLPError SLPFindSrvTypes(SLPHandle handle, const char *namingauthority, const char *scopelist, SV* callback) CODE: RETVAL = SLPFindSrvTypes(handle, namingauthority, scopelist, &slp_srvtype_callback_glue, (void*)newSVsv(callback)); OUTPUT: RETVAL SLPError SLPFindAttrs(SLPHandle handle, const char *srvurl, const char *scopelist, const char* attrids, SV* callback) CODE: RETVAL = SLPFindAttrs(handle, srvurl, scopelist, attrids, &slp_attr_callback_glue, (void*)newSVsv(callback)); OUTPUT: RETVAL const char * SLPGetProperty(const char* name) void SLPSetProperty(const char* name, const char* value) SLPError SLPFindScopes(SLPHandle handle, OUT char *scopelist) CLEANUP: SLPFree(scopelist); int SLPGetRefreshInterval() SLPError SLPEscape(const char* unescaped, OUT char* escaped, SLPBoolean istag) CLEANUP: SLPFree(escaped); SLPError SLPUnescape(const char* escaped, OUT char* unescaped, SLPBoolean istag) CLEANUP: SLPFree(unescaped); SLPError SLPReg(SLPHandle handle, const char* srvurl, unsigned short lifetime, const char* srvtype, const char* attrs, SLPBoolean fresh, SV* callback) CODE: RETVAL = SLPReg(handle, srvurl, lifetime, srvtype, attrs, fresh, &slp_reg_callback_glue, (void*)newSVsv(callback)); OUTPUT: RETVAL SLPError SLPDereg(SLPHandle handle, const char* srvurl, SV* callback) CODE: RETVAL = SLPDereg(handle, srvurl, &slp_reg_callback_glue, (void*)newSVsv(callback)); OUTPUT: RETVAL SLPError SLPDelAttrs(SLPHandle handle, const char* srvurl, const char* attrs, SV* callback) CODE: RETVAL = SLPDelAttrs(handle, srvurl, attrs, &slp_reg_callback_glue, (void*)newSVsv(callback)); OUTPUT: RETVAL