#ifdef __cplusplus
extern "C" {
#endif
/* perl stuff */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <libxml/parser.h>
/* #include <libxml/tree.h> */
#ifdef __cplusplus
}
#endif
static SV * LibXML_COMMON_error = NULL;
/* stores libxml errors into $@ */
void
LIBXML_COMMON_error_handler(void * ctxt, const char * msg, ...)
{
va_list args;
SV * sv;
sv = NEWSV(0,512);
va_start(args, msg);
sv_vsetpvfn(sv, msg, strlen(msg), &args, NULL, 0, NULL);
va_end(args);
if (LibXML_COMMON_error != NULL) {
sv_catsv(LibXML_COMMON_error, sv); /* remember the last error */
}
else {
croak(SvPV(sv, PL_na));
}
SvREFCNT_dec(sv);
}
MODULE = XML::LibXML::Common PACKAGE = XML::LibXML::Common
PROTOTYPES: DISABLE
SV*
encodeToUTF8( encoding, string )
const char * encoding
SV * string
PREINIT:
xmlChar * realstring = NULL;
xmlChar * tstr = NULL;
xmlCharEncoding enc = 0;
STRLEN len = 0;
xmlBufferPtr in = NULL, out = NULL;
xmlCharEncodingHandlerPtr coder = NULL;
CODE:
realstring = SvPV(string, len);
if ( realstring != NULL ) {
/* warn("encode %s", realstring ); */
#ifdef HAVE_UTF8
if ( !DO_UTF8(string) && encoding != NULL ) {
#else
if ( encoding != NULL ) {
#endif
enc = xmlParseCharEncoding( encoding );
if ( enc == 0 ) {
/* this happens if the encoding is "" or NULL */
enc = XML_CHAR_ENCODING_UTF8;
}
if ( enc == XML_CHAR_ENCODING_UTF8 ) {
/* copy the string */
/* warn( "simply copy the string" ); */
tstr = xmlStrdup( realstring );
}
else {
LibXML_COMMON_error = NEWSV(0, 512);
xmlSetGenericErrorFunc(PerlIO_stderr(),
(xmlGenericErrorFunc)LIBXML_COMMON_error_handler);
if ( enc > 1 ) {
coder= xmlGetCharEncodingHandler( enc );
}
else if ( enc == XML_CHAR_ENCODING_ERROR ){
coder =xmlFindCharEncodingHandler( encoding );
}
else {
croak("no encoder found\n");
}
if ( coder == NULL ) {
croak( "cannot encode string" );
}
in = xmlBufferCreate();
out = xmlBufferCreate();
xmlBufferCCat( in, realstring );
if ( xmlCharEncInFunc( coder, out, in ) >= 0 ) {
tstr = xmlStrdup( out->content );
}
xmlBufferFree( in );
xmlBufferFree( out );
xmlCharEncCloseFunc( coder );
sv_2mortal(LibXML_COMMON_error);
if ( SvCUR( LibXML_COMMON_error ) > 0 ) {
croak(SvPV(LibXML_COMMON_error, len));
}
}
}
else {
tstr = xmlStrdup( realstring );
}
if ( !tstr ) {
croak( "return value missing!" );
}
len = xmlStrlen( tstr );
RETVAL = newSVpvn( (const char *)tstr, len );
#ifdef HAVE_UTF8
SvUTF8_on(RETVAL);
#endif
xmlFree(tstr);
}
else {
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
SV*
decodeFromUTF8( encoding, string )
const char * encoding
SV* string
PREINIT:
xmlChar * tstr = NULL;
xmlChar * realstring = NULL;
xmlCharEncoding enc = 0;
STRLEN len = 0;
xmlBufferPtr in = NULL, out = NULL;
xmlCharEncodingHandlerPtr coder = NULL;
CODE:
#ifdef HAVE_UTF8
if ( !SvUTF8(string) ) {
croak("string is not utf8!!");
}
else {
#endif
realstring = SvPV(string, len);
if ( realstring != NULL ) {
/* warn("decode %s", realstring ); */
enc = xmlParseCharEncoding( encoding );
if ( enc == 0 ) {
/* this happens if the encoding is "" or NULL */
enc = XML_CHAR_ENCODING_UTF8;
}
if ( enc == XML_CHAR_ENCODING_UTF8 ) {
/* copy the string */
/* warn( "simply copy the string" ); */
tstr = xmlStrdup( realstring );
len = xmlStrlen( tstr );
}
else {
LibXML_COMMON_error = NEWSV(0, 512);
xmlSetGenericErrorFunc(PerlIO_stderr(),
(xmlGenericErrorFunc)LIBXML_COMMON_error_handler);
sv_2mortal(LibXML_COMMON_error);
if ( enc > 1 ) {
coder= xmlGetCharEncodingHandler( enc );
}
else if ( enc == XML_CHAR_ENCODING_ERROR ){
coder = xmlFindCharEncodingHandler( encoding );
}
else {
croak("no encoder found\n");
}
if ( coder == NULL ) {
croak( "cannot encode string" );
}
in = xmlBufferCreate();
out = xmlBufferCreate();
xmlBufferCCat( in, realstring );
if ( xmlCharEncOutFunc( coder, out, in ) >= 0 ) {
len = xmlBufferLength( out );
tstr = xmlCharStrndup( xmlBufferContent( out ), len );
}
xmlBufferFree( in );
xmlBufferFree( out );
xmlCharEncCloseFunc( coder );
if ( SvCUR( LibXML_COMMON_error ) > 0 ) {
croak(SvPV(LibXML_COMMON_error, len));
}
if ( !tstr ) {
croak( "return value missing!" );
}
}
RETVAL = newSVpvn( (const char *)tstr, len );
xmlFree( tstr );
#ifdef HAVE_UTF8
if ( enc == XML_CHAR_ENCODING_UTF8 ) {
SvUTF8_on(RETVAL);
}
#endif
}
else {
XSRETURN_UNDEF;
}
#ifdef HAVE_UTF8
}
#endif
OUTPUT:
RETVAL