/**
***     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.
***     This is targeted to function parameter encoding conversion.
***     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);
}
