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