[libxml2] OS400: Easy character transcoding support
- From: Daniel Veillard <veillard src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml2] OS400: Easy character transcoding support
- Date: Sat, 4 Oct 2014 13:20:58 +0000 (UTC)
commit 5621c81b49cf2c2eb7b110d862f4b52b916f82b2
Author: Patrick Monnerat <pm datasphere ch>
Date: Tue Mar 4 17:09:26 2014 +0100
OS400: Easy character transcoding support
os400/transcode.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++
os400/transcode.h | 43 +++++++++
2 files changed, 311 insertions(+), 0 deletions(-)
---
diff --git a/os400/transcode.c b/os400/transcode.c
new file mode 100644
index 0000000..bae6187
--- /dev/null
+++ b/os400/transcode.c
@@ -0,0 +1,268 @@
+/**
+*** 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 targetted 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);
+}
diff --git a/os400/transcode.h b/os400/transcode.h
new file mode 100644
index 0000000..6ca5773
--- /dev/null
+++ b/os400/transcode.h
@@ -0,0 +1,43 @@
+/**
+*** Transcoding support declarations.
+***
+*** See Copyright for the status of this software.
+***
+*** Author: Patrick Monnerat <pm datasphere ch>, DATASPHERE S.A.
+**/
+
+#ifndef _TRANSCODE_H_
+#define _TRANSCODE_H_
+
+#include <stdarg.h>
+#include <libxml/dict.h>
+
+
+XMLPUBFUN void xmlZapDict(xmlDictPtr * dict);
+XMLPUBFUN const char * xmlTranscodeResult(const xmlChar * s,
+ const char * encoding, xmlDictPtr * dict,
+ void (*freeproc)(const void *));
+XMLPUBFUN const xmlChar * xmlTranscodeString(const char * s,
+ const char * encoding, xmlDictPtr * dict);
+XMLPUBFUN const xmlChar * xmlTranscodeWString(const char * s,
+ const char * encoding, xmlDictPtr * dict);
+XMLPUBFUN const xmlChar * xmlTranscodeHString(const char * s,
+ const char * encoding, xmlDictPtr * dict);
+
+#ifndef XML_NO_SHORT_NAMES
+/**
+*** Since the above functions are generally called "inline" (i.e.: several
+*** times nested in a single expression), define shorthand names
+*** to minimize calling statement length.
+**/
+
+#define xmlTR xmlTranscodeResult
+#define xmlTS xmlTranscodeString
+#define xmlTW xmlTranscodeWString
+#define xmlTH xmlTranscodeHstring
+#endif
+
+XMLPUBFUN const char * xmlVasprintf(xmlDictPtr * dict, const char * encoding,
+ const xmlChar * fmt, va_list args);
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]