diff --git a/client/ipcclient.cbp b/client/ipcclient.cbp index bca4de9..d343ed1 100644 --- a/client/ipcclient.cbp +++ b/client/ipcclient.cbp @@ -45,6 +45,7 @@ + @@ -55,6 +56,7 @@ + diff --git a/client/src/core/property.cc b/client/src/core/property.cc new file mode 100644 index 0000000..e4b39ad --- /dev/null +++ b/client/src/core/property.cc @@ -0,0 +1,212 @@ +/* + * "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 src/core/property.cc + * + * @brief Implements type independent property object. + * + * @author perry.werneck@gmail.com + * + */ + + #include + #include + #include + #include + + using std::runtime_error; + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + + namespace TN3270 { + + class StringProperty : public Property, std::string { + public: + StringProperty(const char *str) : Property(Property::String), std::string(str) { + } + + StringProperty(const std::string &str) : Property(Property::String), std::string(str) { + } + + std::string toString() const override { + return std::string(this->c_str()); + } + + int32_t toInt32() const override { + return (int32_t) atoi(this->c_str()); + } + + uint32_t toUint32() const override { + return (uint32_t) atoi(this->c_str()); + } + + bool toBool() const override { + return atoi(this->c_str()) != 0; + } + + }; + + Property::Property(Property::Type type) { + this->type = type; + + } + + Property::~Property() { + } + + std::string Property::toString() const { + throw runtime_error("The value can't be converted to string"); + } + + int32_t Property::toInt32() const { + throw runtime_error("The value can't be converted to a signed integer"); + } + + uint32_t Property::toUint32() const { + throw runtime_error("The value can't be converted to an unsigned integer"); + } + + bool Property::toBool() const { + throw runtime_error("The value can't be converted to boolean"); + } + + + Property * Property::create(const char *str) { + return new StringProperty(str); + } + + Property * Property::create(const std::string &str) { + return new StringProperty(str); + } + + Property * Property::create(const int value) { + + class Value : public Property { + private: + int32_t value; + + public: + Value(int value) : Property(Property::Int32) { + this->value = (int32_t) value; + } + + std::string toString() const override { + return std::to_string(value); + } + + int32_t toInt32() const override { + return (int32_t) value; + } + + uint32_t toUint32() const override { + return (uint32_t) value; + } + + bool toBool() const override { + return value != 0; + } + + }; + + return new Value(value); + + } + + Property * Property::create(const unsigned int value) { + + class Value : public Property { + private: + uint32_t value; + + public: + Value(unsigned int value) : Property(Property::Uint32) { + this->value = (uint32_t) value; + } + + std::string toString() const override { + return std::to_string(value); + } + + int32_t toInt32() const override { + return (int32_t) value; + } + + uint32_t toUint32() const override { + return (uint32_t) value; + } + + bool toBool() const override { + return value != 0; + } + + }; + + return new Value(value); + + } + + Property * Property::create(const bool value) { + + class Value : public Property { + private: + bool value; + + public: + Value(bool value) : Property(Property::Boolean) { + this->value = value; + } + + std::string toString() const override { + return std::to_string(value); + } + + int32_t toInt32() const override { + return (int32_t) value; + } + + uint32_t toUint32() const override { + return (uint32_t) value; + } + + bool toBool() const override { + return value; + } + + }; + + return new Value(value); + + } + + + } + + + diff --git a/client/src/core/session.cc b/client/src/core/session.cc index a5c1848..c7e3a51 100644 --- a/client/src/core/session.cc +++ b/client/src/core/session.cc @@ -401,6 +401,9 @@ } + Property * Session::getProperty(const char *name) const { + throw std::system_error(ENOTSUP, std::system_category()); + } } diff --git a/client/src/host/properties.cc b/client/src/host/properties.cc new file mode 100644 index 0000000..0fa36ee --- /dev/null +++ b/client/src/host/properties.cc @@ -0,0 +1,50 @@ +/* + * "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" + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + +TN3270::Property * TN3270::Host::operator[](const char *name) const { + + if(!this->session) + throw std::system_error(ENODATA, std::system_category()); + + return this->session->getProperty(name); + +} diff --git a/client/src/include/lib3270/ipc.h b/client/src/include/lib3270/ipc.h index a49bc88..8436094 100644 --- a/client/src/include/lib3270/ipc.h +++ b/client/src/include/lib3270/ipc.h @@ -241,6 +241,58 @@ KYBD_UNLOCK, ///< @brief Unlock the keyboard if it was locked by operator error. }; + /// @brief Dynamic Data type + class TN3270_PUBLIC Property { + public: + + /// @brief IPC Data type. + enum Type : uint8_t { + String = 's', + Boolean = 'b', + Uchar = 'y', + Int16 = 'n', + Uint16 = 'q', + Int32 = 'i', + Int32x = 'h', + Uint32 = 'u', + Int64 = 'x', + Uint64 = 't' + }; + + private: + Type type; + + protected: + Property(Type type); + + public: + inline bool operator==(Type type) const noexcept { + return this->type == type; + } + + static Property * create(const char *str); + static Property * create(const std::string &str); + static Property * create(const int value); + static Property * create(const unsigned int value); + static Property * create(const bool value); + + inline Type getType() const { + return this->type; + } + + inline operator Type() const { + return this->type; + } + + virtual std::string toString() const; + virtual int32_t toInt32() const; + virtual uint32_t toUint32() const; + virtual bool toBool() const; + + virtual ~Property(); + + }; + /// @brief TN3270 Session. class TN3270_PUBLIC Session { protected: @@ -351,6 +403,7 @@ LIB3270_KEYBOARD_LOCK_STATE input(const std::string &str, const char control_char = '@'); // Properties. + virtual Property * getProperty(const char *name) const; virtual void getProperty(const char *name, int &value) const = 0; virtual void getProperty(const char *name, unsigned int &value) const = 0; virtual void getProperty(const char *name, std::string &value) const = 0; @@ -582,6 +635,7 @@ // Get properties + Property * operator[](const char *name) const; /// @brief Get lib3270 version. inline std::string getVersion() const { diff --git a/client/src/session/local/private.h b/client/src/session/local/private.h index 72e6b69..877af64 100644 --- a/client/src/session/local/private.h +++ b/client/src/session/local/private.h @@ -113,6 +113,7 @@ SSLState getSSLState() const override; // Properties. + Property * getProperty(const char *name) const override; void getProperty(const char *name, int &value) const override; void getProperty(const char *name, unsigned int &value) const override; void getProperty(const char *name, std::string &value) const override; diff --git a/client/src/session/local/properties.cc b/client/src/session/local/properties.cc index 8916284..aa4cdeb 100644 --- a/client/src/session/local/properties.cc +++ b/client/src/session/local/properties.cc @@ -37,6 +37,7 @@ */ #include "private.h" + #include #include #include #include @@ -45,6 +46,93 @@ namespace TN3270 { + Property * Local::Session::getProperty(const char *name) const { + + std::lock_guard lock(const_cast(this)->sync); + + // 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)) { + + errno = 0; + int value = intprop[ix].get(hSession); + + if(errno != 0) { + throw std::system_error(errno, std::system_category()); + } + + return TN3270::Property::create(value); + + } + + } + } + + // 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)) { + + errno = 0; + unsigned int value = intprop[ix].get(hSession); + + if(errno != 0) { + throw std::system_error(errno, std::system_category()); + } + + return Property::create(value); + + } + + } + + } + + // 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)) { + + // Found it! + const char * str = strprop[ix].get(hSession); + + if(str) { + return Property::create(str); + } + + throw std::system_error(errno, std::system_category()); + + } + + } + + } + + // Check for boolean properties + { + LIB3270_TOGGLE toggle = lib3270_get_toggle_id(name); + if(toggle != (LIB3270_TOGGLE) -1) { + + // Is a Tn3270 toggle, get it! + return Property::create((bool) lib3270_get_toggle(hSession,toggle)); + + } + + } + + // Not found! + throw std::system_error(ENOENT, std::system_category()); + + } + void Local::Session::getProperty(const char *name, int &value) const { const LIB3270_INT_PROPERTY * intprop = lib3270_get_int_properties_list(); diff --git a/client/src/testprogram/testprogram.cc b/client/src/testprogram/testprogram.cc index ee108f2..977c208 100644 --- a/client/src/testprogram/testprogram.cc +++ b/client/src/testprogram/testprogram.cc @@ -92,6 +92,10 @@ try { + auto version = host["version"]; + cout << "Property[version]: " << version->toString() << endl; + delete version; + cout << "Version: " << host.getVersion() << "\tRevision: " << host.getRevision() @@ -136,9 +140,28 @@ } + TN3270::Property * chk() { + + class Test : public TN3270::Property { + private: + int val; + + public: + Test(int value) : TN3270::Property(TN3270::Property::Uint32) { + val = value; + } + + virtual ~Test() { } + }; + + return new Test{10}; + + } + int main(int argc, char **argv) { - const char * session = LIB3270_STRINGIZE_VALUE_OF(PRODUCT_NAME) ":a"; + + const char * session = ""; // ":a"; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -- libgit2 0.21.2