2014-03-04 17:09:26 +01:00
/**
* * * Transcoding support and wrappers .
* * *
* * * See Copyright for the status of this software .
* * *
* * * Author : Patrick Monnerat < pm @ datasphere . ch > , DATASPHERE S . A .
* */
# define IN_LIBXML
# include "libxml.h"
# include <sys/types.h>
# include <iconv.h>
# include "libxml/xmlmemory.h"
# include "libxml/dict.h"
# include "transcode.h"
/**
* * * Destroy a dictionary and mark as destroyed .
* */
void
xmlZapDict ( xmlDictPtr * dict )
{
if ( dict & & * dict ) {
xmlDictFree ( * dict ) ;
* dict = ( xmlDictPtr ) NULL ;
}
}
/**
* * * Support for inline conversion from / to UTF - 8.
2020-03-08 17:19:42 +01:00
* * * This is targeted to function parameter encoding conversion .
2014-03-04 17:09:26 +01:00
* * * Method is :
* * * - Convert string from / to UTF - 8.
* * * - Keep it in a dictionary .
* * * - Free original string if a release procedure is provided .
* * * Can also be called without dictionary to convert a string from / to UTF - 8
* * * into xmlMalloc ' ed dynamic storage .
* */
const char *
xmlTranscodeResult ( const xmlChar * s , const char * encoding ,
xmlDictPtr * dict , void ( * freeproc ) ( const void * ) )
{
size_t l ;
iconv_t cd ;
char * srcp ;
char * dstp ;
size_t srcc ;
size_t dstc ;
char * ts ;
const char * ret ;
int err ;
static const int nullstring [ ] = { 0 } ;
/* Convert from UTF-8. */
if ( ! s )
return ( const char * ) NULL ;
ret = ( const char * ) NULL ;
ts = ( char * ) NULL ;
err = 0 ;
l = xmlStrlen ( s ) ;
if ( ! l & & dict )
ret = ( const char * ) nullstring ;
else {
if ( dict & & ! * dict )
err = ! ( * dict = xmlDictCreate ( ) ) ;
if ( ! err )
err = ! ( ts = xmlMalloc ( 4 * l + 4 ) ) ;
dstp = ts ;
dstc = 4 * l ;
if ( ! err & & l ) {
if ( ! encoding )
encoding = " ibm-0 " ; /* Job's encoding. */
cd = iconv_open ( encoding , " UTF-8 " ) ;
if ( cd = = ( iconv_t ) - 1 )
err = 1 ;
else {
srcp = ( char * ) s ;
srcc = l ;
srcc = iconv ( cd , & srcp , & srcc , & dstp , & dstc ) ;
iconv_close ( cd ) ;
err = srcc = = ( size_t ) - 1 ;
}
}
if ( ! err ) {
dstp [ 0 ] = dstp [ 1 ] = dstp [ 2 ] = dstp [ 3 ] = ' \0 ' ;
if ( ! dict ) {
if ( dstc )
ts = xmlRealloc ( ts , ( dstp - ts ) + 4 ) ;
ret = ( const char * ) ts ;
ts = ( char * ) NULL ;
}
else
ret = ( char * ) xmlDictLookup ( * dict ,
( xmlChar * ) ts , dstp - ts + 1 ) ;
}
}
if ( ts )
xmlFree ( ts ) ;
if ( freeproc )
( * freeproc ) ( s ) ;
return ret ;
}
/**
* * * Support for inline conversion to UTF - 8.
* * * Method is :
* * * - Convert string to UTF - 8.
* * * - Keep it in a dictionary .
* * * Can also be called without dictionary to convert a string to UTF - 8 into
* * * xmlMalloc ' ed dynamic storage .
* */
static const xmlChar *
inTranscode ( const char * s , size_t l , const char * encoding , xmlDictPtr * dict )
{
iconv_t cd ;
char * srcp ;
char * dstp ;
size_t srcc ;
size_t dstc ;
xmlChar * ts ;
const xmlChar * ret ;
static const xmlChar nullstring [ ] = { 0 } ;
if ( ! l & & dict )
return nullstring ;
if ( dict & & ! * dict )
if ( ! ( * dict = xmlDictCreate ( ) ) )
return ( const xmlChar * ) NULL ;
ts = ( xmlChar * ) xmlMalloc ( 6 * l + 1 ) ;
if ( ! ts )
return ( const xmlChar * ) NULL ;
dstp = ( char * ) ts ;
dstc = 6 * l ;
if ( l ) {
if ( ! encoding )
encoding = " ibm-0 " ; /* Use job's encoding. */
cd = iconv_open ( " UTF-8 " , encoding ) ;
if ( cd = = ( iconv_t ) - 1 ) {
xmlFree ( ( char * ) ts ) ;
return ( const xmlChar * ) NULL ;
}
srcp = ( char * ) s ;
srcc = l ;
srcc = iconv ( cd , & srcp , & srcc , & dstp , & dstc ) ;
iconv_close ( cd ) ;
if ( srcc = = ( size_t ) - 1 ) {
xmlFree ( ( char * ) ts ) ;
return ( const xmlChar * ) NULL ;
}
}
* dstp = ' \0 ' ;
if ( ! dict ) {
if ( dstc )
ts = xmlRealloc ( ts , ( dstp - ts ) + 1 ) ;
return ts ;
}
ret = xmlDictLookup ( * dict , ts , dstp - ts + 1 ) ;
xmlFree ( ( char * ) ts ) ;
return ret ;
}
/**
* * * Input 8 - bit character string parameter .
* */
const xmlChar *
xmlTranscodeString ( const char * s , const char * encoding , xmlDictPtr * dict )
{
if ( ! s )
return ( const xmlChar * ) NULL ;
return inTranscode ( s , xmlStrlen ( s ) , encoding , dict ) ;
}
/**
* * * Input 16 - bit character string parameter .
* */
const xmlChar *
xmlTranscodeWString ( const char * s , const char * encoding , xmlDictPtr * dict )
{
size_t i ;
if ( ! s )
return ( const xmlChar * ) NULL ;
for ( i = 0 ; s [ i ] & & s [ i + 1 ] ; i + = 2 )
;
return inTranscode ( s , i , encoding , dict ) ;
}
/**
* * * Input 32 - bit character string parameter .
* */
const xmlChar *
xmlTranscodeHString ( const char * s , const char * encoding , xmlDictPtr * dict )
{
size_t i ;
if ( ! s )
return ( const xmlChar * ) NULL ;
for ( i = 0 ; s [ i ] & & s [ i + 1 ] & & s [ i + 2 ] & & s [ i + 3 ] ; i + = 4 )
;
return inTranscode ( s , i , encoding , dict ) ;
}
/**
* * * vasprintf ( ) implementation with result transcoding .
* */
const char *
xmlVasprintf ( xmlDictPtr * dict , const char * encoding ,
const xmlChar * fmt , va_list args )
{
char * s = NULL ;
vasprintf ( & s , fmt , args ) ;
return xmlTranscodeResult ( ( const xmlChar * ) s , encoding , dict , free ) ;
}