Commit e74f305b5d49d5e329db67eebe985476777b9593

Authored by Perry Werneck
1 parent 5e054e6e
Exists in master and in 1 other branch develop

Adding dynamic typed properties on local session object.

client/ipcclient.cbp
... ... @@ -45,6 +45,7 @@
45 45 <Unit filename="src/core/constants.cc" />
46 46 <Unit filename="src/core/events.cc" />
47 47 <Unit filename="src/core/linux/request.cc" />
  48 + <Unit filename="src/core/property.cc" />
48 49 <Unit filename="src/core/session.cc" />
49 50 <Unit filename="src/core/windows/pop.cc" />
50 51 <Unit filename="src/core/windows/push.cc" />
... ... @@ -55,6 +56,7 @@
55 56 <Unit filename="src/host/init.cc" />
56 57 <Unit filename="src/host/pop.cc" />
57 58 <Unit filename="src/host/private.h" />
  59 + <Unit filename="src/host/properties.cc" />
58 60 <Unit filename="src/host/push.cc" />
59 61 <Unit filename="src/host/states.cc" />
60 62 <Unit filename="src/host/stream.cc" />
... ...
client/src/core/property.cc 0 → 100644
... ... @@ -0,0 +1,212 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @file src/core/property.cc
  32 + *
  33 + * @brief Implements type independent property object.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include <ipc-client-internals.h>
  40 + #include <string>
  41 + #include <cstring>
  42 + #include <stdexcept>
  43 +
  44 + using std::runtime_error;
  45 +
  46 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  47 +
  48 + namespace TN3270 {
  49 +
  50 + class StringProperty : public Property, std::string {
  51 + public:
  52 + StringProperty(const char *str) : Property(Property::String), std::string(str) {
  53 + }
  54 +
  55 + StringProperty(const std::string &str) : Property(Property::String), std::string(str) {
  56 + }
  57 +
  58 + std::string toString() const override {
  59 + return std::string(this->c_str());
  60 + }
  61 +
  62 + int32_t toInt32() const override {
  63 + return (int32_t) atoi(this->c_str());
  64 + }
  65 +
  66 + uint32_t toUint32() const override {
  67 + return (uint32_t) atoi(this->c_str());
  68 + }
  69 +
  70 + bool toBool() const override {
  71 + return atoi(this->c_str()) != 0;
  72 + }
  73 +
  74 + };
  75 +
  76 + Property::Property(Property::Type type) {
  77 + this->type = type;
  78 +
  79 + }
  80 +
  81 + Property::~Property() {
  82 + }
  83 +
  84 + std::string Property::toString() const {
  85 + throw runtime_error("The value can't be converted to string");
  86 + }
  87 +
  88 + int32_t Property::toInt32() const {
  89 + throw runtime_error("The value can't be converted to a signed integer");
  90 + }
  91 +
  92 + uint32_t Property::toUint32() const {
  93 + throw runtime_error("The value can't be converted to an unsigned integer");
  94 + }
  95 +
  96 + bool Property::toBool() const {
  97 + throw runtime_error("The value can't be converted to boolean");
  98 + }
  99 +
  100 +
  101 + Property * Property::create(const char *str) {
  102 + return new StringProperty(str);
  103 + }
  104 +
  105 + Property * Property::create(const std::string &str) {
  106 + return new StringProperty(str);
  107 + }
  108 +
  109 + Property * Property::create(const int value) {
  110 +
  111 + class Value : public Property {
  112 + private:
  113 + int32_t value;
  114 +
  115 + public:
  116 + Value(int value) : Property(Property::Int32) {
  117 + this->value = (int32_t) value;
  118 + }
  119 +
  120 + std::string toString() const override {
  121 + return std::to_string(value);
  122 + }
  123 +
  124 + int32_t toInt32() const override {
  125 + return (int32_t) value;
  126 + }
  127 +
  128 + uint32_t toUint32() const override {
  129 + return (uint32_t) value;
  130 + }
  131 +
  132 + bool toBool() const override {
  133 + return value != 0;
  134 + }
  135 +
  136 + };
  137 +
  138 + return new Value(value);
  139 +
  140 + }
  141 +
  142 + Property * Property::create(const unsigned int value) {
  143 +
  144 + class Value : public Property {
  145 + private:
  146 + uint32_t value;
  147 +
  148 + public:
  149 + Value(unsigned int value) : Property(Property::Uint32) {
  150 + this->value = (uint32_t) value;
  151 + }
  152 +
  153 + std::string toString() const override {
  154 + return std::to_string(value);
  155 + }
  156 +
  157 + int32_t toInt32() const override {
  158 + return (int32_t) value;
  159 + }
  160 +
  161 + uint32_t toUint32() const override {
  162 + return (uint32_t) value;
  163 + }
  164 +
  165 + bool toBool() const override {
  166 + return value != 0;
  167 + }
  168 +
  169 + };
  170 +
  171 + return new Value(value);
  172 +
  173 + }
  174 +
  175 + Property * Property::create(const bool value) {
  176 +
  177 + class Value : public Property {
  178 + private:
  179 + bool value;
  180 +
  181 + public:
  182 + Value(bool value) : Property(Property::Boolean) {
  183 + this->value = value;
  184 + }
  185 +
  186 + std::string toString() const override {
  187 + return std::to_string(value);
  188 + }
  189 +
  190 + int32_t toInt32() const override {
  191 + return (int32_t) value;
  192 + }
  193 +
  194 + uint32_t toUint32() const override {
  195 + return (uint32_t) value;
  196 + }
  197 +
  198 + bool toBool() const override {
  199 + return value;
  200 + }
  201 +
  202 + };
  203 +
  204 + return new Value(value);
  205 +
  206 + }
  207 +
  208 +
  209 + }
  210 +
  211 +
  212 +
... ...
client/src/core/session.cc
... ... @@ -401,6 +401,9 @@
401 401  
402 402 }
403 403  
  404 + Property * Session::getProperty(const char *name) const {
  405 + throw std::system_error(ENOTSUP, std::system_category());
  406 + }
404 407  
405 408 }
406 409  
... ...
client/src/host/properties.cc 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @file
  32 + *
  33 + * @brief
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include "private.h"
  40 +
  41 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  42 +
  43 +TN3270::Property * TN3270::Host::operator[](const char *name) const {
  44 +
  45 + if(!this->session)
  46 + throw std::system_error(ENODATA, std::system_category());
  47 +
  48 + return this->session->getProperty(name);
  49 +
  50 +}
... ...
client/src/include/lib3270/ipc.h
... ... @@ -241,6 +241,58 @@
241 241 KYBD_UNLOCK, ///< @brief Unlock the keyboard if it was locked by operator error.
242 242 };
243 243  
  244 + /// @brief Dynamic Data type
  245 + class TN3270_PUBLIC Property {
  246 + public:
  247 +
  248 + /// @brief IPC Data type.
  249 + enum Type : uint8_t {
  250 + String = 's',
  251 + Boolean = 'b',
  252 + Uchar = 'y',
  253 + Int16 = 'n',
  254 + Uint16 = 'q',
  255 + Int32 = 'i',
  256 + Int32x = 'h',
  257 + Uint32 = 'u',
  258 + Int64 = 'x',
  259 + Uint64 = 't'
  260 + };
  261 +
  262 + private:
  263 + Type type;
  264 +
  265 + protected:
  266 + Property(Type type);
  267 +
  268 + public:
  269 + inline bool operator==(Type type) const noexcept {
  270 + return this->type == type;
  271 + }
  272 +
  273 + static Property * create(const char *str);
  274 + static Property * create(const std::string &str);
  275 + static Property * create(const int value);
  276 + static Property * create(const unsigned int value);
  277 + static Property * create(const bool value);
  278 +
  279 + inline Type getType() const {
  280 + return this->type;
  281 + }
  282 +
  283 + inline operator Type() const {
  284 + return this->type;
  285 + }
  286 +
  287 + virtual std::string toString() const;
  288 + virtual int32_t toInt32() const;
  289 + virtual uint32_t toUint32() const;
  290 + virtual bool toBool() const;
  291 +
  292 + virtual ~Property();
  293 +
  294 + };
  295 +
244 296 /// @brief TN3270 Session.
245 297 class TN3270_PUBLIC Session {
246 298 protected:
... ... @@ -351,6 +403,7 @@
351 403 LIB3270_KEYBOARD_LOCK_STATE input(const std::string &str, const char control_char = '@');
352 404  
353 405 // Properties.
  406 + virtual Property * getProperty(const char *name) const;
354 407 virtual void getProperty(const char *name, int &value) const = 0;
355 408 virtual void getProperty(const char *name, unsigned int &value) const = 0;
356 409 virtual void getProperty(const char *name, std::string &value) const = 0;
... ... @@ -582,6 +635,7 @@
582 635  
583 636  
584 637 // Get properties
  638 + Property * operator[](const char *name) const;
585 639  
586 640 /// @brief Get lib3270 version.
587 641 inline std::string getVersion() const {
... ...
client/src/session/local/private.h
... ... @@ -113,6 +113,7 @@
113 113 SSLState getSSLState() const override;
114 114  
115 115 // Properties.
  116 + Property * getProperty(const char *name) const override;
116 117 void getProperty(const char *name, int &value) const override;
117 118 void getProperty(const char *name, unsigned int &value) const override;
118 119 void getProperty(const char *name, std::string &value) const override;
... ...
client/src/session/local/properties.cc
... ... @@ -37,6 +37,7 @@
37 37 */
38 38  
39 39 #include "private.h"
  40 + #include <lib3270/ipc.h>
40 41 #include <lib3270/properties.h>
41 42 #include <lib3270/toggle.h>
42 43 #include <cstring>
... ... @@ -45,6 +46,93 @@
45 46  
46 47 namespace TN3270 {
47 48  
  49 + Property * Local::Session::getProperty(const char *name) const {
  50 +
  51 + std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync);
  52 +
  53 + // Check for integer properties.
  54 + {
  55 + const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list();
  56 + for(size_t ix = 0; intprop[ix].name; ix++) {
  57 +
  58 + if(!strcasecmp(name,intprop[ix].name)) {
  59 +
  60 + errno = 0;
  61 + int value = intprop[ix].get(hSession);
  62 +
  63 + if(errno != 0) {
  64 + throw std::system_error(errno, std::system_category());
  65 + }
  66 +
  67 + return TN3270::Property::create(value);
  68 +
  69 + }
  70 +
  71 + }
  72 + }
  73 +
  74 + // Check for unsigned int properties
  75 + {
  76 + const LIB3270_UINT_PROPERTY * intprop = lib3270_get_unsigned_properties_list();
  77 + for(size_t ix = 0; intprop[ix].name; ix++) {
  78 +
  79 + if(!strcasecmp(name,intprop[ix].name)) {
  80 +
  81 + errno = 0;
  82 + unsigned int value = intprop[ix].get(hSession);
  83 +
  84 + if(errno != 0) {
  85 + throw std::system_error(errno, std::system_category());
  86 + }
  87 +
  88 + return Property::create(value);
  89 +
  90 + }
  91 +
  92 + }
  93 +
  94 + }
  95 +
  96 + // Check for string properties
  97 + {
  98 + const LIB3270_STRING_PROPERTY * strprop = lib3270_get_string_properties_list();
  99 +
  100 + for(size_t ix = 0; strprop[ix].name; ix++) {
  101 +
  102 + if(!strcasecmp(name,strprop[ix].name)) {
  103 +
  104 + // Found it!
  105 + const char * str = strprop[ix].get(hSession);
  106 +
  107 + if(str) {
  108 + return Property::create(str);
  109 + }
  110 +
  111 + throw std::system_error(errno, std::system_category());
  112 +
  113 + }
  114 +
  115 + }
  116 +
  117 + }
  118 +
  119 + // Check for boolean properties
  120 + {
  121 + LIB3270_TOGGLE toggle = lib3270_get_toggle_id(name);
  122 + if(toggle != (LIB3270_TOGGLE) -1) {
  123 +
  124 + // Is a Tn3270 toggle, get it!
  125 + return Property::create((bool) lib3270_get_toggle(hSession,toggle));
  126 +
  127 + }
  128 +
  129 + }
  130 +
  131 + // Not found!
  132 + throw std::system_error(ENOENT, std::system_category());
  133 +
  134 + }
  135 +
48 136 void Local::Session::getProperty(const char *name, int &value) const {
49 137  
50 138 const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list();
... ...
client/src/testprogram/testprogram.cc
... ... @@ -92,6 +92,10 @@
92 92  
93 93 try {
94 94  
  95 + auto version = host["version"];
  96 + cout << "Property[version]: " << version->toString() << endl;
  97 + delete version;
  98 +
95 99 cout
96 100 << "Version: " << host.getVersion()
97 101 << "\tRevision: " << host.getRevision()
... ... @@ -136,9 +140,28 @@
136 140  
137 141 }
138 142  
  143 + TN3270::Property * chk() {
  144 +
  145 + class Test : public TN3270::Property {
  146 + private:
  147 + int val;
  148 +
  149 + public:
  150 + Test(int value) : TN3270::Property(TN3270::Property::Uint32) {
  151 + val = value;
  152 + }
  153 +
  154 + virtual ~Test() { }
  155 + };
  156 +
  157 + return new Test{10};
  158 +
  159 + }
  160 +
139 161 int main(int argc, char **argv) {
140 162  
141   - const char * session = LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME) ":a";
  163 +
  164 + const char * session = ""; // ":a";
142 165  
143 166 #pragma GCC diagnostic push
144 167 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
... ...