From 60f3a050afe78dbfd5e463f9e64f667cc0375d65 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Wed, 21 Nov 2018 16:33:27 -0200 Subject: [PATCH] Workin on new C++ API. --- src/include/lib3270++.h | 9 +++++++++ src/lib3270++/lib3270++.cbp | 3 ++- src/lib3270++/local.cc | 231 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/lib3270++/local/events.cc | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib3270++/local/session.cc | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib3270++/private.h | 80 ++++++++++++++++++++++++++++++++++++++++++++------------------------------------ src/lib3270++/session.cc | 2 +- 7 files changed, 394 insertions(+), 269 deletions(-) delete mode 100644 src/lib3270++/local.cc create mode 100644 src/lib3270++/local/events.cc create mode 100644 src/lib3270++/local/session.cc diff --git a/src/include/lib3270++.h b/src/include/lib3270++.h index 68f8480..99f19ad 100644 --- a/src/include/lib3270++.h +++ b/src/include/lib3270++.h @@ -74,6 +74,7 @@ Popup, ///< @brief Popup message. Trace, ///< @brief Trace message. Message, ///< @brief Generic message. + Connection ///< @brief Connect/Disconnect event. }; private: @@ -220,6 +221,10 @@ return getConnectionState(); } + inline bool operator==(ConnectionState state) const noexcept { + return this->getConnectionState() == state; + } + // Set contents. /// @brief Set field at current posicion, jumps to next writable field. @@ -272,6 +277,10 @@ Host(const char *id = nullptr, const char *url = nullptr); ~Host(); + inline bool operator==(ConnectionState state) const noexcept { + return session->getConnectionState() == state; + } + inline void connect(const char *url) { this->session->connect(url); } diff --git a/src/lib3270++/lib3270++.cbp b/src/lib3270++/lib3270++.cbp index 20c1d7f..bf67e08 100644 --- a/src/lib3270++/lib3270++.cbp +++ b/src/lib3270++/lib3270++.cbp @@ -46,7 +46,8 @@ - + + diff --git a/src/lib3270++/local.cc b/src/lib3270++/local.cc deleted file mode 100644 index 3dc4534..0000000 --- a/src/lib3270++/local.cc +++ /dev/null @@ -1,231 +0,0 @@ -/* - * "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. - * - * 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 lib3270++.h 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 src/lib3270++/local.cc - * - * @brief Implement lib3270 direct access layout (NO IPC). - * - * @author perry.werneck@gmail.com - * - */ - - #include "private.h" - #include - - using std::string; - -/*---[ Implement ]----------------------------------------------------------------------------------*/ - - namespace TN3270 { - - LocalSession::LocalSession() : Abstract::Session() { - - std::lock_guard lock(sync); - - this->hSession = lib3270_session_new(""); - lib3270_set_user_data(this->hSession,(void *) this); - setCharSet(lib3270_get_display_charset(this->hSession)); - - lib3270_set_popup_handler(this->hSession, popupHandler); - - } - - /// @brief Popup Handler. - int LocalSession::popupHandler(H3270 *h3270, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) { - - LocalSession * session = (LocalSession *) lib3270_get_user_data(h3270); - - if(!session) { - throw std::runtime_error("Invalid session handler"); - } - - class PopupEvent : public Event { - private: - LIB3270_NOTIFY type; - string title; - string msg; - string description; - - public: - PopupEvent(LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) : Event(Event::Popup) { - - this->type = type; - this->title = title; - this->msg = msg; - - char * buffer = NULL; - if(vasprintf(&buffer,fmt,arg) != -1) { - this->description = buffer; - free(buffer); - } - -#ifdef DEBUG - std::cerr << "Popup:" << std::endl - << "\t" << title << std::endl - << "\t" << msg << std::endl - << "\t" << description << std::endl; -#endif // DEBUG - - } - - virtual ~PopupEvent() { - } - - /// @brief Get event description. - std::string toString() const override { - return msg; - } - - - }; - - session->fire(PopupEvent(type,title,msg,fmt,arg)); - - return 0; - - } - - LocalSession::~LocalSession() { - - std::lock_guard lock(sync); - - lib3270_session_free(this->hSession); - this->hSession = nullptr; - } - - void LocalSession::wait(time_t timeout) { - - int rc = lib3270_wait_for_ready(this->hSession, timeout); - - if(rc) { - throw std::system_error(rc, std::system_category()); - } - - } - - void LocalSession::connect(const char *url) { - std::lock_guard lock(sync); - int rc = lib3270_connect_url(hSession,url,0); - - if(rc) { - throw std::system_error(rc, std::system_category()); - } - - wait(); - - } - - void LocalSession::disconnect() { - std::lock_guard lock(sync); - lib3270_disconnect(hSession); - } - - // Wait for session state. - void LocalSession::waitForReady(time_t timeout) throw() { - - std::lock_guard lock(sync); - wait(timeout); - - } - - // Gets - std::string LocalSession::toString() const { - std::lock_guard lock(const_cast(this)->sync); - } - - std::string LocalSession::toString(int baddr, size_t len, bool lf) { - std::lock_guard lock(sync); - } - - std::string LocalSession::toString(int row, int col, size_t sz, bool lf) { - std::lock_guard lock(sync); - } - - ProgramMessage LocalSession::getProgramMessage() const { - std::lock_guard lock(const_cast(this)->sync); - return (ProgramMessage) lib3270_get_program_message(this->hSession); - } - - ConnectionState LocalSession::getConnectionState() const { - std::lock_guard lock(const_cast(this)->sync); - return (ConnectionState) lib3270_get_connection_state(this->hSession); - } - - /// @brief Set field at current posicion, jumps to next writable field. - TN3270::Session & LocalSession::push(const char *text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & LocalSession::push(int baddr, const std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & LocalSession::push(int row, int col, const std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & LocalSession::push(const PFKey key) { - std::lock_guard lock(sync); - lib3270_pfkey(hSession,(int) key); - return *this; - } - - TN3270::Session & LocalSession::push(const PAKey key) { - std::lock_guard lock(sync); - lib3270_pakey(hSession,(int) key); - return *this; - } - - TN3270::Session & LocalSession::push(const Action action) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & LocalSession::pop(int baddr, std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & LocalSession::pop(int row, int col, std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - TN3270::Session & LocalSession::pop(std::string &text) { - std::lock_guard lock(sync); - return *this; - } - - } - - diff --git a/src/lib3270++/local/events.cc b/src/lib3270++/local/events.cc new file mode 100644 index 0000000..597dca0 --- /dev/null +++ b/src/lib3270++/local/events.cc @@ -0,0 +1,147 @@ +/* + * "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. + * + * 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 lib3270++.h 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 src/lib3270++/local/events.cc + * + * @brief Implement lib3270 direct access events. + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + + extern "C" { + #include + #include + } + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + /// @brief Popup Handler. + int Local::Session::popupHandler(H3270 *h3270, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) { + + Local::Session * session = (Local::Session *) lib3270_get_user_data(h3270); + + if(!session) { + throw std::runtime_error("Invalid session handler"); + } + + class PopupEvent : public TN3270::Event { + private: + LIB3270_NOTIFY type; + string title; + string msg; + string description; + + public: + PopupEvent(LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg) : Event(Event::Popup) { + + this->type = type; + this->title = title; + this->msg = msg; + + char * buffer = NULL; + if(vasprintf(&buffer,fmt,arg) != -1) { + this->description = buffer; + free(buffer); + } + +#ifdef DEBUG + std::cerr << "Popup:" << std::endl + << "\t" << title << std::endl + << "\t" << msg << std::endl + << "\t" << description << std::endl; +#endif // DEBUG + + } + + virtual ~PopupEvent() { + } + + /// @brief Get event description. + std::string toString() const override { + return msg; + } + + + }; + + session->fire(PopupEvent(type,title,msg,fmt,arg)); + + return 0; + + } + + /// @brief Connect Handler. + void Local::Session::connectHandler(H3270 *h3270, unsigned char connected) { + + Local::Session * session = (Local::Session *) lib3270_get_user_data(h3270); + + if(!session) { + throw std::runtime_error("Invalid session handler"); + } + + class ConnectionEvent : public TN3270::Event { + private: + bool connected; + + public: + ConnectionEvent(unsigned char connected) : Event(Event::Connection) { + this->connected = (connected != 0); + +#ifdef DEBUG + std::cerr << "Session is " << this->toString().c_str() << std::endl; +#endif // DEBUG + + } + + virtual ~ConnectionEvent() { + } + + /// @brief Get event description. + std::string toString() const override { + return this->connected ? "connected" : "disconnected"; + } + + }; + + session->fire(ConnectionEvent(connected)); + + } + + + } + + diff --git a/src/lib3270++/local/session.cc b/src/lib3270++/local/session.cc new file mode 100644 index 0000000..ef69765 --- /dev/null +++ b/src/lib3270++/local/session.cc @@ -0,0 +1,191 @@ +/* + * "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. + * + * 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 lib3270++.h 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 src/lib3270++/local/session.cc + * + * @brief Implement lib3270 direct access layout (NO IPC). + * + * @author perry.werneck@gmail.com + * + */ + + #include "../private.h" + + extern "C" { + #include + #include + } + + using std::string; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + Local::Session::Session() : Abstract::Session() { + + std::lock_guard lock(sync); + + this->hSession = lib3270_session_new(""); + lib3270_set_user_data(this->hSession,(void *) this); + setCharSet(lib3270_get_display_charset(this->hSession)); + + lib3270_set_popup_handler(this->hSession, popupHandler); + + // Setup callbacks + struct lib3270_session_callbacks *cbk; + + cbk = lib3270_get_session_callbacks(this->hSession,sizeof(struct lib3270_session_callbacks)); + if(!cbk) { + throw std::runtime_error( "Invalid callback table, possible version mismatch in lib3270" ); + } + + cbk->update_connect = connectHandler; + + + } + + Local::Session::~Session() { + + std::lock_guard lock(sync); + + lib3270_session_free(this->hSession); + this->hSession = nullptr; + } + + void Local::Session::wait(time_t timeout) { + + int rc = lib3270_wait_for_ready(this->hSession, timeout); + + if(rc) { + throw std::system_error(rc, std::system_category()); + } + + } + + void Local::Session::connect(const char *url) { + std::lock_guard lock(sync); + int rc = lib3270_connect_url(hSession,url,0); + + if(rc) { + throw std::system_error(rc, std::system_category()); + } + + wait(); + + } + + void Local::Session::disconnect() { + std::lock_guard lock(sync); + lib3270_disconnect(hSession); + } + + // Wait for session state. + void Local::Session::waitForReady(time_t timeout) throw() { + + std::lock_guard lock(sync); + wait(timeout); + + } + + // Gets + std::string Local::Session::toString() const { + std::lock_guard lock(const_cast(this)->sync); + } + + std::string Local::Session::toString(int baddr, size_t len, bool lf) { + std::lock_guard lock(sync); + } + + std::string Local::Session::toString(int row, int col, size_t sz, bool lf) { + std::lock_guard lock(sync); + } + + ProgramMessage Local::Session::getProgramMessage() const { + std::lock_guard lock(const_cast(this)->sync); + return (ProgramMessage) lib3270_get_program_message(this->hSession); + } + + ConnectionState Local::Session::getConnectionState() const { + std::lock_guard lock(const_cast(this)->sync); + return (ConnectionState) lib3270_get_connection_state(this->hSession); + } + + /// @brief Set field at current posicion, jumps to next writable field. + TN3270::Session & Local::Session::push(const char *text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::push(int baddr, const std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::push(int row, int col, const std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::push(const PFKey key) { + std::lock_guard lock(sync); + lib3270_pfkey(hSession,(int) key); + return *this; + } + + TN3270::Session & Local::Session::push(const PAKey key) { + std::lock_guard lock(sync); + lib3270_pakey(hSession,(int) key); + return *this; + } + + TN3270::Session & Local::Session::push(const Action action) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::pop(int baddr, std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::pop(int row, int col, std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + TN3270::Session & Local::Session::pop(std::string &text) { + std::lock_guard lock(sync); + return *this; + } + + } + + diff --git a/src/lib3270++/private.h b/src/lib3270++/private.h index 2ad33d8..0bbd92c 100644 --- a/src/lib3270++/private.h +++ b/src/lib3270++/private.h @@ -100,56 +100,64 @@ } - class TN3270_PRIVATE LocalSession : public Abstract::Session { - private: + /// @brief lib3270 direct access objects (no IPC); + namespace Local { - /// @brief Handle of the related instance of lib3270 - H3270 * hSession; + class TN3270_PRIVATE Session : public TN3270::Abstract::Session { + private: + + /// @brief Handle of the related instance of lib3270 + H3270 * hSession; + + /// @brief Mutex to serialize access to lib3270 + std::mutex sync; + + /// @brief Popup Handler. + static int popupHandler(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg); - /// @brief Mutex to serialize access to lib3270 - std::mutex sync; + /// @brief Connect Handler. + static void connectHandler(H3270 *session, unsigned char connected); - /// @brief Popup Handler. - static int popupHandler(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg); + /// @brief Wait for network events + void wait(time_t timeout = 5); - /// @brief Wait for network events - void wait(time_t timeout = 5); + public: + Session(); + virtual ~Session(); - public: - LocalSession(); - virtual ~LocalSession(); + // Connect/disconnect + void connect(const char *url) override; + void disconnect() override; - // Connect/disconnect - void connect(const char *url) override; - void disconnect() override; + // Wait for session state. + void waitForReady(time_t timeout = 5) throw() override; - // Wait for session state. - void waitForReady(time_t timeout = 5) throw() override; + // Gets + std::string toString() const override; + std::string toString(int baddr = 0, size_t len = -1, bool lf = false) override; + std::string toString(int row, int col, size_t sz, bool lf = false) override; - // Gets - std::string toString() const override; - std::string toString(int baddr = 0, size_t len = -1, bool lf = false) override; - std::string toString(int row, int col, size_t sz, bool lf = false) override; + ProgramMessage getProgramMessage() const override; - ProgramMessage getProgramMessage() const override; + ConnectionState getConnectionState() const override; - ConnectionState getConnectionState() const override; + /// @brief Set field at current posicion, jumps to next writable field. + TN3270::Session & push(const char *text) override; - /// @brief Set field at current posicion, jumps to next writable field. - TN3270::Session & push(const char *text) override; + TN3270::Session & push(int baddr, const std::string &text) override; + TN3270::Session & push(int row, int col, const std::string &text) override; + TN3270::Session & push(const PFKey key) override; + TN3270::Session & push(const PAKey key) override; + TN3270::Session & push(const Action action) override; - TN3270::Session & push(int baddr, const std::string &text) override; - TN3270::Session & push(int row, int col, const std::string &text) override; - TN3270::Session & push(const PFKey key) override; - TN3270::Session & push(const PAKey key) override; - TN3270::Session & push(const Action action) override; + // Get contents. + TN3270::Session & pop(int baddr, std::string &text) override; + TN3270::Session & pop(int row, int col, std::string &text) override; + TN3270::Session & pop(std::string &text) override; - // Get contents. - TN3270::Session & pop(int baddr, std::string &text) override; - TN3270::Session & pop(int row, int col, std::string &text) override; - TN3270::Session & pop(std::string &text) override; + }; - }; + } } diff --git a/src/lib3270++/session.cc b/src/lib3270++/session.cc index 60651c9..9806141 100644 --- a/src/lib3270++/session.cc +++ b/src/lib3270++/session.cc @@ -47,7 +47,7 @@ Session * Session::create(const char *id) { if(!id) { - return new LocalSession(); + return new Local::Session(); } throw std::system_error(EINVAL, std::system_category()); -- libgit2 0.21.2