diff --git a/Foundation/Foundation_vs71.vcproj b/Foundation/Foundation_vs71.vcproj index fc7e742a1..063553cf7 100644 --- a/Foundation/Foundation_vs71.vcproj +++ b/Foundation/Foundation_vs71.vcproj @@ -944,6 +944,9 @@ + + @@ -1272,6 +1275,9 @@ + + @@ -1311,6 +1317,9 @@ + + diff --git a/Foundation/Foundation_vs80.vcproj b/Foundation/Foundation_vs80.vcproj index 542eb6fc8..c774fc72e 100644 --- a/Foundation/Foundation_vs80.vcproj +++ b/Foundation/Foundation_vs80.vcproj @@ -1275,6 +1275,10 @@ RelativePath=".\src\ActiveDispatcher.cpp" > + + @@ -1711,6 +1715,10 @@ RelativePath=".\include\Poco\Activity.h" > + + @@ -1763,6 +1771,10 @@ RelativePath=".\include\Poco\ScopedLock.h" > + + diff --git a/Foundation/Makefile b/Foundation/Makefile index ed3846975..24f6be6fa 100644 --- a/Foundation/Makefile +++ b/Foundation/Makefile @@ -1,7 +1,7 @@ # # Makefile # -# $Id: //poco/Main/Foundation/Makefile#40 $ +# $Id: //poco/Main/Foundation/Makefile#41 $ # # Makefile for Poco Foundation # @@ -20,7 +20,7 @@ objects = ArchiveStrategy ASCIIEncoding AsyncChannel Base64Decoder Base64Encoder NestedDiagnosticContext Notification NotificationCenter \ NotificationQueue NullStream NumberFormatter NumberParser AbstractObserver \ Path PatternFormatter Process PurgeStrategy RWLock Random RandomStream \ - RegularExpression RefCountedObject Runnable RotateStrategy \ + RegularExpression RefCountedObject Runnable RotateStrategy Condition \ SHA1Engine Semaphore SharedLibrary SimpleFileChannel \ SignalHandler SplitterChannel Stopwatch StreamChannel StreamConverter StreamCopier \ StreamTokenizer String StringTokenizer SynchronizedObject SyslogChannel \ diff --git a/Foundation/include/Poco/ASCIIEncoding.h b/Foundation/include/Poco/ASCIIEncoding.h index ba2a12545..cc1e186f5 100644 --- a/Foundation/include/Poco/ASCIIEncoding.h +++ b/Foundation/include/Poco/ASCIIEncoding.h @@ -1,7 +1,7 @@ // // ASCIIEncoding.h // -// $Id: //poco/Main/Foundation/include/Poco/ASCIIEncoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/ASCIIEncoding.h#3 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the ASCIIEncoding class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -53,11 +53,14 @@ class Foundation_API ASCIIEncoding: public TextEncoding public: ASCIIEncoding(); ~ASCIIEncoding(); + const char* canonicalName() const; + bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; int convert(const unsigned char* bytes) const; int convert(int ch, unsigned char* bytes, int length) const; private: + static const char* _names[]; static const CharacterMap _charMap; }; diff --git a/Foundation/include/Poco/Bugcheck.h b/Foundation/include/Poco/Bugcheck.h index bfd3521a5..fd8a6cd6f 100644 --- a/Foundation/include/Poco/Bugcheck.h +++ b/Foundation/include/Poco/Bugcheck.h @@ -1,7 +1,7 @@ // // Bugcheck.h // -// $Id: //poco/Main/Foundation/include/Poco/Bugcheck.h#3 $ +// $Id: //poco/Main/Foundation/include/Poco/Bugcheck.h#5 $ // // Library: Foundation // Package: Core @@ -86,6 +86,9 @@ protected: }; +} // namespace Poco + + // // useful macros (these automatically supply line number and file name) // @@ -121,7 +124,42 @@ protected: Poco::Bugcheck::debugger(msg, __FILE__, __LINE__) -} // namespace Poco +// +// poco_static_assert +// +// The following was ported from +// + + +template +struct POCO_STATIC_ASSERTION_FAILURE; + + +template <> +struct POCO_STATIC_ASSERTION_FAILURE +{ + enum + { + value = 1 + }; +}; + + +template +struct poco_static_assert_test +{ +}; + + +#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) +#define poco_static_assert(B) \ + typedef char POCO_JOIN(poco_static_assert_typedef_, __LINE__) \ + [POCO_STATIC_ASSERTION_FAILURE<(bool) (B)>::value] +#else +#define poco_static_assert(B) \ + typedef poco_static_assert_test)> \ + POCO_JOIN(poco_static_assert_typedef_, __LINE__) +#endif #endif // Foundation_Bugcheck_INCLUDED diff --git a/Foundation/include/Poco/ClassLibrary.h b/Foundation/include/Poco/ClassLibrary.h index 8d20d8927..e56b2571f 100644 --- a/Foundation/include/Poco/ClassLibrary.h +++ b/Foundation/include/Poco/ClassLibrary.h @@ -1,7 +1,7 @@ // // ClassLibrary.h // -// $Id: //poco/Main/Foundation/include/Poco/ClassLibrary.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/ClassLibrary.h#3 $ // // Library: Foundation // Package: SharedLibrary @@ -76,13 +76,13 @@ extern "C" // #define POCO_BEGIN_MANIFEST(base) \ bool pocoBuildManifest(Poco::ManifestBase* pManifest_) \ - { \ - typedef base _Base; \ - typedef Poco::Manifest<_Base> _Manifest; \ - std::string requiredType(typeid(_Manifest).name()); \ - std::string actualType(pManifest_->className()); \ - if (requiredType == actualType) \ - { \ + { \ + typedef base _Base; \ + typedef Poco::Manifest<_Base> _Manifest; \ + std::string requiredType(typeid(_Manifest).name()); \ + std::string actualType(pManifest_->className()); \ + if (requiredType == actualType) \ + { \ Poco::Manifest<_Base>* pManifest = static_cast<_Manifest*>(pManifest_); diff --git a/Foundation/include/Poco/Condition.h b/Foundation/include/Poco/Condition.h new file mode 100644 index 000000000..8fce80034 --- /dev/null +++ b/Foundation/include/Poco/Condition.h @@ -0,0 +1,159 @@ +// +// Condition.h +// +// $Id: //poco/Main/Foundation/include/Poco/Condition.h#1 $ +// +// Library: Foundation +// Package: Threading +// Module: Condition +// +// Definition of the Condition class template. +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_Condition_INCLUDED +#define Foundation_Condition_INCLUDED + + +#include "Poco/Foundation.h" +#include "Poco/Mutex.h" +#include "Poco/ScopedUnlock.h" +#include "Poco/Event.h" +#include "Poco/Exception.h" +#include + + +namespace Poco { + + +class Foundation_API Condition + /// A Condition is a synchronization object used to block a thread + /// until a particular condition is met. + /// A Condition object is always used in conjunction with + /// a Mutex (or FastMutex) object. + /// + /// Condition objects are similar to POSIX condition variables, which the + /// difference that Condition is not subject to spurious wakeups. + /// + /// Threads waiting on a Condition are resumed in FIFO order. +{ +public: + Condition(); + /// Creates the Condition. + + ~Condition(); + /// Destroys the Condition. + + template + void wait(Mtx& mutex) + /// Unlocks the mutex (which must be locked upon calling + /// wait()) and waits until the Condition is signalled. + /// + /// The given mutex will be locked again upon + /// leaving the function, even in case of an exception. + { + ScopedUnlock unlock(mutex, false); + Event event; + { + FastMutex::ScopedLock lock(_mutex); + mutex.unlock(); + enqueue(event); + } + event.wait(); + } + + template + void wait(Mtx& mutex, long milliseconds) + /// Unlocks the mutex (which must be locked upon calling + /// wait()) and waits for the given time until the Condition is signalled. + /// + /// The given mutex will be locked again upon successfully leaving the + /// function, even in case of an exception. + /// + /// Throws a TimeoutException if the Condition is not signalled + /// within the given time interval. + { + if (!tryWait(mutex, milliseconds)) + throw TimeoutException(); + } + + template + bool tryWait(Mtx& mutex, long milliseconds) + /// Unlocks the mutex (which must be locked upon calling + /// tryWait()) and waits for the given time until the Condition is signalled. + /// + /// The given mutex will be locked again upon leaving the + /// function, even in case of an exception. + /// + /// Returns true if the Condition has been signalled + /// within the given time interval, otherwise false. + { + ScopedUnlock unlock(mutex, false); + Event event; + { + FastMutex::ScopedLock lock(_mutex); + mutex.unlock(); + enqueue(event); + } + if (!event.tryWait(milliseconds)) + { + FastMutex::ScopedLock lock(_mutex); + dequeue(event); + return false; + } + return true; + } + + void signal(); + /// Signals the Condition and allows one waiting thread + /// to continue execution. + + void broadcast(); + /// Signals the Condition and allows all waiting + /// threads to continue their execution. + +protected: + void enqueue(Event& event); + void dequeue(); + void dequeue(Event& event); + +private: + Condition(const Condition&); + Condition& operator = (const Condition&); + + typedef std::deque WaitQueue; + + FastMutex _mutex; + WaitQueue _waitQueue; +}; + + +} // namespace Poco + + +#endif // Foundation_Condition_INCLUDED diff --git a/Foundation/include/Poco/DynamicAny.h b/Foundation/include/Poco/DynamicAny.h index 1a087e8bd..5687a0ad5 100644 --- a/Foundation/include/Poco/DynamicAny.h +++ b/Foundation/include/Poco/DynamicAny.h @@ -1,7 +1,7 @@ // // DynamicAny.h // -// $Id: //poco/Main/Foundation/include/Poco/DynamicAny.h#3 $ +// $Id: //poco/Main/Foundation/include/Poco/DynamicAny.h#4 $ // // Library: Poco // Package: Core @@ -61,7 +61,7 @@ class Foundation_API DynamicAny /// Precision loss, such as in conversion from floating-point types to integers or from double to float on platforms /// where they differ in size (provided internal actual value fits in float min/max range), is allowed. /// - /// String truncation is allowed - it is possible to convert between string and character when string length is + /// String truncation is allowed -- it is possible to convert between string and character when string length is /// greater than 1. An empty string gets converted to the char '\0', a non-empty string is truncated to the first character. /// /// Bolean conversion are performed as follows: @@ -99,23 +99,33 @@ public: template void convert(T& val) const - /// Invoke this method to perform conversion. + /// Invoke this method to perform a safe conversion. /// /// Example usage: /// DynamicAny any("42"); /// int i; /// any.convert(i); + /// + /// Throws a RangeException if the value does not fit + /// into the result variable. + /// Throws a NotImplementedException if conversion is + /// not available for the given type. { _pHolder->convert(val); } template T convert() const - /// Invoke this method to perform conversion. + /// Invoke this method to perform a safe conversion. /// /// Example usage: /// DynamicAny any("42"); /// int i = any.convert(); + /// + /// Throws a RangeException if the value does not fit + /// into the result variable. + /// Throws a NotImplementedException if conversion is + /// not available for the given type. { T result; _pHolder->convert(result); @@ -124,8 +134,13 @@ public: template operator T() const - /// Conversion operator for implicit type + /// Safe conversion operator for implicit type /// conversions. + /// + /// Throws a RangeException if the value does not fit + /// into the result variable. + /// Throws a NotImplementedException if conversion is + /// not available for the given type. { T result; _pHolder->convert(result); diff --git a/Foundation/include/Poco/DynamicAnyHolder.h b/Foundation/include/Poco/DynamicAnyHolder.h index a904deef0..384a0cfe7 100644 --- a/Foundation/include/Poco/DynamicAnyHolder.h +++ b/Foundation/include/Poco/DynamicAnyHolder.h @@ -1,7 +1,7 @@ // // DynamicAnyHolder.h // -// $Id: //poco/Main/Foundation/include/Poco/DynamicAnyHolder.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/DynamicAnyHolder.h#3 $ // // Library: Poco // Package: Core @@ -48,35 +48,6 @@ #include #include -///BEGIN ported from boost -/// following macros were ported from boost to help the DynamicAnyHolder development -/// for complete multi-platform code, see static_assert.hpp in boost libraries - -// Helper macro POCO_JOIN: -// The following piece of macro magic joins the two -// arguments together, even when one of the arguments is -// itself a macro (see 16.3.1 in C++ standard). The key -// is that macro expansion of macro arguments does not -// occur in POCO_DO_JOIN2 but does in POCO_DO_JOIN. -// -#define POCO_JOIN(X, Y) POCO_DO_JOIN( X, Y ) -#define POCO_DO_JOIN(X, Y) POCO_DO_JOIN2(X,Y) -#define POCO_DO_JOIN2(X, Y) X##Y - -template struct STATIC_ASSERTION_FAILURE; -template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; -template struct static_assert_test{}; - -#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) -# define poco_static_assert( B ) \ - typedef char POCO_JOIN(poco_static_assert_typedef_, __LINE__) \ - [ STATIC_ASSERTION_FAILURE< (bool)(B) >::value ] -#else -# define poco_static_assert(B) \ - typedef static_assert_test)> poco_static_assert_typedef_ -#endif -///END ported from boost - namespace Poco { @@ -203,7 +174,6 @@ private: if (from < std::numeric_limits::min()) throw RangeException("Value too small."); } - }; @@ -326,7 +296,6 @@ class DynamicAnyHolderImpl: public DynamicAnyHolder }; - template <> class DynamicAnyHolderImpl: public DynamicAnyHolder { @@ -419,7 +388,6 @@ private: }; - template <> class DynamicAnyHolderImpl: public DynamicAnyHolder { diff --git a/Foundation/include/Poco/Event.h b/Foundation/include/Poco/Event.h index cead694fc..77f9c0b9b 100644 --- a/Foundation/include/Poco/Event.h +++ b/Foundation/include/Poco/Event.h @@ -1,7 +1,7 @@ // // Event.h // -// $Id: //poco/Main/Foundation/include/Poco/Event.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Event.h#3 $ // // Library: Foundation // Package: Threading @@ -84,7 +84,7 @@ public: void wait(long milliseconds); /// Waits for the event to become signalled. - /// Throws a TimeOutException if the event + /// Throws a TimeoutException if the event /// does not become signalled within the specified /// time interval. diff --git a/Foundation/include/Poco/File.h b/Foundation/include/Poco/File.h index 2e8566259..3e6c4e25f 100644 --- a/Foundation/include/Poco/File.h +++ b/Foundation/include/Poco/File.h @@ -1,7 +1,7 @@ // // File.h // -// $Id: //poco/Main/Foundation/include/Poco/File.h#4 $ +// $Id: //poco/Main/Foundation/include/Poco/File.h#5 $ // // Library: Foundation // Package: Filesystem @@ -164,12 +164,14 @@ public: /// Does nothing on Windows and OpenVMS. void copyTo(const std::string& path) const; - /// Copies the file to the given path. The target path - /// can be a directory. + /// Copies the file (or directory) to the given path. + /// The target path can be a directory. + /// + /// A directory is copied recursively. void moveTo(const std::string& path); - /// Copies the file to the given path and removes the - /// original file. The target path can be a directory. + /// Copies the file (or directory) to the given path and + /// removes the original file. The target path can be a directory. void renameTo(const std::string& path); /// Renames the file to the new name. @@ -212,6 +214,10 @@ public: static void handleLastError(const std::string& path); /// For internal use only. Throws an appropriate /// exception for the last file-related error. + +protected: + void copyDirectory(const std::string& path) const; + /// Copies a directory. Used internally by copyTo(). }; diff --git a/Foundation/include/Poco/Foundation.h b/Foundation/include/Poco/Foundation.h index 6717c837a..e58cd3fb4 100644 --- a/Foundation/include/Poco/Foundation.h +++ b/Foundation/include/Poco/Foundation.h @@ -1,7 +1,7 @@ // // Foundation.h // -// $Id: //poco/Main/Foundation/include/Poco/Foundation.h#6 $ +// $Id: //poco/Main/Foundation/include/Poco/Foundation.h#7 $ // // Library: Foundation // Package: Core @@ -93,6 +93,20 @@ #endif +// +// POCO_JOIN +// +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in POCO_DO_JOIN2 but does in POCO_DO_JOIN. +// +#define POCO_JOIN(X, Y) POCO_DO_JOIN( X, Y ) +#define POCO_DO_JOIN(X, Y) POCO_DO_JOIN2(X,Y) +#define POCO_DO_JOIN2(X, Y) X##Y + + // // Pull in basic definitions // diff --git a/Foundation/include/Poco/Latin1Encoding.h b/Foundation/include/Poco/Latin1Encoding.h index 1d9a66c33..f7371767b 100644 --- a/Foundation/include/Poco/Latin1Encoding.h +++ b/Foundation/include/Poco/Latin1Encoding.h @@ -1,7 +1,7 @@ // // Latin1Encoding.h // -// $Id: //poco/Main/Foundation/include/Poco/Latin1Encoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Latin1Encoding.h#3 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the Latin1Encoding class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -53,11 +53,14 @@ class Foundation_API Latin1Encoding: public TextEncoding public: Latin1Encoding(); ~Latin1Encoding(); + const char* canonicalName() const; + bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; int convert(const unsigned char* bytes) const; int convert(int ch, unsigned char* bytes, int length) const; private: + static const char* _names[]; static const CharacterMap _charMap; }; diff --git a/Foundation/include/Poco/Latin9Encoding.h b/Foundation/include/Poco/Latin9Encoding.h index 363d67a65..41f0319c5 100644 --- a/Foundation/include/Poco/Latin9Encoding.h +++ b/Foundation/include/Poco/Latin9Encoding.h @@ -1,7 +1,7 @@ // // Latin9Encoding.h // -// $Id: //poco/Main/Foundation/include/Poco/Latin9Encoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Latin9Encoding.h#3 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the Latin9Encoding class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -56,11 +56,14 @@ class Foundation_API Latin9Encoding: public TextEncoding public: Latin9Encoding(); ~Latin9Encoding(); + const char* canonicalName() const; + bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; int convert(const unsigned char* bytes) const; int convert(int ch, unsigned char* bytes, int length) const; private: + static const char* _names[]; static const CharacterMap _charMap; }; diff --git a/Foundation/include/Poco/Path.h b/Foundation/include/Poco/Path.h index 26febb154..4aff08108 100644 --- a/Foundation/include/Poco/Path.h +++ b/Foundation/include/Poco/Path.h @@ -1,7 +1,7 @@ // // Path.h // -// $Id: //poco/Main/Foundation/include/Poco/Path.h#5 $ +// $Id: //poco/Main/Foundation/include/Poco/Path.h#6 $ // // Library: Foundation // Package: Filesystem @@ -96,6 +96,10 @@ public: /// Creates a path from a parent path and a filename. /// The parent path is expected to reference a directory. + Path(const Path& parent, const char* fileName); + /// Creates a path from a parent path and a filename. + /// The parent path is expected to reference a directory. + Path(const Path& parent, const Path& relative); /// Creates a path from a parent path and a relative path. /// The parent path is expected to reference a directory. diff --git a/Foundation/include/Poco/ScopedUnlock.h b/Foundation/include/Poco/ScopedUnlock.h new file mode 100644 index 000000000..8d1a5776a --- /dev/null +++ b/Foundation/include/Poco/ScopedUnlock.h @@ -0,0 +1,79 @@ +// +// ScopedUnlock.h +// +// $Id: //poco/Main/Foundation/include/Poco/ScopedUnlock.h#1 $ +// +// Library: Foundation +// Package: Threading +// Module: Mutex +// +// Definition of the ScopedUnlock template class. +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef Foundation_ScopedUnlock_INCLUDED +#define Foundation_ScopedUnlock_INCLUDED + + +#include "Poco/Foundation.h" + + +namespace Poco { + + +template +class ScopedUnlock + /// A class that simplifies thread synchronization + /// with a mutex. + /// The constructor accepts a Mutex and unlocks it. + /// The destructor unlocks the mutex. +{ +public: + inline ScopedUnlock(M& mutex, bool unlockNow = true): _mutex(mutex) + { + if (unlockNow) + _mutex.unlock(); + } + inline ~ScopedUnlock() + { + _mutex.lock(); + } + +private: + M& _mutex; + + ScopedUnlock(); + ScopedUnlock(const ScopedUnlock&); + ScopedUnlock& operator = (const ScopedUnlock&); +}; + + +} // namespace Poco + + +#endif // Foundation_ScopedUnlock_INCLUDED diff --git a/Foundation/include/Poco/Semaphore.h b/Foundation/include/Poco/Semaphore.h index 6b354b5d4..9843ab8e3 100644 --- a/Foundation/include/Poco/Semaphore.h +++ b/Foundation/include/Poco/Semaphore.h @@ -1,7 +1,7 @@ // // Semaphore.h // -// $Id: //poco/Main/Foundation/include/Poco/Semaphore.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Semaphore.h#3 $ // // Library: Foundation // Package: Threading @@ -100,7 +100,7 @@ public: /// Waits for the semaphore to become signalled. /// To become signalled, a semaphore's value must /// be greater than zero. - /// Throws a TimeOutException if the semaphore + /// Throws a TimeoutException if the semaphore /// does not become signalled within the specified /// time interval. /// Decrements the semaphore's value by one diff --git a/Foundation/include/Poco/String.h b/Foundation/include/Poco/String.h index 9825baa1b..a23eda7fa 100644 --- a/Foundation/include/Poco/String.h +++ b/Foundation/include/Poco/String.h @@ -1,7 +1,7 @@ // // String.h // -// $Id: //poco/Main/Foundation/include/Poco/String.h#5 $ +// $Id: //poco/Main/Foundation/include/Poco/String.h#6 $ // // Library: Foundation // Package: Core @@ -475,7 +475,7 @@ S& replaceInPlace(S& str, const typename S::value_type* from, const typename S:: S result; typename S::size_type pos = 0; - typename S::size_type fromLen = strlen(from); + typename S::size_type fromLen = std::strlen(from); result.append(str, 0, start); do { diff --git a/Foundation/include/Poco/SynchronizedObject.h b/Foundation/include/Poco/SynchronizedObject.h index c081029b5..422836d3c 100644 --- a/Foundation/include/Poco/SynchronizedObject.h +++ b/Foundation/include/Poco/SynchronizedObject.h @@ -1,7 +1,7 @@ // // SynchronizedObject.h // -// $Id: //poco/Main/Foundation/include/Poco/SynchronizedObject.h#3 $ +// $Id: //poco/Main/Foundation/include/Poco/SynchronizedObject.h#4 $ // // Library: Foundation // Package: Threading @@ -86,7 +86,7 @@ public: void wait(long milliseconds) const; /// Waits for the object to become signalled. - /// Throws a TimeOutException if the object + /// Throws a TimeoutException if the object /// does not become signalled within the specified /// time interval. diff --git a/Foundation/include/Poco/TextEncoding.h b/Foundation/include/Poco/TextEncoding.h index 362ed04b1..62590c725 100644 --- a/Foundation/include/Poco/TextEncoding.h +++ b/Foundation/include/Poco/TextEncoding.h @@ -1,7 +1,7 @@ // // TextEncoding.h // -// $Id: //poco/Main/Foundation/include/Poco/TextEncoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/TextEncoding.h#4 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the abstract TextEncoding class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -41,19 +41,30 @@ #include "Poco/Foundation.h" +#include "Poco/SharedPtr.h" namespace Poco { +class TextEncodingManager; + + class Foundation_API TextEncoding /// An abstract base class for implementing text encodings /// like UTF-8 or ISO 8859-1. /// - /// Subclasses must override the characterMap() and convert() - /// methods. + /// Subclasses must override the canonicalName(), isA(), + /// characterMap() and convert() methods and need to be + /// thread safe and stateless. + /// + /// TextEncoding also provides static member functions + /// for managing mappings from encoding names to + /// TextEncoding objects. { public: + typedef SharedPtr Ptr; + enum { MAX_SEQUENCE_LENGTH = 6 /// The maximum character byte sequence length supported. @@ -70,6 +81,17 @@ public: virtual ~TextEncoding(); /// Destroys the encoding. + + virtual const char* canonicalName() const = 0; + /// Returns the canonical name of this encoding, + /// e.g. "ISO-8859-1". Encoding name comparisons are case + /// insensitive. + + virtual bool isA(const std::string& encodingName) const = 0; + /// Returns true if the given name is one of the names of this encoding. + /// For example, the "ISO-8859-1" encoding is also known as "Latin-1". + /// + /// Encoding name comparision are be case insensitive. virtual const CharacterMap& characterMap() const = 0; /// Returns the CharacterMap for the encoding. @@ -97,6 +119,49 @@ public: /// If the character cannot be converted, 0 is returned and /// the byte sequence remains unchanged. /// The default implementation simply returns 0. + + static TextEncoding& byName(const std::string& encodingName); + /// Returns the TextEncoding object for the given encoding name. + /// + /// Throws a NotFoundException if the encoding with given name is not available. + + static TextEncoding::Ptr find(const std::string& encodingName); + /// Returns a pointer to the TextEncoding object for the given encodingName, + /// or NULL if no such TextEncoding object exists. + + static void add(TextEncoding::Ptr encoding); + /// Adds the given TextEncoding to the table of text encodings, + /// under the encoding's canonical name. + /// + /// If an encoding with the given name is already registered, + /// it is replaced. + + static void add(TextEncoding::Ptr encoding, const std::string& name); + /// Adds the given TextEncoding to the table of text encodings, + /// under the given name. + /// + /// If an encoding with the given name is already registered, + /// it is replaced. + + static void remove(const std::string& encodingName); + /// Removes the encoding with the given name from the table + /// of text encodings. + + static TextEncoding::Ptr global(TextEncoding::Ptr encoding); + /// Sets global TextEncoding object. + /// + /// This function sets the global encoding to the argument and returns a + /// reference of the previous global encoding. + + static TextEncoding& global(); + /// Return the current global TextEncoding object + + static const std::string GLOBAL; + /// Name of the global TextEncoding, which is the empty string. + +protected: + static TextEncodingManager& manager(); + /// Returns the TextEncodingManager. }; diff --git a/Foundation/include/Poco/Thread.h b/Foundation/include/Poco/Thread.h index 953dc57d4..23097d008 100644 --- a/Foundation/include/Poco/Thread.h +++ b/Foundation/include/Poco/Thread.h @@ -1,7 +1,7 @@ // // Thread.h // -// $Id: //poco/Main/Foundation/include/Poco/Thread.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Thread.h#3 $ // // Library: Foundation // Package: Threading @@ -107,6 +107,16 @@ public: /// Waits until the thread completes execution. /// If multiple threads try to join the same /// thread, the result is undefined. + + void join(long milliseconds); + /// Waits for at most the given interval for the thread + /// to complete. Throws a TimeoutException if the thread + /// does not complete within the specified time interval. + + bool tryJoin(long milliseconds); + /// Waits for at most the given interval for the thread + /// to complete. Returns true if the thread has finished, + /// false otherwise. bool isRunning() const; /// Returns true if the thread is running. diff --git a/Foundation/include/Poco/Thread_POSIX.h b/Foundation/include/Poco/Thread_POSIX.h index b8d5c212f..369130bee 100644 --- a/Foundation/include/Poco/Thread_POSIX.h +++ b/Foundation/include/Poco/Thread_POSIX.h @@ -1,7 +1,7 @@ // // Thread_POSIX.h // -// $Id: //poco/Main/Foundation/include/Poco/Thread_POSIX.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Thread_POSIX.h#5 $ // // Library: Foundation // Package: Threading @@ -9,7 +9,7 @@ // // Definition of the ThreadImpl class for POSIX Threads. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -43,6 +43,9 @@ #include "Poco/Foundation.h" #include "Poco/Runnable.h" #include "Poco/SignalHandler.h" +#include "Poco/Event.h" +#include "Poco/RefCountedObject.h" +#include "Poco/AutoPtr.h" #include #if !defined(POCO_NO_SYS_SELECT_H) #include @@ -74,6 +77,7 @@ public: void startImpl(Runnable& target); void joinImpl(); + bool joinImpl(long milliseconds); bool isRunningImpl() const; static void sleepImpl(long milliseconds); static void yieldImpl(); @@ -84,9 +88,23 @@ protected: static int mapPrio(int prio); private: - Runnable* _pTarget; - pthread_t _thread; - int _prio; + struct ThreadData: public RefCountedObject + { + ThreadData(): + pTarget(0), + thread(0), + prio(PRIO_NORMAL_IMPL), + done(false) + { + } + + Runnable* pTarget; + pthread_t thread; + int prio; + Event done; + }; + + AutoPtr _pData; static pthread_key_t _currentKey; static bool _haveCurrentKey; @@ -103,7 +121,7 @@ private: // inline int ThreadImpl::getPriorityImpl() const { - return _prio; + return _pData->prio; } diff --git a/Foundation/include/Poco/Thread_WIN32.h b/Foundation/include/Poco/Thread_WIN32.h index abffe2e09..eff9ce0e1 100644 --- a/Foundation/include/Poco/Thread_WIN32.h +++ b/Foundation/include/Poco/Thread_WIN32.h @@ -1,7 +1,7 @@ // // Thread_WIN32.h // -// $Id: //poco/Main/Foundation/include/Poco/Thread_WIN32.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Thread_WIN32.h#3 $ // // Library: Foundation // Package: Threading @@ -68,6 +68,7 @@ public: void startImpl(Runnable& target); void joinImpl(); + bool joinImpl(long milliseconds); bool isRunningImpl() const; static void sleepImpl(long milliseconds); static void yieldImpl(); diff --git a/Foundation/include/Poco/UTF16Encoding.h b/Foundation/include/Poco/UTF16Encoding.h index 40467763e..8284ab684 100644 --- a/Foundation/include/Poco/UTF16Encoding.h +++ b/Foundation/include/Poco/UTF16Encoding.h @@ -1,7 +1,7 @@ // // UTF16Encoding.h // -// $Id: //poco/Main/Foundation/include/Poco/UTF16Encoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/UTF16Encoding.h#3 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the UTF16Encoding class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -86,12 +86,15 @@ public: /// byte order mark, which is the Unicode /// character 0xFEFF. + const char* canonicalName() const; + bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; int convert(const unsigned char* bytes) const; int convert(int ch, unsigned char* bytes, int length) const; private: bool _flipBytes; + static const char* _names[]; static const CharacterMap _charMap; }; diff --git a/Foundation/include/Poco/UTF8Encoding.h b/Foundation/include/Poco/UTF8Encoding.h index 56351ccec..be00dc18c 100644 --- a/Foundation/include/Poco/UTF8Encoding.h +++ b/Foundation/include/Poco/UTF8Encoding.h @@ -1,7 +1,7 @@ // // UTF8Encoding.h // -// $Id: //poco/Main/Foundation/include/Poco/UTF8Encoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/UTF8Encoding.h#3 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the UTF8Encoding class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -53,11 +53,14 @@ class Foundation_API UTF8Encoding: public TextEncoding public: UTF8Encoding(); ~UTF8Encoding(); + const char* canonicalName() const; + bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; int convert(const unsigned char* bytes) const; int convert(int ch, unsigned char* bytes, int length) const; private: + static const char* _names[]; static const CharacterMap _charMap; }; diff --git a/Foundation/include/Poco/Windows1252Encoding.h b/Foundation/include/Poco/Windows1252Encoding.h index dac3ee240..70ec00669 100644 --- a/Foundation/include/Poco/Windows1252Encoding.h +++ b/Foundation/include/Poco/Windows1252Encoding.h @@ -1,7 +1,7 @@ // // Windows1252Encoding.h // -// $Id: //poco/Main/Foundation/include/Poco/Windows1252Encoding.h#2 $ +// $Id: //poco/Main/Foundation/include/Poco/Windows1252Encoding.h#3 $ // // Library: Foundation // Package: Text @@ -9,7 +9,7 @@ // // Definition of the Windows1252Encoding class. // -// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2005-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -53,11 +53,14 @@ class Foundation_API Windows1252Encoding: public TextEncoding public: Windows1252Encoding(); ~Windows1252Encoding(); + const char* canonicalName() const; + bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; int convert(const unsigned char* bytes) const; int convert(int ch, unsigned char* bytes, int length) const; private: + static const char* _names[]; static const CharacterMap _charMap; }; diff --git a/Foundation/src/ASCIIEncoding.cpp b/Foundation/src/ASCIIEncoding.cpp index 55294116a..83fd6115a 100644 --- a/Foundation/src/ASCIIEncoding.cpp +++ b/Foundation/src/ASCIIEncoding.cpp @@ -1,13 +1,13 @@ // // ASCIIEncoding.cpp // -// $Id: //poco/Main/Foundation/src/ASCIIEncoding.cpp#11 $ +// $Id: //poco/Main/Foundation/src/ASCIIEncoding.cpp#12 $ // // Library: Foundation // Package: Text // Module: ASCIIEncoding // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -35,11 +35,19 @@ #include "Poco/ASCIIEncoding.h" +#include "Poco/String.h" namespace Poco { +const char* ASCIIEncoding::_names[] = +{ + "ASCII", + NULL +}; + + const TextEncoding::CharacterMap ASCIIEncoding::_charMap = { /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -71,6 +79,23 @@ ASCIIEncoding::~ASCIIEncoding() } +const char* ASCIIEncoding::canonicalName() const +{ + return _names[0]; +} + + +bool ASCIIEncoding::isA(const std::string& encodingName) const +{ + for (const char** name = _names; *name; ++name) + { + if (Poco::icompare(encodingName, *name) == 0) + return true; + } + return false; +} + + const TextEncoding::CharacterMap& ASCIIEncoding::characterMap() const { return _charMap; diff --git a/Foundation/src/Condition.cpp b/Foundation/src/Condition.cpp new file mode 100644 index 000000000..0bf10fd84 --- /dev/null +++ b/Foundation/src/Condition.cpp @@ -0,0 +1,101 @@ +// +// Condition.cpp +// +// $Id: //poco/Main/Foundation/src/Condition.cpp#1 $ +// +// Library: Foundation +// Package: Threading +// Module: Condition +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Condition.h" + + +namespace Poco { + + +Condition::Condition() +{ +} + +Condition::~Condition() +{ +} + + +void Condition::signal() +{ + FastMutex::ScopedLock lock(_mutex); + + if (!_waitQueue.empty()) + { + _waitQueue.front()->set(); + dequeue(); + } +} + + +void Condition::broadcast() +{ + FastMutex::ScopedLock lock(_mutex); + + for (WaitQueue::iterator it = _waitQueue.begin(); it != _waitQueue.end(); ++it) + { + (*it)->set(); + } + _waitQueue.clear(); +} + + +void Condition::enqueue(Event& event) +{ + _waitQueue.push_back(&event); +} + + +void Condition::dequeue() +{ + _waitQueue.pop_front(); +} + + +void Condition::dequeue(Event& event) +{ + for (WaitQueue::iterator it = _waitQueue.begin(); it != _waitQueue.end(); ++it) + { + if (*it == &event) + { + _waitQueue.erase(it); + break; + } + } +} + + +} // namespace Poco diff --git a/Foundation/src/File.cpp b/Foundation/src/File.cpp index 4c33711e8..7e329292a 100644 --- a/Foundation/src/File.cpp +++ b/Foundation/src/File.cpp @@ -1,7 +1,7 @@ // // File.cpp // -// $Id: //poco/Main/Foundation/src/File.cpp#17 $ +// $Id: //poco/Main/Foundation/src/File.cpp#19 $ // // Library: Foundation // Package: Filesystem @@ -211,24 +211,40 @@ void File::setExecutable(bool flag) void File::copyTo(const std::string& path) const { Path src(getPathImpl()); - File srcFile(src); - if (srcFile.isDirectory()) - throw OpenFileException("cannot copy directory", src.toString()); - Path dest(path); - if (dest.isDirectory()) + File destFile(path); + if (destFile.exists() && destFile.isDirectory() || dest.isDirectory()) { dest.makeDirectory(); dest.setFileName(src.getFileName()); } - copyToImpl(dest.toString()); + if (isDirectory()) + copyDirectory(dest.toString()); + else + copyToImpl(dest.toString()); +} + + +void File::copyDirectory(const std::string& path) const +{ + File target(path); + target.createDirectories(); + + Path src(getPathImpl()); + src.makeFile(); + DirectoryIterator it(src); + DirectoryIterator end; + for (; it != end; ++it) + { + it->copyTo(path); + } } void File::moveTo(const std::string& path) { - copyToImpl(path); - removeImpl(); + copyTo(path); + remove(true); setPathImpl(path); } diff --git a/Foundation/src/File_WIN32.cpp b/Foundation/src/File_WIN32.cpp index 8d2946524..509772808 100644 --- a/Foundation/src/File_WIN32.cpp +++ b/Foundation/src/File_WIN32.cpp @@ -1,7 +1,7 @@ // // File_WIN32.cpp // -// $Id: //poco/Main/Foundation/src/File_WIN32.cpp#16 $ +// $Id: //poco/Main/Foundation/src/File_WIN32.cpp#17 $ // // Library: Foundation // Package: Filesystem @@ -319,7 +319,7 @@ bool FileImpl::createFileImpl() poco_assert (!_path.empty()); HANDLE hFile = CreateFile(_path.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0); - if (hFile) + if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); return true; diff --git a/Foundation/src/File_WIN32U.cpp b/Foundation/src/File_WIN32U.cpp index 0755aeb6e..b4bb94040 100644 --- a/Foundation/src/File_WIN32U.cpp +++ b/Foundation/src/File_WIN32U.cpp @@ -1,7 +1,7 @@ // // File_WIN32U.cpp // -// $Id: //poco/Main/Foundation/src/File_WIN32U.cpp#10 $ +// $Id: //poco/Main/Foundation/src/File_WIN32U.cpp#11 $ // // Library: Foundation // Package: Filesystem @@ -327,7 +327,7 @@ bool FileImpl::createFileImpl() poco_assert (!_path.empty()); HANDLE hFile = CreateFileW(_upath.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0); - if (hFile) + if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); return true; diff --git a/Foundation/src/Latin1Encoding.cpp b/Foundation/src/Latin1Encoding.cpp index 0708ebd58..4d615fa99 100644 --- a/Foundation/src/Latin1Encoding.cpp +++ b/Foundation/src/Latin1Encoding.cpp @@ -1,13 +1,13 @@ // // Latin1Encoding.cpp // -// $Id: //poco/Main/Foundation/src/Latin1Encoding.cpp#11 $ +// $Id: //poco/Main/Foundation/src/Latin1Encoding.cpp#12 $ // // Library: Foundation // Package: Text // Module: Latin1Encoding // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -35,11 +35,21 @@ #include "Poco/Latin1Encoding.h" +#include "Poco/String.h" namespace Poco { +const char* Latin1Encoding::_names[] = +{ + "ISO-8859-1", + "Latin1", + "Latin-1", + NULL +}; + + const TextEncoding::CharacterMap Latin1Encoding::_charMap = { /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -71,6 +81,23 @@ Latin1Encoding::~Latin1Encoding() } +const char* Latin1Encoding::canonicalName() const +{ + return _names[0]; +} + + +bool Latin1Encoding::isA(const std::string& encodingName) const +{ + for (const char** name = _names; *name; ++name) + { + if (Poco::icompare(encodingName, *name) == 0) + return true; + } + return false; +} + + const TextEncoding::CharacterMap& Latin1Encoding::characterMap() const { return _charMap; diff --git a/Foundation/src/Latin9Encoding.cpp b/Foundation/src/Latin9Encoding.cpp index 69d2c578e..0bd574a6c 100644 --- a/Foundation/src/Latin9Encoding.cpp +++ b/Foundation/src/Latin9Encoding.cpp @@ -1,13 +1,13 @@ // // Latin9Encoding.cpp // -// $Id: //poco/Main/Foundation/src/Latin9Encoding.cpp#11 $ +// $Id: //poco/Main/Foundation/src/Latin9Encoding.cpp#12 $ // // Library: Foundation // Package: Text // Module: Latin9Encoding // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -35,11 +35,21 @@ #include "Poco/Latin9Encoding.h" +#include "Poco/String.h" namespace Poco { +const char* Latin9Encoding::_names[] = +{ + "ISO-8859-15", + "Latin9", + "Latin-9", + NULL +}; + + const TextEncoding::CharacterMap Latin9Encoding::_charMap = { /* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, @@ -71,6 +81,23 @@ Latin9Encoding::~Latin9Encoding() } +const char* Latin9Encoding::canonicalName() const +{ + return _names[0]; +} + + +bool Latin9Encoding::isA(const std::string& encodingName) const +{ + for (const char** name = _names; *name; ++name) + { + if (Poco::icompare(encodingName, *name) == 0) + return true; + } + return false; +} + + const TextEncoding::CharacterMap& Latin9Encoding::characterMap() const { return _charMap; diff --git a/Foundation/src/Path.cpp b/Foundation/src/Path.cpp index 4a129affa..15ca937aa 100644 --- a/Foundation/src/Path.cpp +++ b/Foundation/src/Path.cpp @@ -1,7 +1,7 @@ // // Path.cpp // -// $Id: //poco/Main/Foundation/src/Path.cpp#20 $ +// $Id: //poco/Main/Foundation/src/Path.cpp#21 $ // // Library: Foundation // Package: Filesystem @@ -119,6 +119,19 @@ Path::Path(const Path& parent, const std::string& fileName): } +Path::Path(const Path& parent, const char* fileName): + _node(parent._node), + _device(parent._device), + _name(parent._name), + _version(parent._version), + _dirs(parent._dirs), + _absolute(parent._absolute) +{ + makeDirectory(); + _name = fileName; +} + + Path::Path(const Path& parent, const Path& relative): _node(parent._node), _device(parent._device), diff --git a/Foundation/src/SharedMemory.cpp b/Foundation/src/SharedMemory.cpp index e1e4e6f35..849e404ff 100644 --- a/Foundation/src/SharedMemory.cpp +++ b/Foundation/src/SharedMemory.cpp @@ -1,7 +1,7 @@ // // SharedMemory.cpp // -// $Id: //poco/Main/Foundation/src/SharedMemory.cpp#4 $ +// $Id: //poco/Main/Foundation/src/SharedMemory.cpp#5 $ // // Library: Poco // Package: Processes @@ -34,6 +34,12 @@ // +#if POCO_OS == POCO_OS_SOLARIS +#undef _XOPEN_SOURCE +#define _XOPEN_SOURCE 500 +#endif + + #include "Poco/SharedMemory.h" #include "Poco/Exception.h" #if defined(POCO_OS_FAMILY_WINDOWS) diff --git a/Foundation/src/TextEncoding.cpp b/Foundation/src/TextEncoding.cpp index ffba2296b..8d297f081 100644 --- a/Foundation/src/TextEncoding.cpp +++ b/Foundation/src/TextEncoding.cpp @@ -1,7 +1,7 @@ // // TextEncoding.cpp // -// $Id: //poco/Main/Foundation/src/TextEncoding.cpp#10 $ +// $Id: //poco/Main/Foundation/src/TextEncoding.cpp#13 $ // // Library: Foundation // Package: Text @@ -35,16 +35,114 @@ #include "Poco/TextEncoding.h" +#include "Poco/Exception.h" +#include "Poco/String.h" +#include "Poco/ASCIIEncoding.h" +#include "Poco/Latin1Encoding.h" +#include "Poco/Latin9Encoding.h" +#include "Poco/UTF16Encoding.h" +#include "Poco/UTF8Encoding.h" +#include "Poco/Windows1252Encoding.h" +#include "Poco/RWLock.h" +#include "Poco/SingletonHolder.h" +#include namespace Poco { +// +// TextEncodingManager +// + + +class TextEncodingManager +{ +public: + TextEncodingManager() + { + TextEncoding::Ptr pUtf8Encoding(new UTF8Encoding); + add(pUtf8Encoding, TextEncoding::GLOBAL); + + add(new ASCIIEncoding); + add(new Latin1Encoding); + add(new Latin9Encoding); + add(pUtf8Encoding); + add(new UTF16Encoding); + add(new Windows1252Encoding); + } + + ~TextEncodingManager() + { + } + + void add(TextEncoding::Ptr pEncoding) + { + add(pEncoding, pEncoding->canonicalName()); + } + + void add(TextEncoding::Ptr pEncoding, const std::string& name) + { + RWLock::ScopedLock lock(_lock, true); + + _encodings[name] = pEncoding; + } + + void remove(const std::string& name) + { + RWLock::ScopedLock lock(_lock, true); + + _encodings.erase(name); + } + + TextEncoding::Ptr find(const std::string& name) const + { + RWLock::ScopedLock lock(_lock); + + EncodingMap::const_iterator it = _encodings.find(name); + if (it != _encodings.end()) + return it->second; + + for (it = _encodings.begin(); it != _encodings.end(); ++it) + { + if (it->second->isA(name)) + return it->second; + } + return TextEncoding::Ptr(); + } + +private: + TextEncodingManager(const TextEncodingManager&); + TextEncodingManager& operator = (const TextEncodingManager&); + + struct ILT + { + bool operator() (const std::string& s1, const std::string& s2) const + { + return Poco::icompare(s1, s2) < 0; + } + }; + + typedef std::map EncodingMap; + + EncodingMap _encodings; + mutable RWLock _lock; +}; + + +// +// TextEncoding +// + + +const std::string TextEncoding::GLOBAL; + + TextEncoding::~TextEncoding() { } - + int TextEncoding::convert(const unsigned char* bytes) const { return (int) *bytes; @@ -57,5 +155,59 @@ int TextEncoding::convert(int ch, unsigned char* bytes, int length) const } -} // namespace Poco +TextEncoding& TextEncoding::byName(const std::string& encodingName) +{ + TextEncoding* pEncoding = manager().find(encodingName); + if (pEncoding) + return *pEncoding; + else + throw NotFoundException(encodingName); +} + +TextEncoding::Ptr TextEncoding::find(const std::string& encodingName) +{ + return manager().find(encodingName); +} + + +void TextEncoding::add(TextEncoding::Ptr pEncoding) +{ + manager().add(pEncoding, pEncoding->canonicalName()); +} + + +void TextEncoding::add(TextEncoding::Ptr pEncoding, const std::string& name) +{ + manager().add(pEncoding, name); +} + + +void TextEncoding::remove(const std::string& encodingName) +{ + manager().remove(encodingName); +} + + +TextEncoding::Ptr TextEncoding::global(TextEncoding::Ptr encoding) +{ + TextEncoding::Ptr prev = find(GLOBAL); + add(encoding, GLOBAL); + return prev; +} + + +TextEncoding& TextEncoding::global() +{ + return byName(GLOBAL); +} + + +TextEncodingManager& TextEncoding::manager() +{ + static SingletonHolder sh; + return *sh.get(); +} + + +} // namespace Poco diff --git a/Foundation/src/Thread.cpp b/Foundation/src/Thread.cpp index 3a8df3447..b9f30a0cd 100644 --- a/Foundation/src/Thread.cpp +++ b/Foundation/src/Thread.cpp @@ -1,7 +1,7 @@ // // Thread.cpp // -// $Id: //poco/Main/Foundation/src/Thread.cpp#12 $ +// $Id: //poco/Main/Foundation/src/Thread.cpp#13 $ // // Library: Foundation // Package: Threading @@ -97,6 +97,19 @@ void Thread::join() } +void Thread::join(long milliseconds) +{ + if (!joinImpl(milliseconds)) + throw TimeoutException(); +} + + +bool Thread::tryJoin(long milliseconds) +{ + return joinImpl(milliseconds); +} + + ThreadLocalStorage& Thread::tls() { if (!_pTLS) diff --git a/Foundation/src/Thread_POSIX.cpp b/Foundation/src/Thread_POSIX.cpp index 2be3841a3..4c5af6071 100644 --- a/Foundation/src/Thread_POSIX.cpp +++ b/Foundation/src/Thread_POSIX.cpp @@ -1,13 +1,13 @@ // // Thread_POSIX.cpp // -// $Id: //poco/Main/Foundation/src/Thread_POSIX.cpp#13 $ +// $Id: //poco/Main/Foundation/src/Thread_POSIX.cpp#15 $ // // Library: Foundation // Package: Threading // Module: Thread // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -73,10 +73,8 @@ pthread_key_t ThreadImpl::_currentKey; bool ThreadImpl::_haveCurrentKey = false; -ThreadImpl::ThreadImpl(): - _pTarget(0), - _thread(0), - _prio(PRIO_NORMAL_IMPL) +ThreadImpl::ThreadImpl(): + _pData(new ThreadData) { if (!_haveCurrentKey) { @@ -89,21 +87,21 @@ ThreadImpl::ThreadImpl(): ThreadImpl::~ThreadImpl() { - if (_pTarget) - pthread_detach(_thread); + if (_pData->pTarget) + pthread_detach(_pData->thread); } void ThreadImpl::setPriorityImpl(int prio) { - if (prio != _prio) + if (prio != _pData->prio) { - _prio = prio; - if (_pTarget) + _pData->prio = prio; + if (_pData->pTarget) { struct sched_param par; - par.sched_priority = mapPrio(_prio); - if (pthread_setschedparam(_thread, SCHED_OTHER, &par)) + par.sched_priority = mapPrio(_pData->prio); + if (pthread_setschedparam(_pData->thread, SCHED_OTHER, &par)) throw SystemException("cannot set thread priority"); } } @@ -112,20 +110,20 @@ void ThreadImpl::setPriorityImpl(int prio) void ThreadImpl::startImpl(Runnable& target) { - if (_pTarget) throw SystemException("thread already running"); + if (_pData->pTarget) throw SystemException("thread already running"); - _pTarget = ⌖ - if (pthread_create(&_thread, NULL, entry, this)) + _pData->pTarget = ⌖ + if (pthread_create(&_pData->thread, NULL, entry, this)) { - _pTarget = 0; + _pData->pTarget = 0; throw SystemException("cannot start thread"); } - if (_prio != PRIO_NORMAL_IMPL) + if (_pData->prio != PRIO_NORMAL_IMPL) { struct sched_param par; - par.sched_priority = mapPrio(_prio); - if (pthread_setschedparam(_thread, SCHED_OTHER, &par)) + par.sched_priority = mapPrio(_pData->prio); + if (pthread_setschedparam(_pData->thread, SCHED_OTHER, &par)) throw SystemException("cannot set thread priority"); } } @@ -133,24 +131,36 @@ void ThreadImpl::startImpl(Runnable& target) void ThreadImpl::joinImpl() { - if (!_pTarget) return; + _pData->done.wait(); void* result; - if (pthread_join(_thread, &result)) + if (pthread_join(_pData->thread, &result)) throw SystemException("cannot join thread"); - _pTarget = 0; +} + + +bool ThreadImpl::joinImpl(long milliseconds) +{ + if (_pData->done.tryWait(milliseconds)) + { + void* result; + if (pthread_join(_pData->thread, &result)) + throw SystemException("cannot join thread"); + return true; + } + else return false; } bool ThreadImpl::isRunningImpl() const { - return _pTarget != 0; + return _pData->pTarget != 0; } ThreadImpl* ThreadImpl::currentImpl() { if (_haveCurrentKey) - return (ThreadImpl*) pthread_getspecific(_currentKey); + return reinterpret_cast(pthread_getspecific(_currentKey)); else return 0; } @@ -169,9 +179,11 @@ void* ThreadImpl::entry(void* pThread) pthread_sigmask(SIG_BLOCK, &sset, 0); #endif + ThreadImpl* pThreadImpl = reinterpret_cast(pThread); + AutoPtr pData = pThreadImpl->_pData; try { - reinterpret_cast(pThread)->_pTarget->run(); + pData->pTarget->run(); } catch (Exception& exc) { @@ -185,6 +197,8 @@ void* ThreadImpl::entry(void* pThread) { ErrorHandler::handle(); } + pData->pTarget = 0; + pData->done.set(); return 0; } diff --git a/Foundation/src/Thread_WIN32.cpp b/Foundation/src/Thread_WIN32.cpp index 4e4b06459..87767df89 100644 --- a/Foundation/src/Thread_WIN32.cpp +++ b/Foundation/src/Thread_WIN32.cpp @@ -1,7 +1,7 @@ // // Thread_WIN32.h // -// $Id: //poco/Main/Foundation/src/Thread_WIN32.cpp#12 $ +// $Id: //poco/Main/Foundation/src/Thread_WIN32.cpp#13 $ // // Library: Foundation // Package: Threading @@ -110,6 +110,22 @@ void ThreadImpl::joinImpl() } +bool ThreadImpl::joinImpl(long milliseconds) +{ + if (!_thread) return true; + + switch (WaitForSingleObject(_thread, milliseconds + 1)) + { + case WAIT_TIMEOUT: + return false; + case WAIT_OBJECT_0: + return true; + default: + throw SystemException("cannot join thread"); + } +} + + bool ThreadImpl::isRunningImpl() const { if (_thread) diff --git a/Foundation/src/UTF16Encoding.cpp b/Foundation/src/UTF16Encoding.cpp index c2828add8..a3b3303dd 100644 --- a/Foundation/src/UTF16Encoding.cpp +++ b/Foundation/src/UTF16Encoding.cpp @@ -1,13 +1,13 @@ // // UTF16Encoding.cpp // -// $Id: //poco/Main/Foundation/src/UTF16Encoding.cpp#12 $ +// $Id: //poco/Main/Foundation/src/UTF16Encoding.cpp#13 $ // // Library: Foundation // Package: Text // Module: UTF16Encoding // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -36,11 +36,20 @@ #include "Poco/UTF16Encoding.h" #include "Poco/ByteOrder.h" +#include "Poco/String.h" namespace Poco { +const char* UTF16Encoding::_names[] = +{ + "UTF-16", + "UTF16", + NULL +}; + + const TextEncoding::CharacterMap UTF16Encoding::_charMap = { /* 00 */ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, @@ -105,6 +114,23 @@ void UTF16Encoding::setByteOrder(int byteOrderMark) } +const char* UTF16Encoding::canonicalName() const +{ + return _names[0]; +} + + +bool UTF16Encoding::isA(const std::string& encodingName) const +{ + for (const char** name = _names; *name; ++name) + { + if (Poco::icompare(encodingName, *name) == 0) + return true; + } + return false; +} + + const TextEncoding::CharacterMap& UTF16Encoding::characterMap() const { return _charMap; diff --git a/Foundation/src/UTF8Encoding.cpp b/Foundation/src/UTF8Encoding.cpp index 9eee43790..7d3a85a38 100644 --- a/Foundation/src/UTF8Encoding.cpp +++ b/Foundation/src/UTF8Encoding.cpp @@ -1,13 +1,13 @@ // // UTF8Encoding.cpp // -// $Id: //poco/Main/Foundation/src/UTF8Encoding.cpp#12 $ +// $Id: //poco/Main/Foundation/src/UTF8Encoding.cpp#13 $ // // Library: Foundation // Package: Text // Module: UTF8Encoding // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -35,11 +35,20 @@ #include "Poco/UTF8Encoding.h" +#include "Poco/String.h" namespace Poco { +const char* UTF8Encoding::_names[] = +{ + "UTF-8", + "UTF8", + NULL +}; + + const TextEncoding::CharacterMap UTF8Encoding::_charMap = { /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -71,6 +80,23 @@ UTF8Encoding::~UTF8Encoding() } +const char* UTF8Encoding::canonicalName() const +{ + return _names[0]; +} + + +bool UTF8Encoding::isA(const std::string& encodingName) const +{ + for (const char** name = _names; *name; ++name) + { + if (Poco::icompare(encodingName, *name) == 0) + return true; + } + return false; +} + + const TextEncoding::CharacterMap& UTF8Encoding::characterMap() const { return _charMap; diff --git a/Foundation/src/Windows1252Encoding.cpp b/Foundation/src/Windows1252Encoding.cpp index e5014727a..81e7ae358 100644 --- a/Foundation/src/Windows1252Encoding.cpp +++ b/Foundation/src/Windows1252Encoding.cpp @@ -1,13 +1,13 @@ // // Windows1252Encoding.cpp // -// $Id: //poco/Main/Foundation/src/Windows1252Encoding.cpp#6 $ +// $Id: //poco/Main/Foundation/src/Windows1252Encoding.cpp#7 $ // // Library: Foundation // Package: Text // Module: Windows1252Encoding // -// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2005-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -35,11 +35,20 @@ #include "Poco/Windows1252Encoding.h" +#include "Poco/String.h" namespace Poco { +const char* Windows1252Encoding::_names[] = +{ + "Windows-1252", + "CP1252", + NULL +}; + + const TextEncoding::CharacterMap Windows1252Encoding::_charMap = { /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */ @@ -72,6 +81,23 @@ Windows1252Encoding::~Windows1252Encoding() } +const char* Windows1252Encoding::canonicalName() const +{ + return _names[0]; +} + + +bool Windows1252Encoding::isA(const std::string& encodingName) const +{ + for (const char** name = _names; *name; ++name) + { + if (Poco::icompare(encodingName, *name) == 0) + return true; + } + return false; +} + + const TextEncoding::CharacterMap& Windows1252Encoding::characterMap() const { return _charMap; diff --git a/Foundation/testsuite/TestSuite_vs71.vcproj b/Foundation/testsuite/TestSuite_vs71.vcproj index 3ed08cd61..b38cffd67 100644 --- a/Foundation/testsuite/TestSuite_vs71.vcproj +++ b/Foundation/testsuite/TestSuite_vs71.vcproj @@ -577,6 +577,9 @@ + + @@ -611,6 +614,9 @@ + + @@ -892,6 +898,9 @@ + + @@ -908,6 +917,9 @@ + + diff --git a/Foundation/testsuite/TestSuite_vs80.vcproj b/Foundation/testsuite/TestSuite_vs80.vcproj index 0b7aef8ee..e3060c05b 100644 --- a/Foundation/testsuite/TestSuite_vs80.vcproj +++ b/Foundation/testsuite/TestSuite_vs80.vcproj @@ -1,7 +1,7 @@ + + @@ -834,6 +838,10 @@ RelativePath=".\src\ActivityTest.h" > + + @@ -1186,6 +1194,10 @@ RelativePath=".\src\TextConverterTest.cpp" > + + @@ -1206,6 +1218,10 @@ RelativePath=".\src\TextConverterTest.h" > + + diff --git a/Foundation/testsuite/src/ConditionTest.cpp b/Foundation/testsuite/src/ConditionTest.cpp new file mode 100644 index 000000000..0b51bdf1a --- /dev/null +++ b/Foundation/testsuite/src/ConditionTest.cpp @@ -0,0 +1,214 @@ +// +// ConditionTest.cpp +// +// $Id: //poco/Main/Foundation/testsuite/src/ConditionTest.cpp#1 $ +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "ConditionTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/Thread.h" +#include "Poco/Runnable.h" +#include "Poco/Condition.h" +#include "Poco/Mutex.h" +#include "Poco/Exception.h" + + +using Poco::Thread; +using Poco::Runnable; +using Poco::Condition; +using Poco::Mutex; +using Poco::TimeoutException; + + +namespace +{ + class WaitRunnable: public Runnable + { + public: + WaitRunnable(Condition& cond, Mutex& mutex): + _ran(false), + _cond(cond), + _mutex(mutex) + { + } + + void run() + { + _mutex.lock(); + _cond.wait(_mutex); + _mutex.unlock(); + _ran = true; + } + + bool ran() const + { + return _ran; + } + + private: + bool _ran; + Condition& _cond; + Mutex& _mutex; + }; + + class TryWaitRunnable: public Runnable + { + public: + TryWaitRunnable(Condition& cond, Mutex& mutex): + _ran(false), + _cond(cond), + _mutex(mutex) + { + } + + void run() + { + _mutex.lock(); + if (_cond.tryWait(_mutex, 10000)) + { + _ran = true; + } + _mutex.unlock(); + } + + bool ran() const + { + return _ran; + } + + private: + bool _ran; + Condition& _cond; + Mutex& _mutex; + }; + +} + + +ConditionTest::ConditionTest(const std::string& name): CppUnit::TestCase(name) +{ +} + + +ConditionTest::~ConditionTest() +{ +} + + +void ConditionTest::testSignal() +{ + Condition cond; + Mutex mtx; + WaitRunnable r1(cond, mtx); + WaitRunnable r2(cond, mtx); + + Thread t1; + Thread t2; + + t1.start(r1); + Thread::sleep(200); + t2.start(r2); + + assert (!r1.ran()); + assert (!r2.ran()); + + cond.signal(); + + t1.join(); + assert (r1.ran()); + + assert (!t2.tryJoin(200)); + + cond.signal(); + + t2.join(); + + assert (r2.ran()); +} + + +void ConditionTest::testBroadcast() +{ + Condition cond; + Mutex mtx; + WaitRunnable r1(cond, mtx); + WaitRunnable r2(cond, mtx); + TryWaitRunnable r3(cond, mtx); + + Thread t1; + Thread t2; + Thread t3; + + t1.start(r1); + Thread::sleep(200); + t2.start(r2); + Thread::sleep(200); + t3.start(r3); + + assert (!r1.ran()); + assert (!r2.ran()); + assert (!r3.ran()); + + cond.signal(); + t1.join(); + + assert (r1.ran()); + assert (!t2.tryJoin(500)); + assert (!t3.tryJoin(500)); + + cond.broadcast(); + + t2.join(); + t3.join(); + + assert (r2.ran()); + assert (r3.ran()); +} + + +void ConditionTest::setUp() +{ +} + + +void ConditionTest::tearDown() +{ +} + + +CppUnit::Test* ConditionTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ConditionTest"); + + CppUnit_addTest(pSuite, ConditionTest, testSignal); + CppUnit_addTest(pSuite, ConditionTest, testBroadcast); + + return pSuite; +} diff --git a/Foundation/testsuite/src/ConditionTest.h b/Foundation/testsuite/src/ConditionTest.h new file mode 100644 index 000000000..d2a311330 --- /dev/null +++ b/Foundation/testsuite/src/ConditionTest.h @@ -0,0 +1,61 @@ +// +// ConditionTest.h +// +// $Id: //poco/Main/Foundation/testsuite/src/ConditionTest.h#1 $ +// +// Definition of the ConditionTest class. +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef ConditionTest_INCLUDED +#define ConditionTest_INCLUDED + + +#include "Poco/Foundation.h" +#include "CppUnit/TestCase.h" + + +class ConditionTest: public CppUnit::TestCase +{ +public: + ConditionTest(const std::string& name); + ~ConditionTest(); + + void testSignal(); + void testBroadcast(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + + +#endif // ConditionTest_INCLUDED diff --git a/Foundation/testsuite/src/DynamicAnyTest.cpp b/Foundation/testsuite/src/DynamicAnyTest.cpp index 622f5c8f4..95fbbbd80 100644 --- a/Foundation/testsuite/src/DynamicAnyTest.cpp +++ b/Foundation/testsuite/src/DynamicAnyTest.cpp @@ -1,7 +1,7 @@ // // DynamicAnyTest.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/DynamicAnyTest.cpp#3 $ +// $Id: //poco/Main/Foundation/testsuite/src/DynamicAnyTest.cpp#5 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. diff --git a/Foundation/testsuite/src/DynamicAnyTest.h b/Foundation/testsuite/src/DynamicAnyTest.h index 95a404b4b..f6f580c8d 100644 --- a/Foundation/testsuite/src/DynamicAnyTest.h +++ b/Foundation/testsuite/src/DynamicAnyTest.h @@ -1,7 +1,7 @@ // // DynamicAnyTest.h // -// $Id: //poco/Main/Foundation/testsuite/src/DynamicAnyTest.h#2 $ +// $Id: //poco/Main/Foundation/testsuite/src/DynamicAnyTest.h#3 $ // // Tests for Any types // diff --git a/Foundation/testsuite/src/FileChannelTest.cpp b/Foundation/testsuite/src/FileChannelTest.cpp index c47de90c1..49fb1dd73 100644 --- a/Foundation/testsuite/src/FileChannelTest.cpp +++ b/Foundation/testsuite/src/FileChannelTest.cpp @@ -1,7 +1,7 @@ // // FileChannelTest.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/FileChannelTest.cpp#13 $ +// $Id: //poco/Main/Foundation/testsuite/src/FileChannelTest.cpp#14 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. diff --git a/Foundation/testsuite/src/FileChannelTest.h b/Foundation/testsuite/src/FileChannelTest.h index a8925ff01..b908c42e8 100644 --- a/Foundation/testsuite/src/FileChannelTest.h +++ b/Foundation/testsuite/src/FileChannelTest.h @@ -1,7 +1,7 @@ // // FileChannelTest.h // -// $Id: //poco/Main/Foundation/testsuite/src/FileChannelTest.h#10 $ +// $Id: //poco/Main/Foundation/testsuite/src/FileChannelTest.h#11 $ // // Definition of the FileChannelTest class. // diff --git a/Foundation/testsuite/src/FileTest.cpp b/Foundation/testsuite/src/FileTest.cpp index 72be572ce..74df0744e 100644 --- a/Foundation/testsuite/src/FileTest.cpp +++ b/Foundation/testsuite/src/FileTest.cpp @@ -1,7 +1,7 @@ // // FileTest.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/FileTest.cpp#13 $ +// $Id: //poco/Main/Foundation/testsuite/src/FileTest.cpp#14 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -390,6 +390,76 @@ void FileTest::testMove() } +void FileTest::testCopyDirectory() +{ + Path pd1("testdir"); + File fd1(pd1); + try + { + fd1.remove(true); + } + catch (...) + { + } + fd1.createDirectories(); + Path pd2(pd1, "subdir"); + File fd2(pd2); + fd2.createDirectories(); + Path pf1(pd1, "testfile1.dat"); + std::ofstream ostr1(pf1.toString().c_str()); + ostr1 << "Hello, world!" << std::endl; + ostr1.close(); + Path pf2(pd1, "testfile2.dat"); + std::ofstream ostr2(pf2.toString().c_str()); + ostr2 << "Hello, world!" << std::endl; + ostr2.close(); + Path pf3(pd2, "testfile3.dat"); + std::ofstream ostr3(pf3.toString().c_str()); + ostr3 << "Hello, world!" << std::endl; + ostr3.close(); + + File fd3("testdir2"); + + try + { + fd3.remove(true); + } + catch (...) + { + } + + fd1.copyTo("testdir2"); + + Path pd1t("testdir2"); + File fd1t(pd1t); + assert (fd1t.exists()); + assert (fd1t.isDirectory()); + + Path pd2t(pd1t, "subdir"); + File fd2t(pd2t); + assert (fd2t.exists()); + assert (fd2t.isDirectory()); + + Path pf1t(pd1t, "testfile1.dat"); + File ff1t(pf1t); + assert (ff1t.exists()); + assert (ff1t.isFile()); + + Path pf2t(pd1t, "testfile2.dat"); + File ff2t(pf2t); + assert (ff2t.exists()); + assert (ff2t.isFile()); + + Path pf3t(pd2t, "testfile3.dat"); + File ff3t(pf3t); + assert (ff3t.exists()); + assert (ff3t.isFile()); + + fd1.remove(true); + fd3.remove(true); +} + + void FileTest::testRename() { std::ofstream ostr("testfile.dat"); @@ -446,6 +516,7 @@ CppUnit::Test* FileTest::suite() CppUnit_addTest(pSuite, FileTest, testDirectory); CppUnit_addTest(pSuite, FileTest, testCopy); CppUnit_addTest(pSuite, FileTest, testMove); + CppUnit_addTest(pSuite, FileTest, testCopyDirectory); CppUnit_addTest(pSuite, FileTest, testRename); CppUnit_addTest(pSuite, FileTest, testRootDir); diff --git a/Foundation/testsuite/src/FileTest.h b/Foundation/testsuite/src/FileTest.h index 7cd4dcdd7..f36f27b51 100644 --- a/Foundation/testsuite/src/FileTest.h +++ b/Foundation/testsuite/src/FileTest.h @@ -1,7 +1,7 @@ // // FileTest.h // -// $Id: //poco/Main/Foundation/testsuite/src/FileTest.h#10 $ +// $Id: //poco/Main/Foundation/testsuite/src/FileTest.h#11 $ // // Definition of the FileTest class. // @@ -55,6 +55,7 @@ public: void testDirectory(); void testCopy(); void testMove(); + void testCopyDirectory(); void testRename(); void testRootDir(); diff --git a/Foundation/testsuite/src/TaskManagerTest.cpp b/Foundation/testsuite/src/TaskManagerTest.cpp index c3bb4da2d..f1438e370 100644 --- a/Foundation/testsuite/src/TaskManagerTest.cpp +++ b/Foundation/testsuite/src/TaskManagerTest.cpp @@ -1,7 +1,7 @@ // // TaskManagerTest.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/TaskManagerTest.cpp#8 $ +// $Id: //poco/Main/Foundation/testsuite/src/TaskManagerTest.cpp#9 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. diff --git a/Foundation/testsuite/src/TextEncodingTest.cpp b/Foundation/testsuite/src/TextEncodingTest.cpp new file mode 100644 index 000000000..8b45781ba --- /dev/null +++ b/Foundation/testsuite/src/TextEncodingTest.cpp @@ -0,0 +1,89 @@ +// +// TextEncodingTest.cpp +// +// $Id: //poco/Main/Foundation/testsuite/src/TextEncodingTest.cpp#2 $ +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "TextEncodingTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/TextEncoding.h" +#include "Poco/Latin1Encoding.h" + + +using Poco::TextEncoding; +using Poco::Latin1Encoding; + + +TextEncodingTest::TextEncodingTest(const std::string& name): CppUnit::TestCase(name) +{ +} + + +TextEncodingTest::~TextEncodingTest() +{ +} + + +void TextEncodingTest::testTextEncoding() +{ + TextEncoding& utf8 = TextEncoding::byName("utf8"); + assert (std::string("UTF-8") == utf8.canonicalName()); + + TextEncoding& latin1 = TextEncoding::byName("latin1"); + assert (std::string("ISO-8859-1") == latin1.canonicalName()); + + TextEncoding& glob = TextEncoding::global(); + assert (std::string("UTF-8") == glob.canonicalName()); + + TextEncoding::global(new Latin1Encoding); + + TextEncoding& glob2 = TextEncoding::global(); + assert (std::string("ISO-8859-1") == glob2.canonicalName()); +} + + +void TextEncodingTest::setUp() +{ +} + + +void TextEncodingTest::tearDown() +{ +} + + +CppUnit::Test* TextEncodingTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("TextEncodingTest"); + + CppUnit_addTest(pSuite, TextEncodingTest, testTextEncoding); + + return pSuite; +} diff --git a/Foundation/testsuite/src/TextEncodingTest.h b/Foundation/testsuite/src/TextEncodingTest.h new file mode 100644 index 000000000..77e21c7fc --- /dev/null +++ b/Foundation/testsuite/src/TextEncodingTest.h @@ -0,0 +1,60 @@ +// +// TextEncodingTest.h +// +// $Id: //poco/Main/Foundation/testsuite/src/TextEncodingTest.h#1 $ +// +// Definition of the TextEncodingTest class. +// +// Copyright (c) 2007, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef TextEncodingTest_INCLUDED +#define TextEncodingTest_INCLUDED + + +#include "Poco/Foundation.h" +#include "CppUnit/TestCase.h" + + +class TextEncodingTest: public CppUnit::TestCase +{ +public: + TextEncodingTest(const std::string& name); + ~TextEncodingTest(); + + void testTextEncoding(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + + +#endif // TextEncodingTest_INCLUDED diff --git a/Foundation/testsuite/src/TextTestSuite.cpp b/Foundation/testsuite/src/TextTestSuite.cpp index fd0ed168b..833f48730 100644 --- a/Foundation/testsuite/src/TextTestSuite.cpp +++ b/Foundation/testsuite/src/TextTestSuite.cpp @@ -1,7 +1,7 @@ // // TextTestSuite.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/TextTestSuite.cpp#8 $ +// $Id: //poco/Main/Foundation/testsuite/src/TextTestSuite.cpp#9 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -34,6 +34,7 @@ #include "TextIteratorTest.h" #include "TextConverterTest.h" #include "StreamConverterTest.h" +#include "TextEncodingTest.h" CppUnit::Test* TextTestSuite::suite() @@ -43,6 +44,7 @@ CppUnit::Test* TextTestSuite::suite() pSuite->addTest(TextIteratorTest::suite()); pSuite->addTest(TextConverterTest::suite()); pSuite->addTest(StreamConverterTest::suite()); + pSuite->addTest(TextEncodingTest::suite()); return pSuite; } diff --git a/Foundation/testsuite/src/ThreadTest.cpp b/Foundation/testsuite/src/ThreadTest.cpp index ad5ef2416..33dcbc9ab 100644 --- a/Foundation/testsuite/src/ThreadTest.cpp +++ b/Foundation/testsuite/src/ThreadTest.cpp @@ -1,7 +1,7 @@ // // ThreadTest.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/ThreadTest.cpp#9 $ +// $Id: //poco/Main/Foundation/testsuite/src/ThreadTest.cpp#10 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -180,6 +180,21 @@ void ThreadTest::testThreads() } +void ThreadTest::testJoin() +{ + Thread thread; + MyRunnable r; + assert (!thread.isRunning()); + thread.start(r); + Thread::sleep(200); + assert (thread.isRunning()); + assert (!thread.tryJoin(100)); + r.notify(); + assert (thread.tryJoin(500)); + assert (!thread.isRunning()); +} + + void ThreadTest::setUp() { } @@ -198,6 +213,7 @@ CppUnit::Test* ThreadTest::suite() CppUnit_addTest(pSuite, ThreadTest, testNamedThread); CppUnit_addTest(pSuite, ThreadTest, testCurrent); CppUnit_addTest(pSuite, ThreadTest, testThreads); + CppUnit_addTest(pSuite, ThreadTest, testJoin); return pSuite; } diff --git a/Foundation/testsuite/src/ThreadTest.h b/Foundation/testsuite/src/ThreadTest.h index c3b8596ec..809ada879 100644 --- a/Foundation/testsuite/src/ThreadTest.h +++ b/Foundation/testsuite/src/ThreadTest.h @@ -1,7 +1,7 @@ // // ThreadTest.h // -// $Id: //poco/Main/Foundation/testsuite/src/ThreadTest.h#8 $ +// $Id: //poco/Main/Foundation/testsuite/src/ThreadTest.h#9 $ // // Definition of the ThreadTest class. // @@ -50,6 +50,7 @@ public: void testNamedThread(); void testCurrent(); void testThreads(); + void testJoin(); void setUp(); void tearDown(); diff --git a/Foundation/testsuite/src/ThreadingTestSuite.cpp b/Foundation/testsuite/src/ThreadingTestSuite.cpp index 8bae565fb..b01ede96a 100644 --- a/Foundation/testsuite/src/ThreadingTestSuite.cpp +++ b/Foundation/testsuite/src/ThreadingTestSuite.cpp @@ -1,7 +1,7 @@ // // ThreadingTestSuite.cpp // -// $Id: //poco/Main/Foundation/testsuite/src/ThreadingTestSuite.cpp#9 $ +// $Id: //poco/Main/Foundation/testsuite/src/ThreadingTestSuite.cpp#10 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -40,6 +40,7 @@ #include "ActivityTest.h" #include "ActiveMethodTest.h" #include "ActiveDispatcherTest.h" +#include "ConditionTest.h" CppUnit::Test* ThreadingTestSuite::suite() @@ -55,6 +56,7 @@ CppUnit::Test* ThreadingTestSuite::suite() pSuite->addTest(ActivityTest::suite()); pSuite->addTest(ActiveMethodTest::suite()); pSuite->addTest(ActiveDispatcherTest::suite()); + pSuite->addTest(ConditionTest::suite()); return pSuite; } diff --git a/XML/src/ParserEngine.cpp b/XML/src/ParserEngine.cpp index 59625025d..8db023a21 100644 --- a/XML/src/ParserEngine.cpp +++ b/XML/src/ParserEngine.cpp @@ -1,13 +1,13 @@ // // ParserEngine.cpp // -// $Id: //poco/Main/XML/src/ParserEngine.cpp#12 $ +// $Id: //poco/Main/XML/src/ParserEngine.cpp#13 $ // // Library: XML // Package: XML // Module: ParserEngine // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2007, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -699,14 +699,21 @@ int ParserEngine::handleUnknownEncoding(void* encodingHandlerData, const XML_Cha ParserEngine* pThis = reinterpret_cast(encodingHandlerData); XMLString encoding(name); + TextEncoding* knownEncoding = 0; + EncodingMap::const_iterator it = pThis->_encodings.find(encoding); if (it != pThis->_encodings.end()) + knownEncoding = it->second; + else + knownEncoding = Poco::TextEncoding::find(encoding); + + if (knownEncoding) { - const TextEncoding::CharacterMap& map = it->second->characterMap(); + const TextEncoding::CharacterMap& map = knownEncoding->characterMap(); for (int i = 0; i < 256; ++i) info->map[i] = map[i]; - info->data = it->second; + info->data = knownEncoding; info->convert = &ParserEngine::convert; info->release = 0; return XML_STATUS_OK;