Edit

kc3-lang/libxml2/os400/transcode.c

Branch :

  • Show log

    Commit

  • Author : Nick Wellnhofer
    Date : 2020-03-08 17:19:42
    Hash : 20c60886
    Message : Fix typos Resolves #133.

  • os400/transcode.c
  • /**
    ***     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);
    }