// 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 <slp.h>
#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