diff --git a/src/classlib/local.cc b/src/classlib/local.cc index f1f1b66..4cc36e0 100644 --- a/src/classlib/local.cc +++ b/src/classlib/local.cc @@ -300,6 +300,7 @@ int (*_get_next_unprotected)(H3270 *hSession, int baddr0); void (*_popup_va)(H3270 *session, LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, va_list); void * (*_free)(void *); + const char * (*_get_charset)(H3270 *hSession); public: @@ -346,6 +347,8 @@ { (void **) & _get_next_unprotected, "lib3270_get_next_unprotected" }, { (void **) & _popup_va, "lib3270_popup_va" }, { (void **) & _free, "lib3270_free" }, + { (void **) & _get_charset, "lib3270_get_charset" }, + }; @@ -366,6 +369,8 @@ set_trace_handler(tracehandler); this->hSession = lib3270_new(""); + set_charset(); + } virtual ~local() @@ -535,6 +540,10 @@ return 0; } + const char * get_charset(void) + { + return _get_charset(hSession); + } }; diff --git a/src/classlib/session.cc b/src/classlib/session.cc index a574500..5efb804 100644 --- a/src/classlib/session.cc +++ b/src/classlib/session.cc @@ -29,6 +29,8 @@ #include #include + #include + #include #include @@ -46,6 +48,11 @@ session::session() { +#ifdef HAVE_ICONV + this->conv2Local = (iconv_t) (-1); + this->conv2Host = (iconv_t) (-1); +#endif + if(first) { prev = last; @@ -58,10 +65,21 @@ prev = next = 0; first = last = this; } + } session::~session() { +#ifdef HAVE_ICONV + + if(this->conv2Local != (iconv_t) (-1)) + iconv_close(this->conv2Local); + + if(this->conv2Host != (iconv_t) (-1)) + iconv_close(this->conv2Host); + +#endif + if(prev) prev->next = next; else @@ -103,11 +121,38 @@ } // Object settings - void session::set_charset(const char *charset) + void session::set_charset(const char *remote, const char *local) { +#ifdef HAVE_ICONV + + if(this->conv2Local != (iconv_t) (-1)) + iconv_close(this->conv2Local); + + if(this->conv2Host != (iconv_t) (-1)) + iconv_close(this->conv2Host); + + if(!remote) + remote = this->get_charset(); + + if(strcmp(local,remote)) + { + // Local and remote charsets aren't the same, setup conversion + conv2Local = iconv_open(local, remote); + conv2Host = iconv_open(remote,local); + } + else + { + conv2Local = conv2Host = (iconv_t)(-1); + } +#endif } + const char * session::get_charset(void) + { + return "ISO-8859-1"; + } + // 3270 methods string session::get_version(void) { @@ -189,6 +234,57 @@ return NULL; } + string * session::get_3270_text(string *str) + { +#ifdef HAVE_ICONV + if(str && conv2Host != (iconv_t)(-1)) + { + size_t in = str->length(); + size_t out = (in << 1); + char * ptr; + char * outBuffer = (char *) malloc(out); + ICONV_CONST char * inBuffer = (ICONV_CONST char *) str->c_str(); + + memset(ptr=outBuffer,0,out); + + iconv(conv2Host,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(conv2Host,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + str->assign(outBuffer); + + free(outBuffer); + } +#endif // HAVE_ICONV + + return str; + } + + string * session::get_local_text(string *str) + { +#ifdef HAVE_ICONV + if(str && conv2Local != (iconv_t)(-1)) + { + size_t in = str->length(); + size_t out = (in << 1); + char * ptr; + char * outBuffer = (char *) malloc(out); + ICONV_CONST char * inBuffer = (ICONV_CONST char *) str->c_str(); + + memset(ptr=outBuffer,0,out); + + iconv(conv2Local,NULL,NULL,NULL,NULL); // Reset state + + if(iconv(conv2Local,&inBuffer,&in,&ptr,&out) != ((size_t) -1)) + str->assign(outBuffer); + + free(outBuffer); + } +#endif // HAVE_ICONV + + return str; + } + + } diff --git a/src/classlib/testprogram.cc b/src/classlib/testprogram.cc index 97a30fd..d2e7708 100644 --- a/src/classlib/testprogram.cc +++ b/src/classlib/testprogram.cc @@ -48,6 +48,7 @@ cout << "\tDisconnected" << endl; cout << "\tSession state: " << session->get_cstate() << endl; + cout << "\tCharset: " << session->get_charset() << endl; delete session; return 0; diff --git a/src/include/pw3270/class.h b/src/include/pw3270/class.h index 90ef00c..578737e 100644 --- a/src/include/pw3270/class.h +++ b/src/include/pw3270/class.h @@ -69,7 +69,13 @@ }; +#if defined (HAVE_GNUC_VISIBILITY) + class __attribute__((visibility("default"))) session +#elif defined(WIN32) + class __declspec (dllexport) session +#else class session +#endif { public: @@ -82,9 +88,6 @@ static session * get_default(void); static void set_plugin(session * (*factory)(const char *name)); - // Object settings - void set_charset(const char *charset); - // Log management void log(const char *fmt, ...); void logva(const char *fmt, va_list args); @@ -93,6 +96,8 @@ virtual string get_version(void); virtual string get_revision(void); + virtual const char * get_charset(void); + virtual bool is_connected(void) = 0; virtual bool is_ready(void) = 0; @@ -139,6 +144,16 @@ virtual int popup_dialog(LIB3270_NOTIFY id , const char *title, const char *message, const char *fmt, ...); virtual string * file_chooser_dialog(GtkFileChooserAction action, const char *title, const char *extension, const char *filename); + string * get_3270_text(string *str); + string * get_local_text(string *str); + + protected: +#ifdef WIN32 + void set_charset(const char *remote = 0, const char *local = "CP1252"); +#else + void set_charset(const char *remote = 0, const char *local = "UTF-8"); +#endif // WIN32 + private: session * prev; diff --git a/src/plugins/rx3270/rx3270.cc b/src/plugins/rx3270/rx3270.cc index 16bc2b3..d884ec5 100644 --- a/src/plugins/rx3270/rx3270.cc +++ b/src/plugins/rx3270/rx3270.cc @@ -46,7 +46,7 @@ #include #include - static rx3270 * factory_default(const char *type); + static rx3270 * factory_default(const char *type); /*--[ Globals ]--------------------------------------------------------------------------------------*/ -- libgit2 0.21.2