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