Blame os400/transcode.c

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
}