Commit e74f305b5d49d5e329db67eebe985476777b9593
1 parent
5e054e6e
Exists in
master
and in
1 other branch
Adding dynamic typed properties on local session object.
Showing
8 changed files
with
434 additions
and
1 deletions
Show diff stats
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" /> | ... | ... |
| ... | ... | @@ -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
| ... | ... | @@ -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" | ... | ... |