diff --git a/client/ipcclient.cbp b/client/ipcclient.cbp index 919b525..e3276ea 100644 --- a/client/ipcclient.cbp +++ b/client/ipcclient.cbp @@ -80,6 +80,7 @@ + diff --git a/client/src/core/linux/request.cc b/client/src/core/linux/request.cc index 4076d11..10609f6 100644 --- a/client/src/core/linux/request.cc +++ b/client/src/core/linux/request.cc @@ -78,7 +78,7 @@ dbus_message_iter_init(msg.in, &msg.iter); - debug(__FUNCTION__," got a valid response"); +// debug(__FUNCTION__," got a valid response"); return *this; @@ -196,6 +196,65 @@ } + static unsigned int getBooleanValue(DBusMessageIter &iter) { + + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32) { + + dbus_uint32_t rc = 0; + dbus_message_iter_get_basic(&iter, &rc); + return rc != 0; + + } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT16) { + + dbus_uint16_t rc = 0; + dbus_message_iter_get_basic(&iter, &rc); + return rc != 0; + + } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_BOOLEAN) { + + dbus_bool_t rc = 0; + dbus_message_iter_get_basic(&iter, &rc); + return rc; + + } else if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { + + DBusMessageIter sub; + int current_type; + + dbus_message_iter_recurse(&iter, &sub); + + while ((current_type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_UINT32) { + + dbus_uint32_t rc = 0; + dbus_message_iter_get_basic(&sub, &rc); + return rc != 0; + + } else if (current_type == DBUS_TYPE_UINT16) { + + dbus_uint16_t rc = 0; + dbus_message_iter_get_basic(&sub, &rc); + return rc != 0; + + } else if (current_type == DBUS_TYPE_BOOLEAN) { + + dbus_bool_t rc = 0; + dbus_message_iter_get_basic(&sub, &rc); + return rc; + + } + + dbus_message_iter_next(&sub); + } + + } + + debug("Argument type is ", ((char) dbus_message_iter_get_arg_type(&iter)) ); + throw std::runtime_error("Expected an integer data type"); + + } + static int getIntValue(DBusMessageIter &iter) { if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) { @@ -247,7 +306,7 @@ value = getIntValue(msg.iter); dbus_message_iter_next(&msg.iter); - debug(__FUNCTION__,"= \"",value,"\""); +// debug(__FUNCTION__,"= \"",value,"\""); return *this; @@ -257,7 +316,17 @@ value = getUIntValue(msg.iter); dbus_message_iter_next(&msg.iter); - debug(__FUNCTION__,"= \"",value,"\""); +// debug(__FUNCTION__,"= \"",value,"\""); + + return *this; + + } + + IPC::Request & IPC::Request::Request::pop(bool &value) { + + value = getBooleanValue(msg.iter); + dbus_message_iter_next(&msg.iter); +// debug(__FUNCTION__,"= \"",value,"\""); return *this; diff --git a/client/src/core/session.cc b/client/src/core/session.cc index 0e9732c..5953db8 100644 --- a/client/src/core/session.cc +++ b/client/src/core/session.cc @@ -409,6 +409,7 @@ throw std::system_error(ENOTSUP, std::system_category()); } + /* Attribute Session::getAttribute(const char *name) const { throw std::system_error(ENOTSUP, std::system_category()); } @@ -416,6 +417,7 @@ void Session::getAttributes(std::vector & attributes) const { throw std::system_error(ENOTSUP, std::system_category()); } + */ std::vector Session::getAttributes() const { std::vector attributes; diff --git a/client/src/include/lib3270/ipc.h b/client/src/include/lib3270/ipc.h index f6bb85e..3f7b9a7 100644 --- a/client/src/include/lib3270/ipc.h +++ b/client/src/include/lib3270/ipc.h @@ -496,8 +496,8 @@ LIB3270_KEYBOARD_LOCK_STATE input(const std::string &str, const char control_char = '@'); // Attributes - virtual Attribute getAttribute(const char *name) const; - virtual void getAttributes(std::vector & attributes) const; + virtual Attribute getAttribute(const char *name) const = 0; + virtual void getAttributes(std::vector & attributes) const = 0; std::vector getAttributes() const; virtual void getAttribute(const char *name, int &value) const; diff --git a/client/src/include/lib3270/ipc/request.h b/client/src/include/lib3270/ipc/request.h index 62d1dc6..2a57453 100644 --- a/client/src/include/lib3270/ipc/request.h +++ b/client/src/include/lib3270/ipc/request.h @@ -155,6 +155,7 @@ Request & pop(std::string &value); Request & pop(int &value); Request & pop(unsigned int &value); + Request & pop(bool &value); }; diff --git a/client/src/session/local/attribute.cc b/client/src/session/local/attribute.cc index 7473e00..8508340 100644 --- a/client/src/session/local/attribute.cc +++ b/client/src/session/local/attribute.cc @@ -156,6 +156,7 @@ }; + // Unsigned int attribute class TN3270_PRIVATE UnsignedIntAttribute : public TemplateAttribute { public: UnsignedIntAttribute(H3270 *hSession, const LIB3270_UINT_PROPERTY *worker) : TemplateAttribute(hSession, Attribute::Boolean, worker) { @@ -190,6 +191,7 @@ } }; + // String attribute class TN3270_PRIVATE StringAttribute : public TemplateAttribute { public: StringAttribute(H3270 *hSession, const LIB3270_STRING_PROPERTY *worker) : TemplateAttribute(hSession, Attribute::String, worker) { @@ -226,6 +228,7 @@ } }; + // Toggle attribute class TN3270_PRIVATE ToggleAttribute : public TemplateAttribute { public: ToggleAttribute(H3270 *hSession, const LIB3270_TOGGLE_ENTRY *worker) : TemplateAttribute(hSession, Attribute::Boolean, worker) { diff --git a/client/src/session/remote/attribute.cc b/client/src/session/remote/attribute.cc new file mode 100644 index 0000000..7bf57ec --- /dev/null +++ b/client/src/session/remote/attribute.cc @@ -0,0 +1,345 @@ +/* + * "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 - 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 + * + * @brief + * + * @author perry.werneck@gmail.com + * + */ + + #include "private.h" + #include + #include + #include + #include + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + // Class template + template + class TN3270_PRIVATE TemplateAttribute : public Attribute { + protected: + + struct Worker { + const T *methods; + IPC::Session * session; + }; + + public: + + TemplateAttribute(const IPC::Session *session, Attribute::Type type, const T *methods) : Attribute(type, sizeof(struct Worker)) { + + getWorker()->session = const_cast(session); + getWorker()->methods = methods; + + get.name = [](const void *worker) { + return ((const struct Worker *) worker)->methods->name; + }; + + get.description = [](const void *worker) { + return ((const struct Worker *) worker)->methods->description; + }; + + } + + inline struct Worker * getWorker() { + return (struct Worker *) this->data; + } + + }; + + // Signed int attribute + class TN3270_PRIVATE IntAttribute : public TemplateAttribute { + public: + IntAttribute(const IPC::Session *session, const LIB3270_INT_PROPERTY *worker) : TemplateAttribute(session, Attribute::Int32, worker) { + + get.asString = [](const Attribute & attr, const void *worker) { + return std::to_string(attr.getInt32()); + }; + + get.asInt32 = [](const Attribute & attr, const void *worker) { + + const struct Worker * w = (const struct Worker *) worker; + + int value; + + IPC::Request(*w->session,false,w->methods->name) + .call() + .pop(value); + + return (int32_t) value; + + }; + + get.asUint32 = [](const Attribute & attr, const void *worker) { + return (uint32_t) attr.getInt32(); + }; + + get.asBoolean = [](const Attribute & attr, const void *worker) { + return (attr.getInt32() != 0); + }; + + + } + + }; + + // Boolean attribute + class TN3270_PRIVATE BooleanAttribute : public TemplateAttribute { + public: + BooleanAttribute(const IPC::Session *session, const LIB3270_INT_PROPERTY *worker) : TemplateAttribute(session, Attribute::Boolean, worker) { + + get.asString = [](const Attribute & attr, const void *worker) { + return attr.getBoolean() ? "true" : "false"; + }; + + get.asInt32 = [](const Attribute & attr, const void *worker) { + return (uint32_t) attr.getBoolean(); + }; + + get.asUint32 = [](const Attribute & attr, const void *worker) { + return (uint32_t) attr.getInt32(); + }; + + get.asBoolean = [](const Attribute & attr, const void *worker) { + + const struct Worker * w = (const struct Worker *) worker; + + bool value; + + IPC::Request(*w->session,false,w->methods->name) + .call() + .pop(value); + + return value; + }; + + + } + + }; + + // Unsigned int attribute + class TN3270_PRIVATE UnsignedIntAttribute : public TemplateAttribute { + public: + UnsignedIntAttribute(const IPC::Session *session, const LIB3270_UINT_PROPERTY *worker) : TemplateAttribute(session, Attribute::Boolean, worker) { + + get.asString = [](const Attribute & attr, const void *worker) { + return std::to_string(attr.getUint32()); + }; + + get.asInt32 = [](const Attribute & attr, const void *worker) { + return (int32_t) attr.getUint32(); + }; + + get.asUint32 = [](const Attribute & attr, const void *worker) { + + const struct Worker * w = (const struct Worker *) worker; + + unsigned int value; + + IPC::Request(*w->session,false,w->methods->name) + .call() + .pop(value); + + return (uint32_t) value; + + }; + + get.asBoolean = [](const Attribute & attr, const void *worker) { + return (attr.getUint32() != 0); + }; + + } + }; + + // String attribute + class TN3270_PRIVATE StringAttribute : public TemplateAttribute { + public: + StringAttribute(const IPC::Session *session, const LIB3270_STRING_PROPERTY *worker) : TemplateAttribute(session, Attribute::String, worker) { + + get.asString = [](const Attribute & attr, const void *worker) { + + + const struct Worker * w = (const struct Worker *) worker; + string value; + + IPC::Request(*w->session,false,w->methods->name) + .call() + .pop(value); + + return value; + + }; + + get.asInt32 = [](const Attribute & attr, const void *worker) { + + const struct Worker * w = (const struct Worker *) worker; + string value; + + IPC::Request(*w->session,false,w->methods->name) + .call() + .pop(value); + + return atoi(value.c_str()); + + }; + + + } + }; + + Attribute IPC::Session::getAttribute(const char *name) const { + + // Check for integer properties. + { + const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + + if(!strcasecmp(name,intprop[ix].name)) { + return IntAttribute(this,&intprop[ix]); + } + + } + } + + // Check for unsigned int properties + { + const LIB3270_UINT_PROPERTY * intprop = lib3270_get_unsigned_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + + if(!strcasecmp(name,intprop[ix].name)) { + return UnsignedIntAttribute(this,&intprop[ix]); + } + + } + + } + + // Check for string properties + { + const LIB3270_STRING_PROPERTY * strprop = lib3270_get_string_properties_list(); + + for(size_t ix = 0; strprop[ix].name; ix++) { + + if(!strcasecmp(name,strprop[ix].name)) { + return StringAttribute(this,&strprop[ix]); + } + + } + + } + + // Check for boolean properties + { + /* + const LIB3270_TOGGLE_ENTRY *toggles = lib3270_get_toggle_list(); + for(size_t ix = 0; toggles[ix].name; ix++) { + + if(!strcasecmp(name,toggles[ix].name)) { + return ToggleAttribute(this,&toggles[ix]); + } + + } + */ + + const LIB3270_INT_PROPERTY * intprop = lib3270_get_boolean_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + + if(!strcasecmp(name,intprop[ix].name)) { + return BooleanAttribute(this,&intprop[ix]); + } + + } + + } + + + // Not found! + throw std::runtime_error("Invalid attribute"); + + } + + void IPC::Session::getAttributes(std::vector & attributes) const { + + // Add integer properties. + { + const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + attributes.push_back(IntAttribute(this,&intprop[ix])); + } + } + + // Add unsigned int properties + { + const LIB3270_UINT_PROPERTY * intprop = lib3270_get_unsigned_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + attributes.push_back(UnsignedIntAttribute(this,&intprop[ix])); + } + + } + + // Add string properties + { + const LIB3270_STRING_PROPERTY * strprop = lib3270_get_string_properties_list(); + + for(size_t ix = 0; strprop[ix].name; ix++) { + attributes.push_back(StringAttribute(this,&strprop[ix])); + } + + } + + // Add boolean properties + { + /* + const LIB3270_TOGGLE_ENTRY *toggles = lib3270_get_toggle_list(); + for(size_t ix = 0; toggles[ix].name; ix++) { + attributes.push_back(ToggleAttribute(this,&toggles[ix])); + } + */ + + const LIB3270_INT_PROPERTY * intprop = lib3270_get_boolean_properties_list(); + for(size_t ix = 0; intprop[ix].name; ix++) { + attributes.push_back(BooleanAttribute(this,&intprop[ix])); + } + + } + + } + + + + } + + diff --git a/client/src/session/remote/private.h b/client/src/session/remote/private.h index 813fbcb..c62f353 100644 --- a/client/src/session/remote/private.h +++ b/client/src/session/remote/private.h @@ -122,6 +122,10 @@ void setAttribute(const char *name, const int value) override; void setAttribute(const char *name, const char *value) override; + // Attributes + Attribute getAttribute(const char *name) const override; + void getAttributes(std::vector & attributes) const override; + std::string getVersion() const override; std::string getRevision() const override; std::string getLUName() const override; diff --git a/client/src/testprogram/testprogram.cc b/client/src/testprogram/testprogram.cc index 2ccbfcb..446f027 100644 --- a/client/src/testprogram/testprogram.cc +++ b/client/src/testprogram/testprogram.cc @@ -167,7 +167,7 @@ int main(int argc, char **argv) { - const char * session = ""; // ":a"; + const char * session = ":a"; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -- libgit2 0.21.2