From 195ab6016cf29c78606ffb0f9500213d8d7b2b2f Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Tue, 3 Dec 2019 16:06:11 -0300 Subject: [PATCH] Adding convenience iconv wrapper to support the MSVC isolation layer. --- lib3270.cbp | 3 +++ src/core/charset/iconv.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/linux/connect.c | 4 ---- src/include/lib3270/charset.h | 22 ++++++++++++++++++++++ 4 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 src/core/charset/iconv.c diff --git a/lib3270.cbp b/lib3270.cbp index ac34580..0743df9 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -65,6 +65,9 @@ + + diff --git a/src/core/charset/iconv.c b/src/core/charset/iconv.c new file mode 100644 index 0000000..9fd1ff2 --- /dev/null +++ b/src/core/charset/iconv.c @@ -0,0 +1,121 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como charset.c e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @file charset/iconv.c + * + * @brief This module implements the ICONV wrapper methods. + */ + +#include +#include +#include +#include +#include + +struct _lib3270_iconv +{ + /// @brief Convert strings from host codepage to local codepage. + iconv_t local; + + /// @brief Convert string from local codepage to host codepage. + iconv_t host; +}; + +/*---[ Implement ]------------------------------------------------------------------------------------------------------------*/ + + LIB3270_ICONV * lib3270_iconv_new(const char *remote, const char *local) + { + LIB3270_ICONV * converter = lib3270_malloc(sizeof(LIB3270_ICONV)); + memset(converter,0,sizeof(LIB3270_ICONV)); + + if(strcmp(local,remote)) { + + // Local and remote charsets aren't the same, setup conversion + converter->local = iconv_open(local, remote); + converter->host = iconv_open(remote,local); + + } else { + + // Same charset, doesn't convert + converter->local = converter->host = (iconv_t)(-1); + + } + + return converter; + } + + void lib3270_iconv_free(LIB3270_ICONV *conv) + { + if(conv->local != (iconv_t) (-1)) + iconv_close(conv->local); + + if(conv->host != (iconv_t) (-1)) + iconv_close(conv->host); + + conv->local = conv->host = (iconv_t) (-1); + + lib3270_free(conv); + } + + static char *convert(iconv_t *converter, const char * str, int length) + { + if(length < 0) + length = (int) strlen(str); + + if(length && converter != (iconv_t)(-1)) + { + + size_t in = length; + size_t out = (length << 1); + char * ptr; + char * outBuffer = (char *) lib3270_malloc(out); + ICONV_CONST char * inBuffer = (ICONV_CONST char *) str; + + memset(ptr=outBuffer,0,out); + + iconv(converter,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(converter,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + return (char *) outBuffer; + + } + + return NULL; + } + + char * lib3270_iconv_from_host(LIB3270_ICONV *conv, const char *str, int len) + { + return convert(&conv->local,str,len); + } + + char * lib3270_iconv_to_host(LIB3270_ICONV *conv, const char *str, int len) + { + return convert(&conv->host,str,len); + } diff --git a/src/core/linux/connect.c b/src/core/linux/connect.c index 94dfd8b..7702b1e 100644 --- a/src/core/linux/connect.c +++ b/src/core/linux/connect.c @@ -42,10 +42,6 @@ #include #include -// #ifdef HAVE_ICONV -// #include -// #endif // HAVE_ICONV - #define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1; #include diff --git a/src/include/lib3270/charset.h b/src/include/lib3270/charset.h index d8e005c..86d5731 100644 --- a/src/include/lib3270/charset.h +++ b/src/include/lib3270/charset.h @@ -92,6 +92,28 @@ */ LIB3270_EXPORT unsigned short lib3270_translate_char(const char *id); + typedef struct _lib3270_iconv LIB3270_ICONV; + + /// + /// @brief Create a new ICONV wrapper. + /// + LIB3270_EXPORT LIB3270_ICONV * lib3270_iconv_new(const char *remote, const char *local); + + /// + /// @brief Release the ICONV Wrapper. + /// + LIB3270_EXPORT void lib3270_iconv_free(LIB3270_ICONV *conv); + + /// + /// @brief Convert from host to local. + /// + LIB3270_EXPORT char * lib3270_iconv_from_host(LIB3270_ICONV *conv, const char *str, int len); + + /// + /// @brief Convert from local to host. + /// + LIB3270_EXPORT char * lib3270_iconv_to_host(LIB3270_ICONV *conv, const char *str, int len); + #ifdef __cplusplus } #endif -- libgit2 0.21.2