diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 7a74a9cc0..102a4a299 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -50,3 +50,4 @@ Jeff Adams Martin Osborne Björn Schramke Francis Andre +Kacper Piwiński diff --git a/Crypto/include/Poco/Crypto/CipherKey.h b/Crypto/include/Poco/Crypto/CipherKey.h index 02042ec88..358556468 100644 --- a/Crypto/include/Poco/Crypto/CipherKey.h +++ b/Crypto/include/Poco/Crypto/CipherKey.h @@ -38,7 +38,7 @@ class Crypto_API CipherKey /// file. /// /// To create a key using a human-readable password - /// string, use the following code. We create a AES Cipher and + /// string, use the following code. We create a AES Cipher and /// use a salt value to make the key more robust: /// /// std::string password = "secret"; @@ -68,16 +68,16 @@ public: /// an iteration count of at least 1000. }; - CipherKey(const std::string& name, - const std::string& passphrase, + CipherKey(const std::string& name, + const std::string& passphrase, const std::string& salt = "", int iterationCount = DEFAULT_ITERATION_COUNT, const std::string& digest = "md5"); /// Creates a new CipherKeyImpl object using the given /// cipher name, passphrase, salt value, iteration count and digest. - CipherKey(const std::string& name, - const ByteVec& key, + CipherKey(const std::string& name, + const ByteVec& key, const ByteVec& iv); /// Creates a new CipherKeyImpl object using the given cipher /// name, key and initialization vector (IV). @@ -87,12 +87,24 @@ public: /// a custom IV size. CipherKey(const std::string& name); - /// Creates a new CipherKeyImpl object. Autoinitializes key and + /// Creates a new CipherKeyImpl object. Autoinitializes key and /// initialization vector. + CipherKey(const CipherKey& other); + /// Copy constructor. + + CipherKey(CipherKey&& other) noexcept; + /// Copy constructor. + ~CipherKey(); /// Destroys the CipherKeyImpl. + CipherKey& operator = (const CipherKey& other); + /// Assignment. + + CipherKey& operator = (CipherKey&& other) noexcept; + /// Move assignment. + const std::string& name() const; /// Returns the name of the Cipher. @@ -107,7 +119,7 @@ public: Mode mode() const; /// Returns the Cipher's mode of operation. - + const ByteVec& getKey() const; /// Returns the key for the Cipher. diff --git a/Crypto/include/Poco/Crypto/ECKey.h b/Crypto/include/Poco/Crypto/ECKey.h index 14f2ac0a1..e2abb928f 100644 --- a/Crypto/include/Poco/Crypto/ECKey.h +++ b/Crypto/include/Poco/Crypto/ECKey.h @@ -32,7 +32,7 @@ class X509Certificate; class PKCS12Container; -class Crypto_API ECKey : public KeyPair +class Crypto_API ECKey: public KeyPair /// This class stores an EC key pair, consisting /// of private and public key. Storage of the private /// key is optional. @@ -73,9 +73,21 @@ public: /// If a private key is specified, you don't need to specify a public key file. /// OpenSSL will auto-create the public key from the private key. + ECKey(const ECKey& key); + /// Creates the ECKey by copying another one. + + ECKey(ECKey&& key) noexcept; + /// Creates the ECKey by moving another one. + ~ECKey(); /// Destroys the ECKey. + ECKey& operator = (const ECKey& other); + /// Assignment. + + ECKey& operator = (ECKey&& other) noexcept; + /// Move assignment. + ECKeyImpl::Ptr impl() const; /// Returns the impl object. @@ -97,9 +109,6 @@ public: static bool hasCurve(const std::string& name); /// Returns true if the named curve is found, /// false otherwise. - -private: - ECKeyImpl::Ptr _pImpl; }; @@ -108,7 +117,7 @@ private: // inline ECKeyImpl::Ptr ECKey::impl() const { - return _pImpl; + return KeyPair::impl().cast(); } diff --git a/Crypto/include/Poco/Crypto/KeyPair.h b/Crypto/include/Poco/Crypto/KeyPair.h index b9a705f8f..6f14a5f8e 100644 --- a/Crypto/include/Poco/Crypto/KeyPair.h +++ b/Crypto/include/Poco/Crypto/KeyPair.h @@ -1,7 +1,6 @@ // // KeyPair.h // -// // Library: Crypto // Package: CryptoCore // Module: KeyPair @@ -48,6 +47,18 @@ public: explicit KeyPair(KeyPairImpl::Ptr pKeyPairImpl = 0); /// Extracts the RSA public key from the given certificate. + KeyPair(const KeyPair& other); + /// Copy constructor. + + KeyPair(KeyPair&& other) noexcept; + /// Move constructor. + + KeyPair& operator = (const KeyPair& other); + /// Assignment. + + KeyPair& operator = (KeyPair&& other) noexcept; + /// Move assignment. + virtual ~KeyPair(); /// Destroys the KeyPair. @@ -57,7 +68,7 @@ public: virtual void save(const std::string& publicKeyPairFile, const std::string& privateKeyPairFile = "", const std::string& privateKeyPairPassphrase = "") const; - /// Exports the public and private keys to the given files. + /// Exports the public and private keys to the given files. /// /// If an empty filename is specified, the corresponding key /// is not exported. @@ -78,7 +89,7 @@ public: Type type() const; /// Returns key pair type - + private: KeyPairImpl::Ptr _pImpl; }; @@ -87,7 +98,6 @@ private: // // inlines // - inline int KeyPair::size() const { return _pImpl->size(); @@ -115,6 +125,7 @@ inline const std::string& KeyPair::name() const return _pImpl->name(); } + inline KeyPairImpl::Ptr KeyPair::impl() const { return _pImpl; diff --git a/Crypto/include/Poco/Crypto/RSAKey.h b/Crypto/include/Poco/Crypto/RSAKey.h index ad9163ed4..51c97432f 100644 --- a/Crypto/include/Poco/Crypto/RSAKey.h +++ b/Crypto/include/Poco/Crypto/RSAKey.h @@ -31,7 +31,7 @@ class X509Certificate; class PKCS12Container; -class Crypto_API RSAKey : public KeyPair +class Crypto_API RSAKey: public KeyPair /// This class stores an RSA key pair, consisting /// of private and public key. Storage of the private /// key is optional. @@ -90,9 +90,21 @@ public: /// If a private key is specified, you don't need to specify a public key file. /// OpenSSL will auto-create the public key from the private key. + RSAKey(const RSAKey& other); + /// Copy constructor. + + RSAKey(RSAKey&& other) noexcept; + /// Move constructor. + ~RSAKey(); /// Destroys the RSAKey. + RSAKey& operator = (const RSAKey& other); + /// Assignment. + + RSAKey& operator = (RSAKey&& other) noexcept; + /// Move assignment. + RSAKeyImpl::ByteVec modulus() const; /// Returns the RSA modulus. @@ -104,9 +116,6 @@ public: RSAKeyImpl::Ptr impl() const; /// Returns the impl object. - -private: - RSAKeyImpl::Ptr _pImpl; }; @@ -115,7 +124,7 @@ private: // inline RSAKeyImpl::Ptr RSAKey::impl() const { - return _pImpl; + return KeyPair::impl().cast(); } diff --git a/Crypto/src/CipherKey.cpp b/Crypto/src/CipherKey.cpp index 275edd1c8..41217422b 100644 --- a/Crypto/src/CipherKey.cpp +++ b/Crypto/src/CipherKey.cpp @@ -41,9 +41,38 @@ CipherKey::CipherKey(const std::string& name): } +CipherKey::CipherKey(const CipherKey& other): + _pImpl(other._pImpl) +{ +} + + +CipherKey::CipherKey(CipherKey&& other) noexcept: + _pImpl(std::move(other._pImpl)) +{ +} + + CipherKey::~CipherKey() { } +CipherKey& CipherKey::operator = (const CipherKey& other) +{ + if (&other != this) + { + _pImpl = other._pImpl; + } + return *this; +} + + +CipherKey& CipherKey::operator = (CipherKey&& other) noexcept +{ + _pImpl = std::move(other._pImpl); + return *this; +} + + } } // namespace Poco::Crypto diff --git a/Crypto/src/ECKey.cpp b/Crypto/src/ECKey.cpp index 56b866377..105a7d3c3 100644 --- a/Crypto/src/ECKey.cpp +++ b/Crypto/src/ECKey.cpp @@ -22,47 +22,49 @@ namespace Crypto { ECKey::ECKey(const EVPPKey& key): - KeyPair(new ECKeyImpl(key)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new ECKeyImpl(key)) { } ECKey::ECKey(const X509Certificate& cert): - KeyPair(new ECKeyImpl(cert)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new ECKeyImpl(cert)) { } ECKey::ECKey(const PKCS12Container& cont): - KeyPair(new ECKeyImpl(cont)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new ECKeyImpl(cont)) { } ECKey::ECKey(const std::string& eccGroup): - KeyPair(new ECKeyImpl(OBJ_txt2nid(eccGroup.c_str()))), - _pImpl(KeyPair::impl().cast()) + KeyPair(new ECKeyImpl(OBJ_txt2nid(eccGroup.c_str()))) { } -ECKey::ECKey(const std::string& publicKeyFile, - const std::string& privateKeyFile, - const std::string& privateKeyPassphrase): - KeyPair(new ECKeyImpl(publicKeyFile, privateKeyFile, privateKeyPassphrase)), - _pImpl(KeyPair::impl().cast()) +ECKey::ECKey(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase): + KeyPair(new ECKeyImpl(publicKeyFile, privateKeyFile, privateKeyPassphrase)) { } -ECKey::ECKey(std::istream* pPublicKeyStream, - std::istream* pPrivateKeyStream, - const std::string& privateKeyPassphrase): - KeyPair(new ECKeyImpl(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase)), - _pImpl(KeyPair::impl().cast()) +ECKey::ECKey(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase): + KeyPair(new ECKeyImpl(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase)) +{ +} + + +ECKey::ECKey(const ECKey& other): + KeyPair(other) +{ +} + + +ECKey::ECKey(ECKey&& other) noexcept: + KeyPair(std::move(other)) { } @@ -72,4 +74,18 @@ ECKey::~ECKey() } +ECKey& ECKey::operator = (const ECKey& other) +{ + KeyPair::operator = (other); + return *this; +} + + +ECKey& ECKey::operator = (ECKey&& other) noexcept +{ + KeyPair::operator = (std::move(other)); + return *this; +} + + } } // namespace Poco::Crypto diff --git a/Crypto/src/EVPPKey.cpp b/Crypto/src/EVPPKey.cpp index d6d9e1072..832add751 100644 --- a/Crypto/src/EVPPKey.cpp +++ b/Crypto/src/EVPPKey.cpp @@ -89,11 +89,10 @@ EVPPKey::EVPPKey(const EVPPKey& other) } -EVPPKey::EVPPKey(EVPPKey&& other) noexcept: +EVPPKey::EVPPKey(EVPPKey&& other) noexcept: _pEVPPKey(other._pEVPPKey) { other._pEVPPKey = nullptr; - poco_check_ptr(_pEVPPKey); } @@ -109,7 +108,6 @@ EVPPKey& EVPPKey::operator = (EVPPKey&& other) noexcept { _pEVPPKey = other._pEVPPKey; other._pEVPPKey = nullptr; - poco_check_ptr(_pEVPPKey); return *this; } diff --git a/Crypto/src/KeyPair.cpp b/Crypto/src/KeyPair.cpp index 1c650806b..25dc4f927 100644 --- a/Crypto/src/KeyPair.cpp +++ b/Crypto/src/KeyPair.cpp @@ -1,7 +1,6 @@ // // KeyPair.cpp // -// // Library: Crypto // Package: CryptoCore // Module: KeyPair @@ -21,7 +20,20 @@ namespace Poco { namespace Crypto { -KeyPair::KeyPair(KeyPairImpl::Ptr pKeyPairImpl): _pImpl(pKeyPairImpl) +KeyPair::KeyPair(KeyPairImpl::Ptr pKeyPairImpl): + _pImpl(pKeyPairImpl) +{ +} + + +KeyPair::KeyPair(const KeyPair& other): + _pImpl(other._pImpl) +{ +} + + +KeyPair::KeyPair(KeyPair&& other) noexcept: + _pImpl(std::move(other._pImpl)) { } @@ -31,4 +43,21 @@ KeyPair::~KeyPair() } +KeyPair& KeyPair::operator = (const KeyPair& other) +{ + if (&other != this) + { + _pImpl = other._pImpl; + } + return *this; +} + + +KeyPair& KeyPair::operator = (KeyPair&& other) noexcept +{ + _pImpl = std::move(other._pImpl); + return *this; +} + + } } // namespace Poco::Crypto diff --git a/Crypto/src/PKCS12Container.cpp b/Crypto/src/PKCS12Container.cpp index a99e7dfaf..9675d9af4 100644 --- a/Crypto/src/PKCS12Container.cpp +++ b/Crypto/src/PKCS12Container.cpp @@ -73,6 +73,17 @@ PKCS12Container::PKCS12Container(const PKCS12Container& other): } +PKCS12Container::PKCS12Container(PKCS12Container&& other) noexcept: + _pKey(other._pKey), + _pX509Cert(std::move(other._pX509Cert)), + _caCertList(std::move(other._caCertList)), + _caCertNames(std::move(other._caCertNames)), + _pkcsFriendlyName(std::move(other._pkcsFriendlyName)) +{ + other._pKey = nullptr; +} + + PKCS12Container& PKCS12Container::operator = (const PKCS12Container& other) { if (&other != this) @@ -88,17 +99,6 @@ PKCS12Container& PKCS12Container::operator = (const PKCS12Container& other) } -PKCS12Container::PKCS12Container(PKCS12Container&& other) noexcept: - _pKey(other._pKey), - _pX509Cert(std::move(other._pX509Cert)), - _caCertList(std::move(other._caCertList)), - _caCertNames(std::move(other._caCertNames)), - _pkcsFriendlyName(std::move(other._pkcsFriendlyName)) -{ - other._pKey = nullptr; -} - - PKCS12Container& PKCS12Container::operator = (PKCS12Container&& other) noexcept { if (_pKey) EVP_PKEY_free(_pKey); diff --git a/Crypto/src/RSAKey.cpp b/Crypto/src/RSAKey.cpp index b81a0281b..ef53be9b2 100644 --- a/Crypto/src/RSAKey.cpp +++ b/Crypto/src/RSAKey.cpp @@ -21,43 +21,49 @@ namespace Crypto { RSAKey::RSAKey(const EVPPKey& key): - KeyPair(new RSAKeyImpl(key)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new RSAKeyImpl(key)) { } RSAKey::RSAKey(const X509Certificate& cert): - KeyPair(new RSAKeyImpl(cert)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new RSAKeyImpl(cert)) { } RSAKey::RSAKey(const PKCS12Container& cont): - KeyPair(new RSAKeyImpl(cont)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new RSAKeyImpl(cont)) { } RSAKey::RSAKey(KeyLength keyLength, Exponent exp): - KeyPair(new RSAKeyImpl(keyLength, (exp == EXP_LARGE) ? RSA_F4 : RSA_3)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new RSAKeyImpl(keyLength, (exp == EXP_LARGE) ? RSA_F4 : RSA_3)) { } RSAKey::RSAKey(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase): - KeyPair(new RSAKeyImpl(publicKeyFile, privateKeyFile, privateKeyPassphrase)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new RSAKeyImpl(publicKeyFile, privateKeyFile, privateKeyPassphrase)) { } RSAKey::RSAKey(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase): - KeyPair(new RSAKeyImpl(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase)), - _pImpl(KeyPair::impl().cast()) + KeyPair(new RSAKeyImpl(pPublicKeyStream, pPrivateKeyStream, privateKeyPassphrase)) +{ +} + + +RSAKey::RSAKey(const RSAKey& other): + KeyPair(other) +{ +} + + +RSAKey::RSAKey(RSAKey&& other) noexcept: + KeyPair(std::move(other)) { } @@ -66,22 +72,37 @@ RSAKey::~RSAKey() { } + +RSAKey& RSAKey::operator = (const RSAKey& other) +{ + KeyPair::operator = (other); + return *this; +} + + +RSAKey& RSAKey::operator = (RSAKey&& other) noexcept +{ + KeyPair::operator = (std::move(other)); + return *this; +} + + RSAKeyImpl::ByteVec RSAKey::modulus() const { - return _pImpl->modulus(); + return impl()->modulus(); } RSAKeyImpl::ByteVec RSAKey::encryptionExponent() const { - return _pImpl->encryptionExponent(); + return impl()->encryptionExponent(); } RSAKeyImpl::ByteVec RSAKey::decryptionExponent() const { - return _pImpl->decryptionExponent(); + return impl()->decryptionExponent(); } -} } // namespace Poco::Crypto \ No newline at end of file +} } // namespace Poco::Crypto diff --git a/Crypto/src/X509Certificate.cpp b/Crypto/src/X509Certificate.cpp index 43e8469d4..53fc573be 100644 --- a/Crypto/src/X509Certificate.cpp +++ b/Crypto/src/X509Certificate.cpp @@ -29,12 +29,14 @@ #include #include + #if OPENSSL_VERSION_NUMBER < 0x10100000L #define ASN1_STRING_get0_data ASN1_STRING_data #define X509_get0_notBefore X509_get_notBefore #define X509_get0_notAfter X509_get_notAfter #endif + namespace Poco { namespace Crypto { @@ -113,6 +115,7 @@ X509Certificate& X509Certificate::operator = (X509Certificate&& cert) noexcept _issuerName = std::move(cert._issuerName); _subjectName = std::move(cert._subjectName); _serialNumber = std::move(cert._serialNumber); + if (_pCert) X509_free(_pCert); _pCert = cert._pCert; cert._pCert = nullptr; return *this; } @@ -302,7 +305,18 @@ Poco::DateTime X509Certificate::validFrom() const const ASN1_TIME* certTime = X509_get0_notBefore(_pCert); std::string dateTime(reinterpret_cast(certTime->data)); int tzd; - return DateTimeParser::parse("%y%m%d%H%M%S", dateTime, tzd); + if (certTime->type == V_ASN1_UTCTIME) + { + return DateTimeParser::parse("%y%m%d%H%M%S", dateTime, tzd); + } + else if (certTime->type == V_ASN1_GENERALIZEDTIME) + { + return DateTimeParser::parse("%Y%m%d%H%M%S", dateTime, tzd); + } + else + { + throw NotImplementedException("Unsupported date/time format in notBefore"); + } } @@ -311,7 +325,18 @@ Poco::DateTime X509Certificate::expiresOn() const const ASN1_TIME* certTime = X509_get0_notAfter(_pCert); std::string dateTime(reinterpret_cast(certTime->data)); int tzd; - return DateTimeParser::parse("%y%m%d%H%M%S", dateTime, tzd); + if (certTime->type == V_ASN1_UTCTIME) + { + return DateTimeParser::parse("%y%m%d%H%M%S", dateTime, tzd); + } + else if (certTime->type == V_ASN1_GENERALIZEDTIME) + { + return DateTimeParser::parse("%Y%m%d%H%M%S", dateTime, tzd); + } + else + { + throw NotImplementedException("Unsupported date/time format in notBefore"); + } } diff --git a/Data/SQLite/testsuite/src/SQLiteTest.cpp b/Data/SQLite/testsuite/src/SQLiteTest.cpp index a874ff3c9..341ce87fe 100755 --- a/Data/SQLite/testsuite/src/SQLiteTest.cpp +++ b/Data/SQLite/testsuite/src/SQLiteTest.cpp @@ -2482,7 +2482,7 @@ void SQLiteTest::testSQLLogger() { AutoPtr pChannel = new SQLChannel(Poco::Data::SQLite::Connector::KEY, "dummy.db", "TestSQLChannel"); Logger& root = Logger::root(); - root.setChannel(pChannel.get()); + root.setChannel(pChannel); root.setLevel(Message::PRIO_INFORMATION); root.information("Informational message"); diff --git a/Data/src/MetaColumn.cpp b/Data/src/MetaColumn.cpp index 940a10a03..d333164fe 100644 --- a/Data/src/MetaColumn.cpp +++ b/Data/src/MetaColumn.cpp @@ -34,7 +34,7 @@ MetaColumn::MetaColumn(std::size_t position, ColumnDataType type, std::size_t length, std::size_t precision, - bool nullable): + bool nullable): _name(name), _length(length), _precision(precision), @@ -91,6 +91,7 @@ MetaColumn& MetaColumn::operator = (MetaColumn&& other) noexcept return *this; } + void MetaColumn::swap(MetaColumn& other) { std::swap(_name, other._name); diff --git a/Data/src/Session.cpp b/Data/src/Session.cpp index 0bd9f90d1..985acb255 100644 --- a/Data/src/Session.cpp +++ b/Data/src/Session.cpp @@ -48,16 +48,16 @@ Session::Session(const std::string& connection, } -Session::Session(const Session& other): +Session::Session(const Session& other): _pImpl(other._pImpl), - _statementCreator(other._pImpl) + _statementCreator(other._statementCreator) { } -Session::Session(Session&& other) noexcept: +Session::Session(Session&& other) noexcept: _pImpl(std::move(other._pImpl)), - _statementCreator(std::move(other._pImpl)) + _statementCreator(std::move(other._statementCreator)) { } diff --git a/Foundation/include/Poco/AutoPtr.h b/Foundation/include/Poco/AutoPtr.h index 4db70dbe5..fedf5e1a2 100644 --- a/Foundation/include/Poco/AutoPtr.h +++ b/Foundation/include/Poco/AutoPtr.h @@ -47,7 +47,7 @@ class AutoPtr /// AutoPtr works in the following way: /// If an AutoPtr is assigned an ordinary pointer to /// an object (via the constructor or the assignment operator), - /// it takes ownership of the object and the object's reference + /// it takes ownership of the object and the object's reference /// count remains unchanged. /// If the AutoPtr is assigned another AutoPtr, the /// object's reference count is incremented by one by @@ -84,7 +84,7 @@ public: ptr._ptr = nullptr; } - template + template AutoPtr(const AutoPtr& ptr): _ptr(const_cast(ptr.get())) { if (_ptr) _ptr->duplicate(); @@ -94,7 +94,7 @@ public: { if (_ptr) _ptr->release(); } - + AutoPtr& assign(C* ptr) { if (_ptr != ptr) @@ -115,7 +115,7 @@ public: } return *this; } - + AutoPtr& assign(const AutoPtr& ptr) { if (&ptr != this) @@ -126,8 +126,8 @@ public: } return *this; } - - template + + template AutoPtr& assign(const AutoPtr& ptr) { if (ptr.get() != _ptr) @@ -182,12 +182,12 @@ public: AutoPtr& operator = (AutoPtr&& ptr) noexcept { if (_ptr) _ptr->release(); - _ptr = std::move(ptr._ptr); + _ptr = ptr._ptr; ptr._ptr = nullptr; return *this; } - - template + + template AutoPtr& operator = (const AutoPtr& ptr) { return assign(ptr); @@ -197,8 +197,8 @@ public: { std::swap(_ptr, ptr._ptr); } - - template + + template AutoPtr cast() const /// Casts the AutoPtr via a dynamic cast to the given type. /// Returns an AutoPtr containing NULL if the cast fails. @@ -211,7 +211,7 @@ public: return AutoPtr(pOther, true); } - template + template AutoPtr unsafeCast() const /// Casts the AutoPtr via a static cast to the given type. /// Example: (assume class Sub: public Super) @@ -269,12 +269,12 @@ public: { return _ptr; } - + operator const C* () const { return _ptr; } - + bool operator ! () const { return _ptr == nullptr; @@ -284,7 +284,7 @@ public: { return _ptr == nullptr; } - + C* duplicate() { if (_ptr) _ptr->duplicate(); diff --git a/Foundation/include/Poco/Config.h b/Foundation/include/Poco/Config.h index dc23f218a..fb3cca8f4 100644 --- a/Foundation/include/Poco/Config.h +++ b/Foundation/include/Poco/Config.h @@ -96,6 +96,9 @@ // on platforms with no inotify. // #define POCO_NO_INOTIFY +// Define to force the use of PollingDirectoryWatcher +// #define POCO_DW_FORCE_POLLING + // Following are options to remove certain features // to reduce library/executable size for smaller diff --git a/Foundation/include/Poco/Message.h b/Foundation/include/Poco/Message.h index 7c42b748c..9779f0de7 100644 --- a/Foundation/include/Poco/Message.h +++ b/Foundation/include/Poco/Message.h @@ -54,109 +54,109 @@ public: PRIO_DEBUG, /// A debugging message. PRIO_TRACE /// A tracing message. This is the lowest priority. }; - + Message(); /// Creates an empty Message. /// The thread and process ids are set. - + Message(const std::string& source, const std::string& text, Priority prio); /// Creates a Message with the given source, text and priority. /// The thread and process ids are set. Message(const std::string& source, const std::string& text, Priority prio, const char* file, int line); /// Creates a Message with the given source, text, priority, - /// source file path and line. + /// source file path and line. /// - /// The source file path must be a + /// The source file path must be a /// static string with a lifetime that's at least the lifetime /// of the message object (the string is not copied internally). - /// Usually, this will be the path string obtained from the + /// Usually, this will be the path string obtained from the /// __FILE__ macro. /// /// The thread and process ids are set. - + Message(const Message& msg); /// Creates a Message by copying another one. - - Message(Message&& msg); + + Message(Message&& msg) noexcept; /// Creates a Message by copying another one. Message(const Message& msg, const std::string& text); /// Creates a Message by copying all but the text from another message. - + ~Message(); /// Destroys the Message. - + Message& operator = (const Message& msg); /// Assignment operator. - - Message& operator = (Message&& msg); + + Message& operator = (Message&& msg) noexcept; /// Assignment operator. void swap(Message& msg); - /// Swaps the message with another one. - + /// Swaps the message with another one. + void setSource(const std::string& src); /// Sets the source of the message. - + const std::string& getSource() const; /// Returns the source of the message. - + void setText(const std::string& text); /// Sets the text of the message. - + const std::string& getText() const; /// Returns the text of the message. - + void setPriority(Priority prio); /// Sets the priority of the message. - + Priority getPriority() const; /// Returns the priority of the message. - + void setTime(const Timestamp& time); /// Sets the time of the message. - + const Timestamp& getTime() const; /// Returns the time of the message. - + void setThread(const std::string& thread); /// Sets the thread identifier for the message. - + const std::string& getThread() const; /// Returns the thread identifier for the message. void setTid(long pid); /// Sets the numeric thread identifier for the message. - + long getTid() const; /// Returns the numeric thread identifier for the message. - + void setPid(long pid); /// Sets the process identifier for the message. - + long getPid() const; /// Returns the process identifier for the message. - + void setSourceFile(const char* file); /// Sets the source file path of the statement /// generating the log message. /// /// File must be a static string, such as the value of /// the __FILE__ macro. The string is not copied - /// internally for performance reasons. - + /// internally for performance reasons. + const char* getSourceFile() const; /// Returns the source file path of the code creating /// the message. May be 0 if not set. - + void setSourceLine(int line); /// Sets the source file line of the statement /// generating the log message. /// /// This is usually the result of the __LINE__ /// macro. - + int getSourceLine() const; /// Returns the source file line of the statement /// generating the log message. May be 0 @@ -183,7 +183,7 @@ public: /// Returns a const reference to the value of the parameter /// with the given name. Throws a NotFoundException if the /// parameter does not exist. - + std::string& operator [] (const std::string& param); /// Returns a reference to the value of the parameter with the /// given name. This can be used to set the parameter's value. @@ -194,7 +194,7 @@ protected: void init(); typedef std::map StringMap; -private: +private: std::string _source; std::string _text; Priority _prio; diff --git a/Foundation/include/Poco/Nullable.h b/Foundation/include/Poco/Nullable.h index cba9a6c6d..fbae8bf0f 100644 --- a/Foundation/include/Poco/Nullable.h +++ b/Foundation/include/Poco/Nullable.h @@ -123,7 +123,7 @@ public: Nullable& assign(C&& value) /// Assigns a value to the Nullable. { - _value = value; + _value = std::move(value); _isNull = false; return *this; } @@ -152,7 +152,7 @@ public: Nullable& operator = (C&& value) /// Move-assigns a value to the Nullable. { - return assign(value); + return assign(std::move(value)); } Nullable& operator = (const Nullable& other) diff --git a/Foundation/include/Poco/Optional.h b/Foundation/include/Poco/Optional.h index acfff7fc7..6dbc299c6 100644 --- a/Foundation/include/Poco/Optional.h +++ b/Foundation/include/Poco/Optional.h @@ -105,7 +105,7 @@ public: Optional& assign(C&& value) /// Moves a value into the Optional. { - _value = value; + _value = std::move(value); _isSpecified = true; return *this; } @@ -125,7 +125,7 @@ public: Optional& operator = (C&& value) { - return assign(value); + return assign(std::move(value)); } Optional& operator = (const Optional& other) diff --git a/Foundation/include/Poco/Process.h b/Foundation/include/Poco/Process.h index 9557fa031..f84b68ef4 100644 --- a/Foundation/include/Poco/Process.h +++ b/Foundation/include/Poco/Process.h @@ -21,7 +21,7 @@ #include "Poco/Foundation.h" -#if defined(POCO_OS_FAMILY_WINDOWS) +#if defined(POCO_OS_FAMILY_WINDOWS) #if defined(_WIN32_WCE) #include "Process_WINCE.h" #else @@ -66,6 +66,11 @@ public: /// Waits for the process to terminate /// and returns the exit code of the process. + int tryWait() const; + /// Checks that process is terminated + /// and returns the exit code of the process. + /// If the process is still running, returns -1. + protected: ProcessHandle(ProcessHandleImpl* pImpl); @@ -211,6 +216,10 @@ public: /// Waits for the process specified by handle to terminate /// and returns the exit code of the process. + static int tryWait(const ProcessHandle& handle); + /// Checks that process is finished and returns the exit code of the + /// process. If the process is still running, returns -1. + static bool isRunning(const ProcessHandle& handle); /// check if the process specified by handle is running or not /// diff --git a/Foundation/include/Poco/Process_UNIX.h b/Foundation/include/Poco/Process_UNIX.h index b33dd0821..85926f32f 100644 --- a/Foundation/include/Poco/Process_UNIX.h +++ b/Foundation/include/Poco/Process_UNIX.h @@ -36,10 +36,11 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject public: ProcessHandleImpl(pid_t pid); ~ProcessHandleImpl(); - + pid_t id() const; int wait() const; - + int tryWait() const; + private: pid_t _pid; }; @@ -51,15 +52,15 @@ public: typedef pid_t PIDImpl; typedef std::vector ArgsImpl; typedef std::map EnvImpl; - + static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); static ProcessHandleImpl* launchImpl( - const std::string& command, - const ArgsImpl& args, + const std::string& command, + const ArgsImpl& args, const std::string& initialDirectory, - Pipe* inPipe, - Pipe* outPipe, + Pipe* inPipe, + Pipe* outPipe, Pipe* errPipe, const EnvImpl& env); static void killImpl(ProcessHandleImpl& handle); @@ -70,11 +71,11 @@ public: private: static ProcessHandleImpl* launchByForkExecImpl( - const std::string& command, - const ArgsImpl& args, + const std::string& command, + const ArgsImpl& args, const std::string& initialDirectory, - Pipe* inPipe, - Pipe* outPipe, + Pipe* inPipe, + Pipe* outPipe, Pipe* errPipe, const EnvImpl& env); }; diff --git a/Foundation/include/Poco/Process_VX.h b/Foundation/include/Poco/Process_VX.h index 0ac9bcef2..189828e3a 100644 --- a/Foundation/include/Poco/Process_VX.h +++ b/Foundation/include/Poco/Process_VX.h @@ -38,10 +38,11 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject public: ProcessHandleImpl(int pid); ~ProcessHandleImpl(); - + int id() const; int wait() const; - + int tryWait() const; + private: int _pid; }; @@ -53,15 +54,15 @@ public: typedef int PIDImpl; typedef std::vector ArgsImpl; typedef std::map EnvImpl; - + static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); static ProcessHandleImpl* launchImpl( - const std::string& command, - const ArgsImpl& args, + const std::string& command, + const ArgsImpl& args, const std::string& initialDirectory, - Pipe* inPipe, - Pipe* outPipe, + Pipe* inPipe, + Pipe* outPipe, Pipe* errPipe, const EnvImpl& env); static void killImpl(ProcessHandleImpl& handle); diff --git a/Foundation/include/Poco/Process_WIN32.h b/Foundation/include/Poco/Process_WIN32.h index afed42c25..90f5600b5 100644 --- a/Foundation/include/Poco/Process_WIN32.h +++ b/Foundation/include/Poco/Process_WIN32.h @@ -36,16 +36,17 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject public: ProcessHandleImpl(HANDLE _hProcess, UInt32 pid); ~ProcessHandleImpl(); - + UInt32 id() const; HANDLE process() const; int wait() const; + int tryWait() const; void closeHandle(); private: HANDLE _hProcess; UInt32 _pid; - + ProcessHandleImpl(const ProcessHandleImpl&); ProcessHandleImpl& operator = (const ProcessHandleImpl&); }; @@ -57,15 +58,15 @@ public: typedef UInt32 PIDImpl; typedef std::vector ArgsImpl; typedef std::map EnvImpl; - + static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); static ProcessHandleImpl* launchImpl( - const std::string& command, - const ArgsImpl& args, + const std::string& command, + const ArgsImpl& args, const std::string& initialDirectory, - Pipe* inPipe, - Pipe* outPipe, + Pipe* inPipe, + Pipe* outPipe, Pipe* errPipe, const EnvImpl& env); static void killImpl(ProcessHandleImpl& handle); diff --git a/Foundation/include/Poco/Process_WIN32U.h b/Foundation/include/Poco/Process_WIN32U.h index bb5201360..dd62fbf4d 100644 --- a/Foundation/include/Poco/Process_WIN32U.h +++ b/Foundation/include/Poco/Process_WIN32U.h @@ -36,10 +36,11 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject public: ProcessHandleImpl(HANDLE _hProcess, UInt32 pid); ~ProcessHandleImpl(); - + UInt32 id() const; HANDLE process() const; int wait() const; + int tryWait() const; void closeHandle(); private: @@ -57,15 +58,15 @@ public: typedef UInt32 PIDImpl; typedef std::vector ArgsImpl; typedef std::map EnvImpl; - + static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); static ProcessHandleImpl* launchImpl( - const std::string& command, - const ArgsImpl& args, + const std::string& command, + const ArgsImpl& args, const std::string& initialDirectory, - Pipe* inPipe, - Pipe* outPipe, + Pipe* inPipe, + Pipe* outPipe, Pipe* errPipe, const EnvImpl& env); static void killImpl(ProcessHandleImpl& handle); diff --git a/Foundation/include/Poco/Process_WINCE.h b/Foundation/include/Poco/Process_WINCE.h index f754c577a..5f93077d4 100644 --- a/Foundation/include/Poco/Process_WINCE.h +++ b/Foundation/include/Poco/Process_WINCE.h @@ -36,10 +36,11 @@ class Foundation_API ProcessHandleImpl: public RefCountedObject public: ProcessHandleImpl(HANDLE _hProcess, UInt32 pid); ~ProcessHandleImpl(); - + UInt32 id() const; HANDLE process() const; int wait() const; + int tryWait() const; void closeHandle(); private: @@ -57,15 +58,15 @@ public: typedef UInt32 PIDImpl; typedef std::vector ArgsImpl; typedef std::map EnvImpl; - + static PIDImpl idImpl(); static void timesImpl(long& userTime, long& kernelTime); static ProcessHandleImpl* launchImpl( - const std::string& command, - const ArgsImpl& args, + const std::string& command, + const ArgsImpl& args, const std::string& initialDirectory, - Pipe* inPipe, - Pipe* outPipe, + Pipe* inPipe, + Pipe* outPipe, Pipe* errPipe, const EnvImpl& env); static void killImpl(ProcessHandleImpl& handle); diff --git a/Foundation/include/Poco/SharedPtr.h b/Foundation/include/Poco/SharedPtr.h index c09592599..6420355dd 100644 --- a/Foundation/include/Poco/SharedPtr.h +++ b/Foundation/include/Poco/SharedPtr.h @@ -44,7 +44,7 @@ public: { return --_cnt; } - + int referenceCount() const { return _cnt.value(); @@ -61,7 +61,7 @@ class ReleasePolicy /// simply uses the delete operator to delete an object. { public: - static void release(C* pObj) + static void release(C* pObj) noexcept /// Delete the object. /// Note that pObj can be nullptr. { @@ -75,7 +75,7 @@ class ReleaseArrayPolicy /// The release policy for SharedPtr holding arrays. { public: - static void release(C* pObj) + static void release(C* pObj) noexcept /// Delete the object. /// Note that pObj can be nullptr. { @@ -94,11 +94,11 @@ class SharedPtr /// can be used with any class. For this to work, a /// SharedPtr manages a reference count for the object /// it manages. - /// + /// /// SharedPtr works in the following way: /// If an SharedPtr is assigned an ordinary pointer to /// an object (via the constructor or the assignment operator), - /// it takes ownership of the object and the object's reference + /// it takes ownership of the object and the object's reference /// count is initialized to one. /// If the SharedPtr is assigned another SharedPtr, the /// object's reference count is incremented by one. @@ -115,33 +115,41 @@ class SharedPtr public: typedef C Type; - SharedPtr(): _pCounter(nullptr), _ptr(nullptr) + SharedPtr(): + _pCounter(nullptr), + _ptr(nullptr) { } SharedPtr(C* ptr) try: - _pCounter(ptr ? new RC : nullptr), + _pCounter(ptr ? new RC : nullptr), _ptr(ptr) { } - catch (...) + catch (...) { RP::release(ptr); } - template - SharedPtr(const SharedPtr& ptr): _pCounter(ptr._pCounter), _ptr(const_cast(ptr.get())) + template + SharedPtr(const SharedPtr& ptr): + _pCounter(ptr._pCounter), + _ptr(const_cast(ptr.get())) { if (_pCounter) _pCounter->duplicate(); } - SharedPtr(const SharedPtr& ptr): _pCounter(ptr._pCounter), _ptr(ptr._ptr) + SharedPtr(const SharedPtr& ptr): + _pCounter(ptr._pCounter), + _ptr(ptr._ptr) { if (_pCounter) _pCounter->duplicate(); } - SharedPtr(SharedPtr&& ptr) noexcept: _pCounter(std::move(ptr._pCounter)), _ptr(std::move(ptr._ptr)) + SharedPtr(SharedPtr&& ptr) noexcept: + _pCounter(ptr._pCounter), + _ptr(ptr._ptr) { ptr._pCounter = nullptr; ptr._ptr = nullptr; @@ -149,14 +157,7 @@ public: ~SharedPtr() { - try - { - release(); - } - catch (...) - { - poco_unexpected(); - } + release(); } SharedPtr& assign(C* ptr) @@ -168,7 +169,7 @@ public: } return *this; } - + SharedPtr& assign(const SharedPtr& ptr) { if (&ptr != this) @@ -178,7 +179,7 @@ public: } return *this; } - + template SharedPtr& assign(const SharedPtr& ptr) { @@ -223,9 +224,10 @@ public: SharedPtr& operator = (SharedPtr&& ptr) noexcept { - _ptr = std::move(ptr._ptr); - _pCounter = std::move(ptr._pCounter); + release(); + _ptr = ptr._ptr; ptr._ptr = nullptr; + _pCounter = ptr._pCounter; ptr._pCounter = nullptr; return *this; } @@ -242,7 +244,7 @@ public: std::swap(_pCounter, ptr._pCounter); } - template + template SharedPtr cast() const /// Casts the SharedPtr via a dynamic cast to the given type. /// Returns an SharedPtr containing NULL if the cast fails. @@ -257,7 +259,7 @@ public: return SharedPtr(); } - template + template SharedPtr unsafeCast() const /// Casts the SharedPtr via a static cast to the given type. /// Example: (assume class Sub: public Super) @@ -303,7 +305,7 @@ public: { return _ptr; } - + operator const C* () const { return _ptr; @@ -408,7 +410,7 @@ public: { return get() >= ptr; } - + int referenceCount() const { return _pCounter ? _pCounter->referenceCount() : 0; @@ -423,7 +425,7 @@ private: return _ptr; } - void release() + void release() noexcept { if (_pCounter && _pCounter->release() == 0) { diff --git a/Foundation/include/Poco/UUIDGenerator.h b/Foundation/include/Poco/UUIDGenerator.h index 517417de9..b91c2d895 100644 --- a/Foundation/include/Poco/UUIDGenerator.h +++ b/Foundation/include/Poco/UUIDGenerator.h @@ -37,7 +37,7 @@ class Foundation_API UUIDGenerator /// as specified in Appendix A of the DCE 1.1 Remote Procedure /// Call Specification (http://www.opengroup.org/onlinepubs/9629399/), /// RFC 2518 (WebDAV), section 6.4.1 and the UUIDs and GUIDs internet - /// draft by Leach/Salz from February, 1998 + /// draft by Leach/Salz from February, 1998 /// (http://ftp.ics.uci.edu/pub/ietf/webdav/uuid-guid/draft-leach-uuids-guids-01.txt) { public: @@ -53,7 +53,7 @@ public: /// /// Throws a SystemException if no MAC address can be /// obtained. - + UUID createFromName(const UUID& nsid, const std::string& name); /// Creates a name-based UUID. @@ -66,21 +66,28 @@ public: UUID createFromName(const UUID& nsid, const std::string& name, DigestEngine& de, UUID::Version version); /// Creates a name-based UUID, using the given digest engine and version. - + UUID createRandom(); /// Creates a random UUID. - + UUID createOne(); - /// Tries to create and return a time-based UUID (see create()), and, + /// Tries to create and return a time-based UUID (see create()), and, /// if that does not work due to the unavailability of a MAC address, /// creates and returns a random UUID (see createRandom()). /// /// The UUID::version() method can be used to determine the actual kind of /// the UUID generated. + void seed(UInt32 n); + /// Seeds the internal pseudo random generator for time-based UUIDs with the given seed. + + void seed(); + /// Seeds the internal pseudo random generator used for time-based UUIDs + /// with a random seed obtained from a RandomInputStream. + static UUIDGenerator& defaultGenerator(); /// Returns a reference to the default UUIDGenerator. - + protected: Timestamp::UtcTimeVal timeStamp(); void getNode(); @@ -92,7 +99,7 @@ private: int _ticks; Environment::NodeId _node; bool _haveNode; - + UUIDGenerator(const UUIDGenerator&); UUIDGenerator& operator = (const UUIDGenerator&); }; diff --git a/Foundation/include/Poco/UnWindows.h b/Foundation/include/Poco/UnWindows.h index 0c472ee10..b4778bf31 100644 --- a/Foundation/include/Poco/UnWindows.h +++ b/Foundation/include/Poco/UnWindows.h @@ -5,25 +5,7 @@ // Package: Core // Module: UnWindows // -// A wrapper around the header file that #undef's some -// of the macros for function names defined by that -// are a frequent source of conflicts (e.g., GetUserName). -// -// Remember, that most of the WIN32 API functions come in two variants, -// an Unicode variant (e.g., GetUserNameA) and an ASCII variant (GetUserNameW). -// There is also a macro (GetUserName) that's either defined to be the Unicode -// name or the ASCII name, depending on whether the UNICODE macro is #define'd -// or not. POCO always calls the Unicode functions directly. -// -// These macro definitions are a frequent case of problems and naming conflicts, -// especially for C++ programmers. Say, you define a class with a member function named -// GetUserName. Depending on whether "Poco/UnWindows.h" has been included by a particular -// translation unit or not, this might be changed to GetUserNameA/GetUserNameW, or not. -// While, due to naming conventions used, this is less of a problem in POCO, some -// of the users of POCO might use a different naming convention where this can become -// a problem. -// -// To disable the #undef's, compile POCO with the POCO_NO_UNWINDOWS macro #define'd. +// Simple wrapper around the header file. // // Copyright (c) 2007, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -44,17 +26,6 @@ #endif -// Microsoft Visual C++ includes copies of the Windows header files -// that were current at the time Visual C++ was released. -// The Windows header files use macros to indicate which versions -// of Windows support many programming elements. Therefore, you must -// define these macros to use new functionality introduced in each -// major operating system release. (Individual header files may use -// different macros; therefore, if compilation problems occur, check -// the header file that contains the definition for conditional -// definitions.) For more information, see SdkDdkVer.h. - - #if !defined(POCO_NO_WINDOWS_H) #include #ifdef __MINGW32__ @@ -65,55 +36,4 @@ #endif -#if !defined(POCO_NO_UNWINDOWS) -// A list of annoying macros to #undef. -// Extend as required. -#undef GetBinaryType -#undef GetShortPathName -#undef GetLongPathName -#undef GetEnvironmentStrings -#undef SetEnvironmentStrings -#undef FreeEnvironmentStrings -#undef FormatMessage -#undef EncryptFile -#undef DecryptFile -#undef CreateMutex -#undef OpenMutex -#undef CreateEvent -#undef OpenEvent -#undef CreateSemaphore -#undef OpenSemaphore -#undef LoadLibrary -#undef GetModuleFileName -#undef CreateProcess -#undef GetCommandLine -#undef GetEnvironmentVariable -#undef SetEnvironmentVariable -#undef ExpandEnvironmentStrings -#undef OutputDebugString -#undef FindResource -#undef UpdateResource -#undef FindAtom -#undef AddAtom -#undef GetSystemDirectory -#undef GetTempPath -#undef GetTempFileName -#undef SetCurrentDirectory -#undef GetCurrentDirectory -#undef CreateDirectory -#undef RemoveDirectory -#undef CreateFile -#undef DeleteFile -#undef SearchPath -#undef CopyFile -#undef MoveFile -#undef ReplaceFile -#undef GetComputerName -#undef SetComputerName -#undef GetUserName -#undef LogonUser -#undef GetVersion -#undef GetObject -#endif // POCO_NO_UNWINDOWS - #endif // Foundation_UnWindows_INCLUDED diff --git a/Foundation/src/DirectoryIterator.cpp b/Foundation/src/DirectoryIterator.cpp index bc5f53452..432c593f9 100644 --- a/Foundation/src/DirectoryIterator.cpp +++ b/Foundation/src/DirectoryIterator.cpp @@ -15,7 +15,7 @@ #include "Poco/DirectoryIterator.h" -#if defined(POCO_OS_FAMILY_WINDOWS) +#if defined(POCO_OS_FAMILY_WINDOWS) #include "DirectoryIterator_WIN32U.cpp" #elif defined(POCO_OS_FAMILY_UNIX) #include "DirectoryIterator_UNIX.cpp" @@ -72,13 +72,16 @@ DirectoryIterator::~DirectoryIterator() DirectoryIterator& DirectoryIterator::operator = (const DirectoryIterator& it) { - if (_pImpl) _pImpl->release(); - _pImpl = it._pImpl; - if (_pImpl) + if (&it != this) { - _pImpl->duplicate(); - _path = it._path; - _file = _path; + if (_pImpl) _pImpl->release(); + _pImpl = it._pImpl; + if (_pImpl) + { + _pImpl->duplicate(); + _path = it._path; + _file = _path; + } } return *this; } diff --git a/Foundation/src/DirectoryWatcher.cpp b/Foundation/src/DirectoryWatcher.cpp index 4d9d3613d..1b922607e 100644 --- a/Foundation/src/DirectoryWatcher.cpp +++ b/Foundation/src/DirectoryWatcher.cpp @@ -150,7 +150,7 @@ private: }; -#if POCO_OS == POCO_OS_WINDOWS_NT +#if (POCO_OS == POCO_OS_WINDOWS_NT) && !defined(POCO_DW_FORCE_POLLING) class WindowsDirectoryWatcherStrategy: public DirectoryWatcherStrategy @@ -248,7 +248,7 @@ private: }; -#elif POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID +#elif (POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID) && !defined(POCO_DW_FORCE_POLLING) class LinuxDirectoryWatcherStrategy: public DirectoryWatcherStrategy @@ -376,7 +376,7 @@ private: }; -#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD +#elif (POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD) && !defined(POCO_DW_FORCE_POLLING) class BSDDirectoryWatcherStrategy: public DirectoryWatcherStrategy @@ -566,11 +566,11 @@ void DirectoryWatcher::init() if (!_directory.isDirectory()) throw Poco::InvalidArgumentException("not a directory", _directory.path()); -#if POCO_OS == POCO_OS_WINDOWS_NT +#if (POCO_OS == POCO_OS_WINDOWS_NT) && !defined(POCO_DW_FORCE_POLLING) _pStrategy = new WindowsDirectoryWatcherStrategy(*this); -#elif POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID +#elif (POCO_OS == POCO_OS_LINUX || POCO_OS == POCO_OS_ANDROID) && !defined(POCO_DW_FORCE_POLLING) _pStrategy = new LinuxDirectoryWatcherStrategy(*this); -#elif POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD +#elif (POCO_OS == POCO_OS_MAC_OS_X || POCO_OS == POCO_OS_FREE_BSD) && !defined(POCO_DW_FORCE_POLLING) _pStrategy = new BSDDirectoryWatcherStrategy(*this); #else _pStrategy = new PollingDirectoryWatcherStrategy(*this); diff --git a/Foundation/src/Environment.cpp b/Foundation/src/Environment.cpp index 32753efc5..e81a8a7c1 100644 --- a/Foundation/src/Environment.cpp +++ b/Foundation/src/Environment.cpp @@ -26,7 +26,7 @@ #if defined(_WIN32_WCE) #include "Environment_WINCE.cpp" #else -#include "Environment_WIN32.cpp" +#include "Environment_WIN32U.cpp" #endif #endif diff --git a/Foundation/src/Message.cpp b/Foundation/src/Message.cpp index 7a26c9253..94a3b53b3 100644 --- a/Foundation/src/Message.cpp +++ b/Foundation/src/Message.cpp @@ -24,41 +24,41 @@ namespace Poco { -Message::Message(): - _prio(PRIO_FATAL), - _tid(0), +Message::Message(): + _prio(PRIO_FATAL), + _tid(0), _pid(0), _file(0), _line(0), - _pMap(0) + _pMap(0) { init(); } -Message::Message(const std::string& source, const std::string& text, Priority prio): - _source(source), - _text(text), - _prio(prio), +Message::Message(const std::string& source, const std::string& text, Priority prio): + _source(source), + _text(text), + _prio(prio), _tid(0), _pid(0), _file(0), _line(0), - _pMap(0) + _pMap(0) { init(); } Message::Message(const std::string& source, const std::string& text, Priority prio, const char* file, int line): - _source(source), - _text(text), - _prio(prio), + _source(source), + _text(text), + _prio(prio), _tid(0), _pid(0), _file(file), _line(line), - _pMap(0) + _pMap(0) { init(); } @@ -82,7 +82,7 @@ Message::Message(const Message& msg): } -Message::Message(Message&& msg) : +Message::Message(Message&& msg) noexcept: _source(std::move(msg._source)), _text(std::move(msg._text)), _prio(std::move(msg._prio)), @@ -147,23 +147,20 @@ Message& Message::operator = (const Message& msg) } -Message& Message::operator = (Message&& msg) +Message& Message::operator = (Message&& msg) noexcept { - if (&msg != this) - { - _source = std::move(msg._source); - _text = std::move(msg._text); - _prio = std::move(msg._prio); - _time = std::move(msg._time); - _tid = std::move(msg._tid); - _thread = std::move(msg._thread); - _pid = std::move(msg._pid); - _file = std::move(msg._file); - _line = std::move(msg._line); - delete _pMap; - _pMap = msg._pMap; - msg._pMap = nullptr; - } + _source = std::move(msg._source); + _text = std::move(msg._text); + _prio = std::move(msg._prio); + _time = std::move(msg._time); + _tid = std::move(msg._tid); + _thread = std::move(msg._thread); + _pid = std::move(msg._pid); + _file = std::move(msg._file); + _line = std::move(msg._line); + delete _pMap; + _pMap = msg._pMap; + msg._pMap = nullptr; return *this; } diff --git a/Foundation/src/Path_UNIX.cpp b/Foundation/src/Path_UNIX.cpp index 583946c8b..697e0f641 100644 --- a/Foundation/src/Path_UNIX.cpp +++ b/Foundation/src/Path_UNIX.cpp @@ -51,21 +51,34 @@ std::string PathImpl::homeImpl() { #if defined(POCO_VXWORKS) if (EnvironmentImpl::hasImpl("HOME")) - return EnvironmentImpl::getImpl("HOME"); - else - return "/"; + { + std::string path = EnvironmentImpl::getImpl("HOME"); + std::string::size_type n = path.size(); + if (n > 0 && path[n - 1] != '/') path.append("/"); + return path; + } + else return "/"; #else std::string path; - struct passwd* pwd = getpwuid(getuid()); - if (pwd) - path = pwd->pw_dir; + if (EnvironmentImpl::hasImpl("HOME")) + { + path = EnvironmentImpl::getImpl("HOME"); + } else { - pwd = getpwuid(geteuid()); + struct passwd* pwd = getpwuid(getuid()); if (pwd) + { path = pwd->pw_dir; + } else - path = EnvironmentImpl::getImpl("HOME"); + { + pwd = getpwuid(geteuid()); + if (pwd) + path = pwd->pw_dir; + else + path = "/"; + } } std::string::size_type n = path.size(); if (n > 0 && path[n - 1] != '/') path.append("/"); @@ -78,15 +91,23 @@ std::string PathImpl::configHomeImpl() { #if defined(POCO_VXWORKS) return PathImpl::homeImpl(); -#else +#elif POCO_OS == POCO_OS_MAC_OS_X std::string path = PathImpl::homeImpl(); std::string::size_type n = path.size(); - if (n > 0 && path[n - 1] == '/') -#if POCO_OS == POCO_OS_MAC_OS_X - path.append("Library/Preferences/"); + if (n > 0 && path[n - 1] == '/') + path.append("Library/Preferences/"); + return path; #else - path.append(".config/"); -#endif + std::string path; + if (EnvironmentImpl::hasImpl("XDG_CONFIG_HOME")) + path = EnvironmentImpl::getImpl("XDG_CONFIG_HOME"); + if (!path.empty()) + return path; + + path = PathImpl::homeImpl(); + std::string::size_type n = path.size(); + if (n > 0 && path[n - 1] == '/') + path.append(".config/"); return path; #endif @@ -97,15 +118,23 @@ std::string PathImpl::dataHomeImpl() { #if defined(POCO_VXWORKS) return PathImpl::homeImpl(); -#else +#elif POCO_OS == POCO_OS_MAC_OS_X std::string path = PathImpl::homeImpl(); std::string::size_type n = path.size(); - if (n > 0 && path[n - 1] == '/') -#if POCO_OS == POCO_OS_MAC_OS_X - path.append("Library/Application Support/"); + if (n > 0 && path[n - 1] == '/') + path.append("Library/Application Support/"); + return path; #else - path.append(".local/share/"); -#endif + std::string path; + if (EnvironmentImpl::hasImpl("XDG_DATA_HOME")) + path = EnvironmentImpl::getImpl("XDG_DATA_HOME"); + if (!path.empty()) + return path; + + path = PathImpl::homeImpl(); + std::string::size_type n = path.size(); + if (n > 0 && path[n - 1] == '/') + path.append(".local/share/"); return path; #endif @@ -116,15 +145,23 @@ std::string PathImpl::cacheHomeImpl() { #if defined(POCO_VXWORKS) return PathImpl::tempImpl(); -#else +#elif POCO_OS == POCO_OS_MAC_OS_X std::string path = PathImpl::homeImpl(); std::string::size_type n = path.size(); - if (n > 0 && path[n - 1] == '/') -#if POCO_OS == POCO_OS_MAC_OS_X - path.append("Library/Caches/"); + if (n > 0 && path[n - 1] == '/') + path.append("Library/Caches/"); + return path; #else - path.append(".cache/"); -#endif + std::string path; + if (EnvironmentImpl::hasImpl("XDG_CACHE_HOME")) + path = EnvironmentImpl::getImpl("XDG_CACHE_HOME"); + if (!path.empty()) + return path; + + path = PathImpl::homeImpl(); + std::string::size_type n = path.size(); + if (n > 0 && path[n - 1] == '/') + path.append(".cache/"); return path; #endif @@ -138,7 +175,7 @@ std::string PathImpl::tempHomeImpl() #else std::string path = PathImpl::homeImpl(); std::string::size_type n = path.size(); - if (n > 0 && path[n - 1] == '/') + if (n > 0 && path[n - 1] == '/') #if POCO_OS == POCO_OS_MAC_OS_X path.append("Library/Caches/"); #else @@ -171,7 +208,7 @@ std::string PathImpl::tempImpl() std::string PathImpl::configImpl() { std::string path; - + #if POCO_OS == POCO_OS_MAC_OS_X path = "/Library/Preferences/"; #else @@ -219,7 +256,15 @@ std::string PathImpl::expandImpl(const std::string& path) } while (it != end) { - if (*it == '$') + if (*it == '\\') + { + ++it; + if (*it == '$') + { + result += *it++; + } + } + else if (*it == '$') { std::string var; ++it; @@ -238,6 +283,12 @@ std::string PathImpl::expandImpl(const std::string& path) } else result += *it++; } + std::string::size_type found = result.find("//"); + while (found != std::string::npos) + { + result.replace(found, 2, "/"); + found = result.find("//", found+1); + } return result; } diff --git a/Foundation/src/Process.cpp b/Foundation/src/Process.cpp index be542a8aa..984fe50d8 100644 --- a/Foundation/src/Process.cpp +++ b/Foundation/src/Process.cpp @@ -110,6 +110,12 @@ int ProcessHandle::wait() const } +int ProcessHandle::tryWait() const +{ + return _pImpl->tryWait(); +} + + // // Process // @@ -166,6 +172,12 @@ int Process::wait(const ProcessHandle& handle) } +int Process::tryWait(const ProcessHandle& handle) +{ + return handle.tryWait(); +} + + void Process::kill(ProcessHandle& handle) { killImpl(*handle._pImpl); diff --git a/Foundation/src/Process_UNIX.cpp b/Foundation/src/Process_UNIX.cpp index 4cb21fffb..00bf0a750 100644 --- a/Foundation/src/Process_UNIX.cpp +++ b/Foundation/src/Process_UNIX.cpp @@ -66,7 +66,31 @@ int ProcessHandleImpl::wait() const while (rc < 0 && errno == EINTR); if (rc != _pid) throw SystemException("Cannot wait for process", NumberFormatter::format(_pid)); - return WEXITSTATUS(status); + + if (WIFEXITED(status)) // normal termination + return WEXITSTATUS(status); + else // termination by a signal + return 256 + WTERMSIG(status); +} + + +int ProcessHandleImpl::tryWait() const +{ + int status; + int rc; + do + { + rc = waitpid(_pid, &status, WNOHANG); + } + while (rc < 0 && errno == EINTR); + if (rc == 0) + return -1; + if (rc != _pid) + throw SystemException("Cannot wait for process", NumberFormatter::format(_pid)); + if (WIFEXITED(status)) // normal termination + return WEXITSTATUS(status); + else // termination by a signal + return 256 + WTERMSIG(status); } @@ -97,7 +121,7 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg char** argv = new char*[args.size() + 2]; int i = 0; argv[i++] = const_cast(command.c_str()); - for (const auto& a: args) + for (const auto& a: args) argv[i++] = const_cast(a.c_str()); argv[i] = NULL; struct inheritance inherit; @@ -107,7 +131,7 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg fdmap[0] = inPipe ? inPipe->readHandle() : 0; fdmap[1] = outPipe ? outPipe->writeHandle() : 1; fdmap[2] = errPipe ? errPipe->writeHandle() : 2; - + char** envPtr = 0; std::vector envChars; std::vector envPtrs; @@ -125,10 +149,10 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg envPtrs.push_back(0); envPtr = &envPtrs[0]; } - + int pid = spawn(command.c_str(), 3, fdmap, &inherit, argv, envPtr); delete [] argv; - if (pid == -1) + if (pid == -1) throw SystemException("cannot spawn", command); if (inPipe) inPipe->close(Pipe::CLOSE_READ); @@ -155,18 +179,18 @@ ProcessHandleImpl* ProcessImpl::launchByForkExecImpl(const std::string& command, std::vector argv(args.size() + 2); int i = 0; argv[i++] = const_cast(command.c_str()); - for (const auto& a: args) + for (const auto& a: args) { argv[i++] = const_cast(a.c_str()); } argv[i] = NULL; - + const char* pInitialDirectory = initialDirectory.empty() ? 0 : initialDirectory.c_str(); int pid = fork(); if (pid < 0) { - throw SystemException("Cannot fork process for", command); + throw SystemException("Cannot fork process for", command); } else if (pid == 0) { @@ -247,19 +271,19 @@ bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle) } -bool ProcessImpl::isRunningImpl(PIDImpl pid) +bool ProcessImpl::isRunningImpl(PIDImpl pid) { - if (kill(pid, 0) == 0) + if (kill(pid, 0) == 0) { return true; - } - else + } + else { return false; } } - + void ProcessImpl::requestTerminationImpl(PIDImpl pid) { if (kill(pid, SIGINT) != 0) diff --git a/Foundation/src/Process_VX.cpp b/Foundation/src/Process_VX.cpp index 699feb9be..7bb4dca94 100644 --- a/Foundation/src/Process_VX.cpp +++ b/Foundation/src/Process_VX.cpp @@ -45,6 +45,12 @@ int ProcessHandleImpl::wait() const } +int ProcessHandleImpl::tryWait() const +{ + throw Poco::NotImplementedException("Process::tryWait()"); +} + + // // ProcessImpl // @@ -79,13 +85,13 @@ void ProcessImpl::killImpl(PIDImpl pid) } -bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle) +bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle) { throw Poco::NotImplementedException("Process::is_running()"); } -bool ProcessImpl::isRunningImpl(PIDImpl pid) +bool ProcessImpl::isRunningImpl(PIDImpl pid) { throw Poco::NotImplementedException("Process::is_running()"); } diff --git a/Foundation/src/Process_WIN32.cpp b/Foundation/src/Process_WIN32.cpp index 51a99d2d6..469e6da5b 100644 --- a/Foundation/src/Process_WIN32.cpp +++ b/Foundation/src/Process_WIN32.cpp @@ -74,6 +74,18 @@ int ProcessHandleImpl::wait() const } +int ProcessHandleImpl::tryWait() const +{ + DWORD exitCode; + if (GetExitCodeProcess(_hProcess, &exitCode) == 0) + throw SystemException("Cannot get exit code for process", NumberFormatter::format(_pid)); + if (exitCode == STILL_ACTIVE) + return -1; + else + return exitCode; +} + + // // ProcessImpl // @@ -99,7 +111,7 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime) time.LowPart = ftUser.dwLowDateTime; time.HighPart = ftUser.dwHighDateTime; userTime = long(time.QuadPart / 10000000L); - } + } else { userTime = kernelTime = -1; @@ -137,12 +149,12 @@ static std::string escapeArg(const std::string& arg) { quotedArg.append(2 * backslashCount, '\\'); break; - } + } else if ('"' == *it) { quotedArg.append(2 * backslashCount + 1, '\\'); quotedArg.push_back('"'); - } + } else { quotedArg.append(backslashCount, '\\'); @@ -151,7 +163,7 @@ static std::string escapeArg(const std::string& arg) } quotedArg.push_back('"'); return quotedArg; - } + } else { return arg; @@ -185,12 +197,12 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg DuplicateHandle(hProc, inPipe->readHandle(), hProc, &startupInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; inPipe->close(Pipe::CLOSE_READ); - } + } else if (GetStdHandle(STD_INPUT_HANDLE)) { DuplicateHandle(hProc, GetStdHandle(STD_INPUT_HANDLE), hProc, &startupInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else { startupInfo.hStdInput = 0; @@ -200,12 +212,12 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { DuplicateHandle(hProc, outPipe->writeHandle(), hProc, &startupInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else if (GetStdHandle(STD_OUTPUT_HANDLE)) { DuplicateHandle(hProc, GetStdHandle(STD_OUTPUT_HANDLE), hProc, &startupInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else { startupInfo.hStdOutput = 0; @@ -214,12 +226,12 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { DuplicateHandle(hProc, errPipe->writeHandle(), hProc, &startupInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else if (GetStdHandle(STD_ERROR_HANDLE)) { DuplicateHandle(hProc, GetStdHandle(STD_ERROR_HANDLE), hProc, &startupInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else { startupInfo.hStdError = 0; @@ -263,7 +275,7 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { CloseHandle(processInfo.hThread); return new ProcessHandleImpl(processInfo.hProcess, processInfo.dwProcessId); - } + } else throw SystemException("Cannot launch process", command); } @@ -292,14 +304,14 @@ void ProcessImpl::killImpl(PIDImpl pid) throw SystemException("cannot kill process"); } CloseHandle(hProc); - } + } else { switch (GetLastError()) { case ERROR_ACCESS_DENIED: throw NoPermissionException("cannot kill process"); - case ERROR_NOT_FOUND: + case ERROR_NOT_FOUND: throw NotFoundException("cannot kill process"); case ERROR_INVALID_PARAMETER: throw NotFoundException("cannot kill process"); diff --git a/Foundation/src/Process_WIN32U.cpp b/Foundation/src/Process_WIN32U.cpp index 42da63ab4..f44d0a577 100644 --- a/Foundation/src/Process_WIN32U.cpp +++ b/Foundation/src/Process_WIN32U.cpp @@ -78,6 +78,18 @@ int ProcessHandleImpl::wait() const } +int ProcessHandleImpl::tryWait() const +{ + DWORD exitCode; + if (GetExitCodeProcess(_hProcess, &exitCode) == 0) + throw SystemException("Cannot get exit code for process", NumberFormatter::format(_pid)); + if (exitCode == STILL_ACTIVE) + return -1; + else + return exitCode; +} + + // // ProcessImpl // @@ -103,7 +115,7 @@ void ProcessImpl::timesImpl(long& userTime, long& kernelTime) time.LowPart = ftUser.dwLowDateTime; time.HighPart = ftUser.dwHighDateTime; userTime = long(time.QuadPart / 10000000L); - } + } else { userTime = kernelTime = -1; @@ -141,12 +153,12 @@ static std::string escapeArg(const std::string& arg) { quotedArg.append(2 * backslashCount, '\\'); break; - } + } else if ('"' == *it) { quotedArg.append(2 * backslashCount + 1, '\\'); quotedArg.push_back('"'); - } + } else { quotedArg.append(backslashCount, '\\'); @@ -155,7 +167,7 @@ static std::string escapeArg(const std::string& arg) } quotedArg.push_back('"'); return quotedArg; - } + } else { return arg; @@ -205,12 +217,12 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg DuplicateHandle(hProc, inPipe->readHandle(), hProc, &startupInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; inPipe->close(Pipe::CLOSE_READ); - } + } else if (GetStdHandle(STD_INPUT_HANDLE)) { DuplicateHandle(hProc, GetStdHandle(STD_INPUT_HANDLE), hProc, &startupInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else { startupInfo.hStdInput = 0; @@ -220,12 +232,12 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { DuplicateHandle(hProc, outPipe->writeHandle(), hProc, &startupInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else if (GetStdHandle(STD_OUTPUT_HANDLE)) { DuplicateHandle(hProc, GetStdHandle(STD_OUTPUT_HANDLE), hProc, &startupInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else { startupInfo.hStdOutput = 0; @@ -234,12 +246,12 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { DuplicateHandle(hProc, errPipe->writeHandle(), hProc, &startupInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else if (GetStdHandle(STD_ERROR_HANDLE)) { DuplicateHandle(hProc, GetStdHandle(STD_ERROR_HANDLE), hProc, &startupInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); mustInheritHandles = true; - } + } else { startupInfo.hStdError = 0; @@ -285,7 +297,7 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { CloseHandle(processInfo.hThread); return new ProcessHandleImpl(processInfo.hProcess, processInfo.dwProcessId); - } + } else throw SystemException("Cannot launch process", command); } @@ -314,14 +326,14 @@ void ProcessImpl::killImpl(PIDImpl pid) throw SystemException("cannot kill process"); } CloseHandle(hProc); - } + } else { switch (GetLastError()) { case ERROR_ACCESS_DENIED: throw NoPermissionException("cannot kill process"); - case ERROR_NOT_FOUND: + case ERROR_NOT_FOUND: throw NotFoundException("cannot kill process"); case ERROR_INVALID_PARAMETER: throw NotFoundException("cannot kill process"); diff --git a/Foundation/src/Process_WINCE.cpp b/Foundation/src/Process_WINCE.cpp index e640f3be3..49604287a 100644 --- a/Foundation/src/Process_WINCE.cpp +++ b/Foundation/src/Process_WINCE.cpp @@ -73,12 +73,24 @@ int ProcessHandleImpl::wait() const } +int ProcessHandleImpl::tryWait() const +{ + DWORD exitCode; + if (GetExitCodeProcess(_hProcess, &exitCode) == 0) + throw SystemException("Cannot get exit code for process", NumberFormatter::format(_pid)); + if (exitCode == STILL_ACTIVE) + return -1; + else + return exitCode; +} + + // // ProcessImpl // ProcessImpl::PIDImpl ProcessImpl::idImpl() { - return GetCurrentProcessId(); + return GetCurrentProcessId(); } @@ -110,28 +122,28 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg { std::wstring ucommand; UnicodeConverter::toUTF16(command, ucommand); - + std::string commandLine; for (ArgsImpl::const_iterator it = args.begin(); it != args.end(); ++it) { if (it != args.begin()) commandLine.append(" "); commandLine.append(*it); - } + } std::wstring ucommandLine; UnicodeConverter::toUTF16(commandLine, ucommandLine); PROCESS_INFORMATION processInfo; BOOL rc = CreateProcessW( - ucommand.c_str(), - const_cast(ucommandLine.c_str()), - NULL, - NULL, - FALSE, - 0, - NULL, - NULL, - NULL/*&startupInfo*/, + ucommand.c_str(), + const_cast(ucommandLine.c_str()), + NULL, + NULL, + FALSE, + 0, + NULL, + NULL, + NULL/*&startupInfo*/, &processInfo ); @@ -146,7 +158,7 @@ ProcessHandleImpl* ProcessImpl::launchImpl(const std::string& command, const Arg void ProcessImpl::killImpl(ProcessHandleImpl& handle) { - if (handle.process()) + if (handle.process()) { if (TerminateProcess(handle.process(), 0) == 0) { @@ -176,7 +188,7 @@ void ProcessImpl::killImpl(PIDImpl pid) { case ERROR_ACCESS_DENIED: throw NoPermissionException("cannot kill process"); - case ERROR_NOT_FOUND: + case ERROR_NOT_FOUND: throw NotFoundException("cannot kill process"); default: throw SystemException("cannot kill process"); @@ -185,7 +197,7 @@ void ProcessImpl::killImpl(PIDImpl pid) } -bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle) +bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle) { bool result = true; DWORD exitCode; @@ -195,7 +207,7 @@ bool ProcessImpl::isRunningImpl(const ProcessHandleImpl& handle) } -bool ProcessImpl::isRunningImpl(PIDImpl pid) +bool ProcessImpl::isRunningImpl(PIDImpl pid) { HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); bool result = true; diff --git a/Foundation/src/UTF8String.cpp b/Foundation/src/UTF8String.cpp index e5020695a..d9336f3b2 100644 --- a/Foundation/src/UTF8String.cpp +++ b/Foundation/src/UTF8String.cpp @@ -32,11 +32,11 @@ namespace int UTF8::icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, std::string::const_iterator it2, std::string::const_iterator end2) -{ +{ std::string::size_type sz = str.size(); if (pos > sz) pos = sz; if (pos + n > sz) n = sz - pos; - TextIterator uit1(str.begin() + pos, str.begin() + pos + n, utf8); + TextIterator uit1(str.begin() + pos, str.begin() + pos + n, utf8); TextIterator uend1(str.begin() + pos + n); TextIterator uit2(it2, end2, utf8); TextIterator uend2(end2); @@ -50,7 +50,7 @@ int UTF8::icompare(const std::string& str, std::string::size_type pos, std::stri return 1; ++uit1; ++uit2; } - + if (uit1 == uend1) return uit2 == uend2 ? 0 : -1; else @@ -162,9 +162,9 @@ std::string& UTF8::toLowerInPlace(std::string& str) void UTF8::removeBOM(std::string& str) { - if (str.size() >= 3 - && static_cast(str[0]) == 0xEF - && static_cast(str[1]) == 0xBB + if (str.size() >= 3 + && static_cast(str[0]) == 0xEF + && static_cast(str[1]) == 0xBB && static_cast(str[2]) == 0xBF) { str.erase(0, 3); @@ -264,42 +264,74 @@ std::string UTF8::unescape(const std::string::const_iterator& begin, const std:: //Invalid sequence! } - if (*it == 'n') + switch (*it) + { + case 'U': + { + char digs[9]; + std::memset(digs, 0, 9); + unsigned int dno = 0; + + it++; + while (it != end && Ascii::isHexDigit(*it) && dno < 8) + { + digs[dno++] = *it++; + } + if (dno > 0) + { + ch = std::strtol(digs, NULL, 16); + } + break; + } + case '\\': + { + ch = '\\'; + it++; + break; + } + case 'n': { ch = '\n'; it++; + break; } - else if (*it == 't') + case 't': { ch = '\t'; it++; + break; } - else if (*it == 'r') + case 'r': { ch = '\r'; it++; + break; } - else if (*it == 'b') + case 'b': { ch = '\b'; it++; + break; } - else if (*it == 'f') + case 'f': { ch = '\f'; it++; + break; } - else if (*it == 'v') + case 'v': { ch = '\v'; it++; + break; } - else if (*it == 'a') + case 'a': { ch = '\a'; it++; + break; } - else if (*it == 'u') + case 'u': { char digs[5]; std::memset(digs, 0, 5); @@ -345,23 +377,14 @@ std::string UTF8::unescape(const std::string::const_iterator& begin, const std:: } } } + break; } - else if (*it == 'U') + default: { - char digs[9]; - std::memset(digs, 0, 9); - unsigned int dno = 0; - - it++; - while (it != end && Ascii::isHexDigit(*it) && dno < 8) - { - digs[dno++] = *it++; - } - if (dno > 0) - { - ch = std::strtol(digs, NULL, 16); - } + //Invalid sequence! + break; } + }//end switch } unsigned char utf8[4]; diff --git a/Foundation/src/UUIDGenerator.cpp b/Foundation/src/UUIDGenerator.cpp index 1ae72005a..e51add84f 100644 --- a/Foundation/src/UUIDGenerator.cpp +++ b/Foundation/src/UUIDGenerator.cpp @@ -90,7 +90,7 @@ UUID UUIDGenerator::createFromName(const UUID& nsid, const std::string& name, Di return UUID(buffer, version); } - + UUID UUIDGenerator::createRandom() { char buffer[16]; @@ -136,6 +136,22 @@ UUID UUIDGenerator::createOne() } +void UUIDGenerator::seed() +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + _random.seed(); +} + + +void UUIDGenerator::seed(UInt32 n) +{ + Poco::FastMutex::ScopedLock lock(_mutex); + + _random.seed(n); +} + + namespace { static SingletonHolder sh; diff --git a/Foundation/src/Var.cpp b/Foundation/src/Var.cpp index ed95c0696..4908d7ee4 100644 --- a/Foundation/src/Var.cpp +++ b/Foundation/src/Var.cpp @@ -34,7 +34,7 @@ Var::Var() Var::Var(const char* pVal) -#ifdef POCO_NO_SOO +#ifdef POCO_NO_SOO : _pHolder(new VarHolderImpl(pVal)) { } @@ -372,7 +372,7 @@ Var& Var::getAt(std::size_t n) } else if (!isString() && !isEmpty() && (n == 0)) return *this; - + throw RangeException("Index out of bounds."); } @@ -503,7 +503,7 @@ Var Var::parseObject(const std::string& val, std::string::size_type& pos) std::string key = parseString(val, pos); skipWhiteSpace(val, pos); if (val[pos] != ':') - throw DataFormatException("Incorrect object, must contain: key : value pairs"); + throw DataFormatException("Incorrect object, must contain: key : value pairs"); ++pos; // skip past : Var value = parse(val, pos); aStruct.insert(key, value); @@ -515,7 +515,7 @@ Var Var::parseObject(const std::string& val, std::string::size_type& pos) } } if (val[pos] != '}') - throw DataFormatException("Unterminated object"); + throw DataFormatException("Unterminated object"); ++pos; return aStruct; } @@ -538,7 +538,7 @@ Var Var::parseArray(const std::string& val, std::string::size_type& pos) } } if (val[pos] != ']') - throw DataFormatException("Unterminated array"); + throw DataFormatException("Unterminated array"); ++pos; return result; } @@ -554,8 +554,8 @@ std::string Var::parseString(const std::string& val, std::string::size_type& pos else { std::string result; - while (pos < val.size() - && !Poco::Ascii::isSpace(val[pos]) + while (pos < val.size() + && !Poco::Ascii::isSpace(val[pos]) && val[pos] != ',' && val[pos] != ']' && val[pos] != '}') @@ -582,31 +582,30 @@ std::string Var::parseJSONString(const std::string& val, std::string::size_type& ++pos; break; case '\\': - if (pos < val.size()) + if (pos < val.size() - 1) { ++pos; switch (val[pos]) { case 'b': result += '\b'; - break; + break; case 'f': result += '\f'; - break; + break; case 'n': result += '\n'; - break; + break; case 'r': result += '\r'; - break; + break; case 't': result += '\t'; - break; + break; default: result += val[pos]; break; } - break; } else { diff --git a/Foundation/testsuite/src/LogStreamTest.cpp b/Foundation/testsuite/src/LogStreamTest.cpp index 7fec5d0cb..3f9747784 100644 --- a/Foundation/testsuite/src/LogStreamTest.cpp +++ b/Foundation/testsuite/src/LogStreamTest.cpp @@ -38,7 +38,7 @@ void LogStreamTest::testLogStream() { AutoPtr pChannel = new TestChannel; Logger& root = Logger::root(); - root.setChannel(pChannel.get()); + root.setChannel(pChannel); LogStream ls(root); diff --git a/Foundation/testsuite/src/UTF8StringTest.cpp b/Foundation/testsuite/src/UTF8StringTest.cpp index 42a48fbcf..6799ff35d 100644 --- a/Foundation/testsuite/src/UTF8StringTest.cpp +++ b/Foundation/testsuite/src/UTF8StringTest.cpp @@ -96,9 +96,11 @@ void UTF8StringTest::testUnescape() { std::string s1("A \\t, a \\u000B, and an \\u0007 walk into a |, and the barman says \\u0402"); std::string s2("A \\t, a \\v, and an \\a walk into a |, and the barman says \\u0402"); + std::string s3("\\\\"); assertTrue (UTF8::unescape(s1) == "A \t, a \v, and an \a walk into a |, and the barman says \xD0\x82"); assertTrue (UTF8::unescape(s2) == "A \t, a \v, and an \a walk into a |, and the barman says \xD0\x82"); + assertTrue (UTF8::unescape(s3) == "\\"); } diff --git a/Foundation/testsuite/src/VarTest.cpp b/Foundation/testsuite/src/VarTest.cpp index f54989e5d..3fe0db8cf 100644 --- a/Foundation/testsuite/src/VarTest.cpp +++ b/Foundation/testsuite/src/VarTest.cpp @@ -2622,6 +2622,10 @@ void VarTest::testJSONDeserializeString() tst = "{ \"a\" : \"1\", \"b\" : \"2\"\n}"; a = Var::parse(tst); assertTrue (a.toString() == "{ \"a\" : \"1\", \"b\" : \"2\" }"); + + tst = "{ \"message\" : \"escape\\b\\f\\n\\r\\t\", \"path\" : \"\\/dev\\/null\" }"; + a = Var::parse(tst); + assertTrue(a.toString() == "{ \"message\" : \"escape\\b\\f\\n\\r\\t\", \"path\" : \"\\/dev\\/null\" }"); } diff --git a/JSON/include/Poco/JSON/Array.h b/JSON/include/Poco/JSON/Array.h index 507f2ead4..ac65b1313 100644 --- a/JSON/include/Poco/JSON/Array.h +++ b/JSON/include/Poco/JSON/Array.h @@ -73,16 +73,16 @@ public: Array(const Array& copy); /// Creates an Array by copying another one. - Array(Array&& other); + Array(Array&& other) noexcept; /// Move constructor - Array& operator=(Array&& other); - /// Move assignment operator. - - Array& operator=(const Array& other); + Array& operator = (const Array& other); /// Assignment operator. - virtual ~Array(); + Array& operator = (Array&& other) noexcept; + /// Move assignment operator. + + ~Array(); /// Destroys the Array. void setEscapeUnicode(bool escape = true); diff --git a/JSON/include/Poco/JSON/Object.h b/JSON/include/Poco/JSON/Object.h index 60837cf05..b733f828c 100644 --- a/JSON/include/Poco/JSON/Object.h +++ b/JSON/include/Poco/JSON/Object.h @@ -84,18 +84,18 @@ public: /// Struct is not copied to keep the operation as /// efficient as possible (when needed, it will be generated upon request). - Object(Object&& other); + Object(Object&& other) noexcept; /// Move constructor - Object &operator =(Object &&other); - // Move asignment operator - - virtual ~Object(); + ~Object(); /// Destroys the Object. - Object &operator =(const Object &other); + Object &operator = (const Object &other); // Assignment operator + Object &operator = (Object &&other) noexcept; + // Move asignment operator + void setEscapeUnicode(bool escape = true); /// Sets the flag for escaping unicode. diff --git a/JSON/src/Array.cpp b/JSON/src/Array.cpp index 9d07cb04a..67e43f218 100644 --- a/JSON/src/Array.cpp +++ b/JSON/src/Array.cpp @@ -25,46 +25,50 @@ namespace Poco { namespace JSON { -Array::Array(int options): _modified(false), +Array::Array(int options): + _modified(false), _escapeUnicode((options & Poco::JSON_ESCAPE_UNICODE) != 0) { } -Array::Array(const Array& other) : _values(other._values), +Array::Array(const Array& other) : + _values(other._values), _pArray(other._pArray), - _modified(other._modified) + _modified(other._modified), + _escapeUnicode(other._escapeUnicode) { } -Array &Array::operator=(const Array& other) +Array::Array(Array&& other) noexcept: + _values(std::move(other._values)), + _pArray(std::move(other._pArray)), + _modified(other._modified), + _escapeUnicode(other._escapeUnicode) +{ +} + + +Array& Array::operator = (const Array& other) { if (&other != this) { _values = other._values; _pArray = other._pArray; _modified = other._modified; + _escapeUnicode = other._escapeUnicode; } return *this; } -Array::Array(Array&& other): - _values(std::move(other._values)), - _pArray(!other._modified ? other._pArray : 0), - _modified(other._modified) -{ - _pArray = 0; -} - - -Array &Array::operator = (Array&& other) +Array& Array::operator = (Array&& other) noexcept { _values = std::move(other._values); - _pArray = other._pArray; - other._pArray = 0; + _pArray = std::move(other._pArray); _modified = other._modified; + _escapeUnicode = other._escapeUnicode; return *this; } diff --git a/JSON/src/Object.cpp b/JSON/src/Object.cpp index 48c391085..9ddbfc71d 100644 --- a/JSON/src/Object.cpp +++ b/JSON/src/Object.cpp @@ -42,29 +42,15 @@ Object::Object(const Object& other) : _values(other._values), } -Object::Object(Object&& other): +Object::Object(Object&& other) noexcept: _values(std::move(other._values)), _keys(std::move(other._keys)), _preserveInsOrder(other._preserveInsOrder), _escapeUnicode(other._escapeUnicode), - _pStruct(!other._modified ? other._pStruct : 0), + _pStruct(std::move(other._pStruct)), + _pOrdStruct(std::move(other._pOrdStruct)), _modified(other._modified) { - other.clear(); -} - - -Object &Object::operator = (Object&& other) -{ - _values = other._values; - _preserveInsOrder = other._preserveInsOrder; - syncKeys(other._keys); - _escapeUnicode = other._escapeUnicode; - _pStruct = !other._modified ? other._pStruct : 0; - _modified = other._modified; - other.clear(); - - return *this; } @@ -73,7 +59,7 @@ Object::~Object() } -Object &Object::operator= (const Object &other) +Object &Object::operator = (const Object &other) { if (&other != this) { @@ -88,6 +74,20 @@ Object &Object::operator= (const Object &other) } +Object& Object::operator = (Object&& other) noexcept +{ + _values = std::move(other._values); + _keys = std::move(other._keys); + _preserveInsOrder = other._preserveInsOrder; + _escapeUnicode = other._escapeUnicode; + _pStruct = std::move(other._pStruct); + _pOrdStruct = std::move(other._pOrdStruct); + _modified = other._modified; + + return *this; +} + + void Object::syncKeys(const KeyList& keys) { if(_preserveInsOrder) diff --git a/Net/src/HTMLForm.cpp b/Net/src/HTMLForm.cpp index 89c124811..0849f7662 100644 --- a/Net/src/HTMLForm.cpp +++ b/Net/src/HTMLForm.cpp @@ -435,7 +435,7 @@ void HTMLForm::writeMultipart(std::ostream& ostr) // count only, don't move stream position std::streamsize partlen = part.pSource->getContentLength(); if (partlen != PartSource::UNKNOWN_CONTENT_LENGTH) - pCountingOutputStream->addChars(static_cast(partlen)); + pCountingOutputStream->addChars(partlen); else pCountingOutputStream->setValid(false); } diff --git a/Net/src/HTTPClientSession.cpp b/Net/src/HTTPClientSession.cpp index 89d256558..d64c7aa22 100644 --- a/Net/src/HTTPClientSession.cpp +++ b/Net/src/HTTPClientSession.cpp @@ -310,7 +310,6 @@ std::istream& HTTPClientSession::receiveResponse(HTTPResponse& response) networkException()->rethrow(); else throw; - throw; } } while (response.getStatus() == HTTPResponse::HTTP_CONTINUE); diff --git a/Net/src/NetworkInterface.cpp b/Net/src/NetworkInterface.cpp index 568ec4ce7..8b9fbfad6 100644 --- a/Net/src/NetworkInterface.cpp +++ b/Net/src/NetworkInterface.cpp @@ -794,9 +794,9 @@ bool NetworkInterface::isUp() const NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6) { - if (requireIPv6) + if (requireIPv6) return forName(name, IPv6_ONLY); - else + else return forName(name, IPv4_OR_IPv6); } @@ -1067,7 +1067,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly) throw SystemException(format("An error occurred while trying to obtain list of network interfaces: [%s]", Error::getMessage(dwRetVal))); else break; - } + } while ((ERROR_BUFFER_OVERFLOW == dwRetVal) && (++iterations <= 2)); poco_assert (NO_ERROR == dwRetVal); @@ -1240,7 +1240,7 @@ NetworkInterface::Map NetworkInterface::map(bool ipOnly, bool upOnly) { ifIt->second.addAddress(address); } - } + } break; #if defined(POCO_HAVE_IPv6) case AF_INET6: @@ -1357,14 +1357,17 @@ NetworkInterface::Type fromNative(u_char nativeType) void setInterfaceParams(struct ifaddrs* iface, NetworkInterfaceImpl& impl) { - struct sockaddr_dl* sdl = (struct sockaddr_dl*) iface->ifa_addr; impl.setName(iface->ifa_name); impl.setDisplayName(iface->ifa_name); impl.setAdapterName(iface->ifa_name); impl.setPhyParams(); - impl.setMACAddress(LLADDR(sdl), sdl->sdl_alen); - impl.setType(fromNative(sdl->sdl_type)); + if (iface->ifa_addr->sa_family == AF_LINK) + { + struct sockaddr_dl* sdl = (struct sockaddr_dl*) iface->ifa_addr; + impl.setMACAddress(LLADDR(sdl), sdl->sdl_alen); + impl.setType(fromNative(sdl->sdl_type)); + } } @@ -1536,16 +1539,19 @@ void setInterfaceParams(struct ifaddrs* iface, NetworkInterfaceImpl& impl) impl.setPhyParams(); #ifndef POCO_NO_LINUX_IF_PACKET_H - struct sockaddr_ll* sdl = (struct sockaddr_ll*) iface->ifa_addr; - impl.setMACAddress(sdl->sll_addr, sdl->sll_halen); - impl.setType(fromNative(sdl->sll_hatype)); + if (iface->ifa_addr->sa_family == AF_PACKET) + { + struct sockaddr_ll* sdl = (struct sockaddr_ll*) iface->ifa_addr; + impl.setMACAddress(sdl->sll_addr, sdl->sll_halen); + impl.setType(fromNative(sdl->sll_hatype)); + } #else std::string ifPath("/sys/class/net/"); ifPath += iface->ifa_name; std::string addrPath(ifPath); addrPath += "/address"; - + std::ifstream addrStream(addrPath.c_str()); if (addrStream.good()) { @@ -1560,7 +1566,7 @@ void setInterfaceParams(struct ifaddrs* iface, NetworkInterfaceImpl& impl) impl.setMACAddress(&mac[0], mac.size()); addrStream.close(); } - + std::string typePath(ifPath); typePath += "/type"; std::ifstream typeStream(typePath.c_str()); diff --git a/NetSSL_OpenSSL/src/X509Certificate.cpp b/NetSSL_OpenSSL/src/X509Certificate.cpp index f6d3ba4c1..0d9458a74 100644 --- a/NetSSL_OpenSSL/src/X509Certificate.cpp +++ b/NetSSL_OpenSSL/src/X509Certificate.cpp @@ -33,7 +33,7 @@ namespace Net { X509Certificate::X509Certificate(std::istream& istr): Poco::Crypto::X509Certificate(istr) -{ +{ } @@ -91,7 +91,7 @@ X509Certificate& X509Certificate::operator = (const X509Certificate& cert) X509Certificate& X509Certificate::operator = (X509Certificate&& cert) noexcept { - Poco::Crypto::X509Certificate::operator = (cert); + Poco::Crypto::X509Certificate::operator = (std::move(cert)); return *this; } @@ -108,7 +108,7 @@ bool X509Certificate::verify(const std::string& hostName) const bool X509Certificate::verify(const Poco::Crypto::X509Certificate& certificate, const std::string& hostName) -{ +{ #if OPENSSL_VERSION_NUMBER < 0x10002000L std::string commonName; std::set dnsNames; diff --git a/PageCompiler/src/PageReader.h b/PageCompiler/src/PageReader.h index ac3cab913..8bfdaeb1e 100644 --- a/PageCompiler/src/PageReader.h +++ b/PageCompiler/src/PageReader.h @@ -84,7 +84,7 @@ private: const PageReader* _pParent; std::string _path; std::string _attrs; - int _line; + std::streamsize _line; bool _emitLineDirectives; }; diff --git a/Util/src/SystemConfiguration.cpp b/Util/src/SystemConfiguration.cpp index 8beecacef..19332f14c 100644 --- a/Util/src/SystemConfiguration.cpp +++ b/Util/src/SystemConfiguration.cpp @@ -123,7 +123,6 @@ bool SystemConfiguration::getRaw(const std::string& key, std::string& value) con { value = Path::dataHome(); } - else if (key == TEMPHOMEDIR) { value = Path::tempHome(); diff --git a/cppignore.win b/cppignore.win index fac514ff4..ecfca7e59 100644 --- a/cppignore.win +++ b/cppignore.win @@ -19,3 +19,4 @@ class CppUnit::TestCaller.testProperties class CppUnit::TestCaller.testServiceReturnsTrueIfStopped class CppUnit::TestCaller.testSendToReceiveFrom class CppUnit::TestCaller.testMTU +class CppUnit::TestCaller.testCachedSession