diff --git a/client/src/core/session.cc b/client/src/core/session.cc index 5953db8..fe21e7d 100644 --- a/client/src/core/session.cc +++ b/client/src/core/session.cc @@ -378,11 +378,25 @@ return rc; } - /// @brief Search + /// @brief Checks if the terminal contains the string. size_t Session::find(const char * str, size_t pos) const { return toString((int) 0,(int) -1, '\0').find(str,pos); } + /// @brief Get the number of occurrences of a string in the terminal. + size_t Session::count(const char * str, size_t pos) const { + + std::string contents = toString((int) 0,(int) -1, '\0'); + size_t rc = 0; + + while( (pos = contents.find(str,pos)) != std::string::npos) { + rc++; + } + + return rc; + + } + /// @brief Compare contents. int Session::compare(int baddr, const char* s, int len) const { diff --git a/client/src/host/string.cc b/client/src/host/string.cc index a9f747c..09178f8 100644 --- a/client/src/host/string.cc +++ b/client/src/host/string.cc @@ -60,7 +60,7 @@ std::string TN3270::Host::toString(unsigned short row, unsigned short col, int l } -/// @brief Search +/// @brief Checks if the terminal contains the string. size_t TN3270::Host::find(const char * str, size_t pos) const { this->session->waitForReady(this->timeout); @@ -68,6 +68,14 @@ size_t TN3270::Host::find(const char * str, size_t pos) const { } +/// @brief Get the number of occurrences of a string in the terminal. +size_t TN3270::Host::count(const char * str, size_t pos) const { + + this->session->waitForReady(this->timeout); + return this->session->count(str,pos); + +} + /// @brief Compare contents. int TN3270::Host::compare(int baddr, const char* s, int len) const { diff --git a/client/src/include/lib3270/ipc.h b/client/src/include/lib3270/ipc.h index 3f7b9a7..a5291e3 100644 --- a/client/src/include/lib3270/ipc.h +++ b/client/src/include/lib3270/ipc.h @@ -585,9 +585,12 @@ /// @brief Create an action object virtual Action * getAction(const LIB3270_ACTION *descriptor); - /// @brief Search + /// @brief Checks if the terminal contains the string. size_t find(const char * str, size_t pos = 0) const; + /// @brief Get the number of occurrences of a string in the terminal. + size_t count(const char * str, size_t pos = 0) const; + /// @brief Compare contents. int compare(int baddr, const char* s, int len = -1) const; int compare(unsigned short row, unsigned short col, const char* s, int len = -1) const; @@ -863,9 +866,12 @@ return session->wait(addr,text,timeout); } - /// @brief Search + /// @brief Checks if the terminal contains the string. size_t find(const char * str, size_t pos = 0) const; + /// @brief Get the number of occurrences of a string in the terminal. + size_t count(const char * str, size_t pos = 0) const; + /// @brief Compare contents. int compare(int baddr, const char* s, int len = -1) const; int compare(unsigned short row, unsigned short col, const char* s, int len = -1) const; diff --git a/client/src/include/lib3270/ipc/action.h b/client/src/include/lib3270/ipc/action.h index af41c74..eee6567 100644 --- a/client/src/include/lib3270/ipc/action.h +++ b/client/src/include/lib3270/ipc/action.h @@ -53,12 +53,12 @@ Action(const LIB3270_ACTION *descriptor); public: - virtual bool activatable() const noexcept = 0; + virtual bool activatable() const = 0; virtual void activate() = 0; virtual void wait(time_t seconds = 0) = 0; virtual ~Action(); - inline operator bool() const noexcept { + inline operator bool() const { return activatable(); } diff --git a/client/src/session/remote/actions.cc b/client/src/session/remote/actions.cc index bab92bd..494fdd0 100644 --- a/client/src/session/remote/actions.cc +++ b/client/src/session/remote/actions.cc @@ -47,6 +47,30 @@ namespace TN3270 { + IPC::Action::Action(Session *session, const LIB3270_ACTION *descriptor) : TN3270::Action(descriptor) { + this->session = session; + } + + bool IPC::Action::activatable() const { + + bool rc; + + Request(*session,"activatable") + .push(descriptor->name) + .call() + .pop(rc); + + return rc; + } + + void IPC::Action::activate() { + session->action(descriptor->name); + } + + void IPC::Action::wait(time_t seconds) { + session->waitForReady(seconds); + } + void IPC::Session::action(const char *action_name) { int32_t rc; diff --git a/client/src/session/remote/private.h b/client/src/session/remote/private.h index c62f353..99672b8 100644 --- a/client/src/session/remote/private.h +++ b/client/src/session/remote/private.h @@ -42,6 +42,7 @@ #include #include + #include #include #include #include @@ -53,6 +54,20 @@ namespace IPC { + class Session; + + class Action : public TN3270::Action { + private: + Session *session; + + public: + Action(Session *session, const LIB3270_ACTION *descriptor); + bool activatable() const override; + void activate() override; + void wait(time_t seconds) override; + + }; + class TN3270_PRIVATE Session : public TN3270::Abstract::Session { private: diff --git a/server/src/core/getproperties.c b/server/src/core/getproperties.c index cb1e26b..a80fbed 100644 --- a/server/src/core/getproperties.c +++ b/server/src/core/getproperties.c @@ -65,7 +65,7 @@ GVariant * ipc3270_get_property(GObject *object, const gchar *property_name, GEr } // Erro! - ipc3270_set_error(object,ENOENT,error); + ipc3270_set_error(object,errno,error); return NULL; } diff --git a/server/src/core/linux/gobject.c b/server/src/core/linux/gobject.c index 9477968..e85161b 100644 --- a/server/src/core/linux/gobject.c +++ b/server/src/core/linux/gobject.c @@ -112,6 +112,10 @@ void ipc3270_add_terminal_introspection(GString *introspection) { " " \ " " \ " " + " " + " " \ + " " \ + " " " " \ " " \ " " \ diff --git a/server/src/core/methods/action.c b/server/src/core/methods/action.c index 032a090..d768ee4 100644 --- a/server/src/core/methods/action.c +++ b/server/src/core/methods/action.c @@ -46,3 +46,24 @@ int ipc3270_method_action(GObject *session, GVariant *request, GObject *response return 0; } +int ipc3270_method_activatable(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) { + + if(g_variant_n_children(request) != 1) { + g_message("activatable was called with %u arguments.",(unsigned int) g_variant_n_children(request)); + ipc3270_response_append_int32(response, EINVAL); + } + + GVariant *value = g_variant_get_child_value(request,0); + + LIB3270_ACTION * action = lib3270_action_get_by_name(g_variant_get_string(value,NULL)); + + if(action) { + ipc3270_response_append_int32(response, lib3270_action_is_activatable(action, ipc3270_get_session(session))); + } else { + ipc3270_response_append_int32(response, ENOENT); + } + + g_variant_unref(value); + + return 0; +} diff --git a/server/src/core/methods/methods.c b/server/src/core/methods/methods.c index 3810c9c..608ae3a 100644 --- a/server/src/core/methods/methods.c +++ b/server/src/core/methods/methods.c @@ -72,6 +72,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req { "setCursorPosition", ipc3270_method_set_cursor }, { "action", ipc3270_method_action }, + { "activatable", ipc3270_method_activatable }, }; @@ -98,31 +99,13 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req } // Check actions table. - const LIB3270_ACTION * action = lib3270_get_action(method_name); + const LIB3270_ACTION * action = lib3270_action_get_by_name(method_name); if(action) { if(lib3270_action_activate(action,hSession)) { ipc3270_set_error(object,errno,error); } return 0; } - /* - const LIB3270_ACTION * actions = lib3270_get_actions(); - for(ix = 0; actions[ix].name; ix++) { - - if(!g_ascii_strcasecmp(actions[ix].name,method_name)) { - - if(!actions[ix].enabled(hSession)) - ipc3270_set_error(object,EPERM,error); - else if(actions[ix].activate(hSession)) - ipc3270_set_error(object,errno,error); - else - ipc3270_response_append_int32(response, 0); - - return 0; - - } - } - */ // Check lib3270 internal methods const IPC_METHOD_INT_ARG * int_methods = ipc3270_get_int_arg_methods(); diff --git a/server/src/core/methods/private.h b/server/src/core/methods/private.h index 4958541..a73fbaf 100644 --- a/server/src/core/methods/private.h +++ b/server/src/core/methods/private.h @@ -58,6 +58,7 @@ G_GNUC_INTERNAL int ipc3270_method_set_cursor(GObject *session, GVariant *request, GObject *response, GError **error); G_GNUC_INTERNAL int ipc3270_method_action(GObject *session, GVariant *request, GObject *response, GError **error); + G_GNUC_INTERNAL int ipc3270_method_activatable(GObject *session, GVariant *request, GObject *response, GError **error); G_GNUC_INTERNAL int ipc3270_method_get_field_attribute(GObject *session, GVariant *request, GObject *response, GError **error); -- libgit2 0.21.2