From b526dd81f25a037a9132bd747d127c63bdfb0b33 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Tue, 29 Jan 2008 09:06:52 +0000 Subject: [PATCH] changes from main repository --- Foundation/include/Poco/AbstractDelegate.h | 2 +- Foundation/include/Poco/ExpireStrategy.h | 4 +- Foundation/include/Poco/File_UNIX.h | 4 +- Foundation/include/Poco/File_VMS.h | 3 +- Foundation/include/Poco/File_WIN32.h | 3 +- Foundation/include/Poco/File_WIN32U.h | 2 +- Foundation/include/Poco/HashFunction.h | 15 +- Foundation/include/Poco/URIStreamFactory.h | 36 ++- Foundation/include/Poco/URIStreamOpener.h | 8 +- .../include/Poco/UniqueAccessExpireStrategy.h | 4 +- .../include/Poco/UniqueExpireStrategy.h | 4 +- Foundation/src/Debugger.cpp | 6 +- Foundation/src/File.cpp | 8 +- Foundation/src/File_VMS.cpp | 8 +- Foundation/src/SharedMemory.cpp | 6 +- Foundation/src/URIStreamFactory.cpp | 29 ++- Foundation/src/URIStreamOpener.cpp | 40 +++- Foundation/testsuite/src/ExpireCacheTest.cpp | 16 +- Foundation/testsuite/src/ExpireCacheTest.h | 3 +- Foundation/testsuite/src/FileTest.cpp | 3 +- Foundation/testsuite/src/HashTest.cpp | 226 ------------------ Foundation/testsuite/src/HashTest.h | 65 ----- Net/include/Poco/Net/Socket.h | 13 +- Net/include/Poco/Net/SocketImpl.h | 16 +- Net/src/HTTPStreamFactory.cpp | 40 +++- Net/src/SocketImpl.cpp | 9 +- Net/testsuite/src/HTTPStreamFactoryTest.cpp | 8 +- XML/include/Poco/DOM/DOMBuilder.h | 5 +- XML/include/Poco/DOM/DOMParser.h | 5 +- XML/include/Poco/DOM/DOMSerializer.h | 6 +- XML/include/Poco/DOM/Element.h | 9 +- XML/include/Poco/SAX/Attributes.h | 20 +- XML/include/Poco/SAX/AttributesImpl.h | 168 +++++++++++-- XML/include/Poco/SAX/SAXParser.h | 3 +- XML/include/Poco/SAX/XMLFilterImpl.h | 3 +- XML/include/Poco/SAX/XMLReader.h | 6 +- XML/include/Poco/XML/NamespaceStrategy.h | 20 +- XML/include/Poco/XML/ParserEngine.h | 5 +- XML/src/AttributesImpl.cpp | 125 ++-------- XML/src/DOMBuilder.cpp | 30 ++- XML/src/DOMParser.cpp | 22 +- XML/src/DOMSerializer.cpp | 8 +- XML/src/Element.cpp | 23 +- XML/src/NamespaceStrategy.cpp | 90 +++---- XML/src/ParserEngine.cpp | 17 +- XML/src/SAXParser.cpp | 13 +- XML/src/XMLFilterImpl.cpp | 9 +- 47 files changed, 611 insertions(+), 557 deletions(-) delete mode 100644 Foundation/testsuite/src/HashTest.cpp delete mode 100644 Foundation/testsuite/src/HashTest.h diff --git a/Foundation/include/Poco/AbstractDelegate.h b/Foundation/include/Poco/AbstractDelegate.h index c0b3c1918..7409ccc25 100644 --- a/Foundation/include/Poco/AbstractDelegate.h +++ b/Foundation/include/Poco/AbstractDelegate.h @@ -1,7 +1,7 @@ // // AbstractDelegate.h // -// $Id: //poco/svn/Foundation/include/Poco/AbstractDelegate.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/AbstractDelegate.h#3 $ // // Library: Foundation // Package: Events diff --git a/Foundation/include/Poco/ExpireStrategy.h b/Foundation/include/Poco/ExpireStrategy.h index 87268c9d9..a2120216e 100644 --- a/Foundation/include/Poco/ExpireStrategy.h +++ b/Foundation/include/Poco/ExpireStrategy.h @@ -1,7 +1,7 @@ // // ExpireStrategy.h // -// $Id: //poco/svn/Foundation/include/Poco/ExpireStrategy.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/ExpireStrategy.h#3 $ // // Library: Foundation // Package: Cache @@ -122,6 +122,8 @@ public: args.invalidate(); } } + else //not found: probably removed by onReplace + args.invalidate(); } void onReplace(const void*, std::set& elemsToRemove) diff --git a/Foundation/include/Poco/File_UNIX.h b/Foundation/include/Poco/File_UNIX.h index 07b361d79..4e343589f 100644 --- a/Foundation/include/Poco/File_UNIX.h +++ b/Foundation/include/Poco/File_UNIX.h @@ -1,7 +1,7 @@ // // File_UNIX.h // -// $Id: //poco/svn/Foundation/include/Poco/File_UNIX.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/File_UNIX.h#3 $ // // Library: Foundation // Package: Filesystem @@ -63,8 +63,8 @@ protected: bool canExecuteImpl() const; bool isFileImpl() const; bool isDirectoryImpl() const; - bool isHiddenImpl() const; bool isLinkImpl() const; + bool isHiddenImpl() const; Timestamp createdImpl() const; Timestamp getLastModifiedImpl() const; void setLastModifiedImpl(const Timestamp& ts); diff --git a/Foundation/include/Poco/File_VMS.h b/Foundation/include/Poco/File_VMS.h index caf3d7fbc..96fa9e9c2 100644 --- a/Foundation/include/Poco/File_VMS.h +++ b/Foundation/include/Poco/File_VMS.h @@ -1,7 +1,7 @@ // // File_VMS.h // -// $Id: //poco/svn/Foundation/include/Poco/File_VMS.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/File_VMS.h#3 $ // // Library: Foundation // Package: Filesystem @@ -65,6 +65,7 @@ protected: bool isFileImpl() const; bool isDirectoryImpl() const; bool isLinkImpl() const; + bool isHiddenImpl() const; Timestamp createdImpl() const; Timestamp getLastModifiedImpl() const; void setLastModifiedImpl(const Timestamp& ts); diff --git a/Foundation/include/Poco/File_WIN32.h b/Foundation/include/Poco/File_WIN32.h index 4f8998cd0..85d85987f 100644 --- a/Foundation/include/Poco/File_WIN32.h +++ b/Foundation/include/Poco/File_WIN32.h @@ -1,7 +1,7 @@ // // File_WIN32.h // -// $Id: //poco/svn/Foundation/include/Poco/File_WIN32.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/File_WIN32.h#3 $ // // Library: Foundation // Package: Filesystem @@ -65,6 +65,7 @@ protected: bool isFileImpl() const; bool isDirectoryImpl() const; bool isLinkImpl() const; + bool isHiddenImpl() const; Timestamp createdImpl() const; Timestamp getLastModifiedImpl() const; void setLastModifiedImpl(const Timestamp& ts); diff --git a/Foundation/include/Poco/File_WIN32U.h b/Foundation/include/Poco/File_WIN32U.h index 6626562b5..21d9b11cc 100644 --- a/Foundation/include/Poco/File_WIN32U.h +++ b/Foundation/include/Poco/File_WIN32U.h @@ -1,7 +1,7 @@ // // File_WIN32U.h // -// $Id: //poco/svn/Foundation/include/Poco/File_WIN32U.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/File_WIN32U.h#3 $ // // Library: Foundation // Package: Filesystem diff --git a/Foundation/include/Poco/HashFunction.h b/Foundation/include/Poco/HashFunction.h index 6678aef64..e1ad64173 100644 --- a/Foundation/include/Poco/HashFunction.h +++ b/Foundation/include/Poco/HashFunction.h @@ -1,7 +1,7 @@ // // HashFunction.h // -// $Id: //poco/svn/Foundation/include/Poco/HashFunction.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/HashFunction.h#3 $ // // Library: Foundation // Package: Hashing @@ -60,6 +60,19 @@ struct HashFunction }; +//@ deprecated +template <> +struct HashFunction + /// A generic hash function. +{ + UInt32 operator () (const std::string& key, UInt32 maxValue) const + /// Returns the hash value for the given key. + { + return ((UInt32) hash(key)) % maxValue; + } +}; + + } // namespace Poco diff --git a/Foundation/include/Poco/URIStreamFactory.h b/Foundation/include/Poco/URIStreamFactory.h index d0bb6bda8..9f0866f41 100644 --- a/Foundation/include/Poco/URIStreamFactory.h +++ b/Foundation/include/Poco/URIStreamFactory.h @@ -1,7 +1,7 @@ // // URIStreamFactory.h // -// $Id: //poco/svn/Foundation/include/Poco/URIStreamFactory.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/URIStreamFactory.h#3 $ // // Library: Foundation // Package: URI @@ -66,6 +66,9 @@ public: /// /// If the stream cannot be opened for whatever reason, /// an appropriate IOException must be thrown. + /// + /// If opening the stream results in a redirect, a + /// URIRedirection exception should be thrown. protected: virtual ~URIStreamFactory(); @@ -79,6 +82,37 @@ private: }; +class Foundation_API URIRedirection + /// An instance of URIRedirection is thrown by a URIStreamFactory::open() + /// if opening the original URI resulted in a redirection response + /// (such as a MOVED PERMANENTLY in HTTP). +{ +public: + URIRedirection(const std::string& uri); + URIRedirection(const URIRedirection& redir); + + URIRedirection& operator = (const URIRedirection& redir); + void swap(URIRedirection& redir); + + const std::string& uri() const; + /// Returns the new URI. + +private: + URIRedirection(); + + std::string _uri; +}; + + +// +// inlines +// +inline const std::string& URIRedirection::uri() const +{ + return _uri; +} + + } // namespace Poco diff --git a/Foundation/include/Poco/URIStreamOpener.h b/Foundation/include/Poco/URIStreamOpener.h index bbb86f15a..15b4b84e6 100644 --- a/Foundation/include/Poco/URIStreamOpener.h +++ b/Foundation/include/Poco/URIStreamOpener.h @@ -1,7 +1,7 @@ // // URIStreamOpener.h // -// $Id: //poco/svn/Foundation/include/Poco/URIStreamOpener.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/URIStreamOpener.h#3 $ // // Library: Foundation // Package: URI @@ -62,6 +62,11 @@ class Foundation_API URIStreamOpener /// A FileStreamFactory is automatically registered for file URIs. { public: + enum + { + MAX_REDIRECTS = 10 + }; + URIStreamOpener(); /// Creates the URIStreamOpener and registers a FileStreamFactory /// for file URIs. @@ -133,6 +138,7 @@ public: protected: std::istream* openFile(const Path& path) const; + std::istream* openURI(const std::string& scheme, const URI& uri) const; private: URIStreamOpener(const URIStreamOpener&); diff --git a/Foundation/include/Poco/UniqueAccessExpireStrategy.h b/Foundation/include/Poco/UniqueAccessExpireStrategy.h index 66591fc16..67d423bb9 100644 --- a/Foundation/include/Poco/UniqueAccessExpireStrategy.h +++ b/Foundation/include/Poco/UniqueAccessExpireStrategy.h @@ -1,7 +1,7 @@ // // UniqueAccessExpireStrategy.h // -// $Id: //poco/svn/Foundation/include/Poco/UniqueAccessExpireStrategy.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/UniqueAccessExpireStrategy.h#3 $ // // Library: Foundation // Package: Cache @@ -149,6 +149,8 @@ public: args.invalidate(); } } + else //not found: probably removed by onReplace + args.invalidate(); } void onReplace(const void*, std::set& elemsToRemove) diff --git a/Foundation/include/Poco/UniqueExpireStrategy.h b/Foundation/include/Poco/UniqueExpireStrategy.h index 7cfe549bc..b5017799d 100644 --- a/Foundation/include/Poco/UniqueExpireStrategy.h +++ b/Foundation/include/Poco/UniqueExpireStrategy.h @@ -1,7 +1,7 @@ // // UniqueExpireStrategy.h // -// $Id: //poco/svn/Foundation/include/Poco/UniqueExpireStrategy.h#2 $ +// $Id: //poco/svn/Foundation/include/Poco/UniqueExpireStrategy.h#3 $ // // Library: Foundation // Package: Cache @@ -130,6 +130,8 @@ public: args.invalidate(); } } + else //not found: probably removed by onReplace + args.invalidate(); } void onReplace(const void*, std::set& elemsToRemove) diff --git a/Foundation/src/Debugger.cpp b/Foundation/src/Debugger.cpp index a53fd0630..9f2ed2419 100644 --- a/Foundation/src/Debugger.cpp +++ b/Foundation/src/Debugger.cpp @@ -1,7 +1,7 @@ // // Debugger.cpp // -// $Id: //poco/svn/Foundation/src/Debugger.cpp#2 $ +// $Id: //poco/svn/Foundation/src/Debugger.cpp#3 $ // // Library: Foundation // Package: Core @@ -47,7 +47,7 @@ #include #include #endif -#if defined(POCO_WIN32_UTF8) +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) #include "Poco/UnicodeConverter.h" #endif @@ -85,7 +85,7 @@ void Debugger::message(const std::string& msg) #if defined(POCO_OS_FAMILY_WINDOWS) if (IsDebuggerPresent()) { -#if defined(POCO_WIN32_UTF8) +#if defined(POCO_WIN32_UTF8) && !defined(POCO_NO_WSTRING) std::wstring umsg; UnicodeConverter::toUTF16(msg, umsg); umsg += '\n'; diff --git a/Foundation/src/File.cpp b/Foundation/src/File.cpp index 94366609c..9af07b5d0 100644 --- a/Foundation/src/File.cpp +++ b/Foundation/src/File.cpp @@ -1,7 +1,7 @@ // // File.cpp // -// $Id: //poco/svn/Foundation/src/File.cpp#2 $ +// $Id: //poco/svn/Foundation/src/File.cpp#3 $ // // Library: Foundation // Package: Filesystem @@ -160,6 +160,12 @@ bool File::isLink() const } +bool File::isHidden() const +{ + return isHiddenImpl(); +} + + Timestamp File::created() const { return createdImpl(); diff --git a/Foundation/src/File_VMS.cpp b/Foundation/src/File_VMS.cpp index f2140f9d9..3864c9943 100644 --- a/Foundation/src/File_VMS.cpp +++ b/Foundation/src/File_VMS.cpp @@ -1,7 +1,7 @@ // // File_VMS.cpp // -// $Id: //poco/svn/Foundation/src/File_VMS.cpp#2 $ +// $Id: //poco/svn/Foundation/src/File_VMS.cpp#3 $ // // Library: Foundation // Package: Filesystem @@ -174,6 +174,12 @@ bool FileImpl::isLinkImpl() const } +bool FileImpl::isHiddenImpl() const +{ + return false; +} + + Timestamp FileImpl::createdImpl() const { poco_assert (!_path.empty()); diff --git a/Foundation/src/SharedMemory.cpp b/Foundation/src/SharedMemory.cpp index 9df0b2aa0..6458a05e0 100644 --- a/Foundation/src/SharedMemory.cpp +++ b/Foundation/src/SharedMemory.cpp @@ -1,7 +1,7 @@ // // SharedMemory.cpp // -// $Id: //poco/svn/Foundation/src/SharedMemory.cpp#2 $ +// $Id: //poco/svn/Foundation/src/SharedMemory.cpp#3 $ // // Library: Foundation // Package: Processes @@ -42,7 +42,9 @@ #include "Poco/SharedMemory.h" #include "Poco/Exception.h" -#if defined(POCO_OS_FAMILY_WINDOWS) +#if defined(POCO_NO_SHAREDMEMORY) +#include "SharedMemory_DUMMY.cpp" +#elif defined(POCO_OS_FAMILY_WINDOWS) #include "SharedMemory_WIN32.cpp" #elif defined(POCO_OS_FAMILY_UNIX) #include "SharedMemory_POSIX.cpp" diff --git a/Foundation/src/URIStreamFactory.cpp b/Foundation/src/URIStreamFactory.cpp index 493171a88..bd0125152 100644 --- a/Foundation/src/URIStreamFactory.cpp +++ b/Foundation/src/URIStreamFactory.cpp @@ -1,7 +1,7 @@ // // URIStreamFactory.cpp // -// $Id: //poco/svn/Foundation/src/URIStreamFactory.cpp#2 $ +// $Id: //poco/svn/Foundation/src/URIStreamFactory.cpp#3 $ // // Library: Foundation // Package: URI @@ -35,6 +35,7 @@ #include "Poco/URIStreamFactory.h" +#include namespace Poco { @@ -50,4 +51,30 @@ URIStreamFactory::~URIStreamFactory() } +URIRedirection::URIRedirection(const std::string& uri): + _uri(uri) +{ +} + + +URIRedirection::URIRedirection(const URIRedirection& redir): + _uri(redir._uri) +{ +} + + +URIRedirection& URIRedirection::operator = (const URIRedirection& redir) +{ + URIRedirection tmp(redir); + swap(tmp); + return *this; +} + + +void URIRedirection::swap(URIRedirection& redir) +{ + std::swap(_uri, redir._uri); +} + + } // namespace Poco diff --git a/Foundation/src/URIStreamOpener.cpp b/Foundation/src/URIStreamOpener.cpp index 5d202b233..6d8e4ceaf 100644 --- a/Foundation/src/URIStreamOpener.cpp +++ b/Foundation/src/URIStreamOpener.cpp @@ -1,7 +1,7 @@ // // URIStreamOpener.cpp // -// $Id: //poco/svn/Foundation/src/URIStreamOpener.cpp#2 $ +// $Id: //poco/svn/Foundation/src/URIStreamOpener.cpp#3 $ // // Library: Foundation // Package: URI @@ -68,11 +68,7 @@ std::istream* URIStreamOpener::open(const URI& uri) const scheme = "file"; else scheme = uri.getScheme(); - FactoryMap::const_iterator it = _map.find(scheme); - if (it != _map.end()) - return it->second->open(uri); - else - throw UnknownURISchemeException(scheme); + return openURI(scheme, uri); } @@ -86,7 +82,7 @@ std::istream* URIStreamOpener::open(const std::string& pathOrURI) const std::string scheme(uri.getScheme()); FactoryMap::const_iterator it = _map.find(scheme); if (it != _map.end()) - return it->second->open(uri); + return openURI(scheme, uri); } catch (Exception&) { @@ -108,7 +104,7 @@ std::istream* URIStreamOpener::open(const std::string& basePathOrURI, const std: if (it != _map.end()) { uri.resolve(pathOrURI); - return it->second->open(uri); + return openURI(scheme, uri); } } catch (Exception&) @@ -170,5 +166,33 @@ std::istream* URIStreamOpener::openFile(const Path& path) const } +std::istream* URIStreamOpener::openURI(const std::string& scheme, const URI& uri) const +{ + std::string actualScheme(scheme); + URI actualURI(uri); + int redirects = 0; + + while (redirects < MAX_REDIRECTS) + { + try + { + FactoryMap::const_iterator it = _map.find(actualScheme); + if (it != _map.end()) + return it->second->open(actualURI); + else if (redirects > 0) + throw UnknownURISchemeException(actualURI.toString() + std::string("; redirected from ") + uri.toString()); + else + throw UnknownURISchemeException(actualURI.toString()); + } + catch (URIRedirection& redir) + { + actualURI = redir.uri(); + actualScheme = actualURI.getScheme(); + ++redirects; + } + } + throw IOException("Too many redirects while opening URI", uri.toString()); +} + } // namespace Poco diff --git a/Foundation/testsuite/src/ExpireCacheTest.cpp b/Foundation/testsuite/src/ExpireCacheTest.cpp index bdad0cff9..2f13e437b 100644 --- a/Foundation/testsuite/src/ExpireCacheTest.cpp +++ b/Foundation/testsuite/src/ExpireCacheTest.cpp @@ -1,7 +1,7 @@ // // ExpireCacheTest.cpp // -// $Id: //poco/svn/Foundation/testsuite/src/ExpireCacheTest.cpp#2 $ +// $Id: //poco/svn/Foundation/testsuite/src/ExpireCacheTest.cpp#3 $ // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -196,6 +196,19 @@ void ExpireCacheTest::testAccessExpireN() assert (!aCache.has(3)); } + +void ExpireCacheTest::testExpireWithHas() +{ + // 3-1 represents the cache sorted by age, elements get replaced at the end of the list + // 3-1|5 -> 5 gets removed + ExpireCache aCache(DURSLEEP); + aCache.add(1, 2); // 1 + assert (aCache.has(1)); + Thread::sleep(DURWAIT); + assert (!aCache.has(1)); +} + + void ExpireCacheTest::setUp() { } @@ -215,6 +228,7 @@ CppUnit::Test* ExpireCacheTest::suite() CppUnit_addTest(pSuite, ExpireCacheTest, testExpireN); CppUnit_addTest(pSuite, ExpireCacheTest, testDuplicateAdd); CppUnit_addTest(pSuite, ExpireCacheTest, testAccessExpireN); + CppUnit_addTest(pSuite, ExpireCacheTest, testExpireWithHas); return pSuite; } diff --git a/Foundation/testsuite/src/ExpireCacheTest.h b/Foundation/testsuite/src/ExpireCacheTest.h index 68f7900da..c46e47b8e 100644 --- a/Foundation/testsuite/src/ExpireCacheTest.h +++ b/Foundation/testsuite/src/ExpireCacheTest.h @@ -1,7 +1,7 @@ // // ExpireCacheTest.h // -// $Id: //poco/svn/Foundation/testsuite/src/ExpireCacheTest.h#2 $ +// $Id: //poco/svn/Foundation/testsuite/src/ExpireCacheTest.h#3 $ // // Tests for ExpireCache // @@ -50,6 +50,7 @@ public: void testExpire0(); void testExpireN(); void testAccessExpireN(); + void testExpireWithHas(); void setUp(); diff --git a/Foundation/testsuite/src/FileTest.cpp b/Foundation/testsuite/src/FileTest.cpp index 8b42caf7a..3f2cba19d 100644 --- a/Foundation/testsuite/src/FileTest.cpp +++ b/Foundation/testsuite/src/FileTest.cpp @@ -1,7 +1,7 @@ // // FileTest.cpp // -// $Id: //poco/svn/Foundation/testsuite/src/FileTest.cpp#2 $ +// $Id: //poco/svn/Foundation/testsuite/src/FileTest.cpp#3 $ // // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -208,6 +208,7 @@ void FileTest::testCreateFile() File f("testfile.dat"); bool created = f.createFile(); assert (created); + assert (!f.isHidden()); created = f.createFile(); assert (!created); } diff --git a/Foundation/testsuite/src/HashTest.cpp b/Foundation/testsuite/src/HashTest.cpp deleted file mode 100644 index 5e7629c34..000000000 --- a/Foundation/testsuite/src/HashTest.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// -// HashTest.cpp -// -// $Id: //poco/1.2/Foundation/testsuite/src/HashTest.cpp#2 $ -// -// Copyright (c) 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 "HashTest.h" -#include "CppUnit/TestCaller.h" -#include "CppUnit/TestSuite.h" -#include "Poco/HashTable.h" -#include "Poco/NumberFormatter.h" - - -using namespace Poco; - - -HashTest::HashTest(const std::string& name): CppUnit::TestCase(name) -{ -} - - -HashTest::~HashTest() -{ -} - - -void HashTest::testInsert() -{ - std::string s1("str1"); - std::string s2("str2"); - HashTable hashTable; - assert (!hashTable.exists(s1)); - hashTable.insert(s1, 13); - assert (hashTable.exists(s1)); - assert (hashTable.get(s1) == 13); - int retVal = 0; - - assert (hashTable.get(s1, retVal)); - assert (retVal == 13); - try - { - hashTable.insert(s1, 22); - failmsg ("duplicate insert must fail"); - } - catch (Exception&){} - try - { - hashTable.get(s2); - failmsg ("getting a non inserted item must fail"); - } - catch (Exception&){} - - assert (!hashTable.exists(s2)); - hashTable.insert(s2, 13); - assert (hashTable.exists(s2)); -} - - -void HashTest::testUpdate() -{ - // add code for second test here - std::string s1("str1"); - std::string s2("str2"); - HashTable hashTable; - hashTable.insert(s1, 13); - hashTable.update(s1, 14); - assert (hashTable.exists(s1)); - assert (hashTable.get(s1) == 14); - int retVal = 0; - - assert (hashTable.get(s1, retVal)); - assert (retVal == 14); - - // updating a non existing item must work too - hashTable.update(s2, 15); - assert (hashTable.get(s2) == 15); -} - - -void HashTest::testOverflow() -{ - HashTable hashTable(13); - for (int i = 0; i < 1024; ++i) - { - hashTable.insert(Poco::NumberFormatter::format(i), i*i); - } - - for (int i = 0; i < 1024; ++i) - { - std::string tmp = Poco::NumberFormatter::format(i); - assert (hashTable.exists(tmp)); - assert (hashTable.get(tmp) == i*i); - } -} - - -void HashTest::testSize() -{ - HashTable hashTable(13); - assert (hashTable.size() == 0); - Poco::UInt32 h1 = hashTable.insert("1", 1); - assert (hashTable.size() == 1); - Poco::UInt32 h2 = hashTable.update("2", 2); - assert (hashTable.size() == 2); - hashTable.remove("1"); - assert (hashTable.size() == 1); - hashTable.remove("3"); - assert (hashTable.size() == 1); - hashTable.removeRaw("2", h2); - assert (hashTable.size() == 0); - hashTable.insert("1", 1); - hashTable.insert("2", 2); - assert (hashTable.size() == 2); - hashTable.clear(); - assert (hashTable.size() == 0); -} - - -void HashTest::testResize() -{ - HashTable hashTable(13); - assert (hashTable.size() == 0); - hashTable.resize(19); - for (int i = 0; i < 1024; ++i) - { - hashTable.insert(Poco::NumberFormatter::format(i), i*i); - } - hashTable.resize(1009); - - for (int i = 0; i < 1024; ++i) - { - std::string tmp = Poco::NumberFormatter::format(i); - assert (hashTable.exists(tmp)); - assert (hashTable.get(tmp) == i*i); - } -} - - -void HashTest::testStatistic() -{ - double relax = 0.001; - HashTable hashTable(13); - assert (hashTable.size() == 0); - HashStatistic stat1(hashTable.currentState()); - assert (stat1.avgEntriesPerHash() < relax && stat1.avgEntriesPerHash() > -relax); - assert (stat1.maxPositionsOfTable() == 13); - assert (stat1.maxEntriesPerHash() == 0); - - hashTable.resize(19); - stat1 = hashTable.currentState(true); - assert (stat1.avgEntriesPerHash() < relax && stat1.avgEntriesPerHash() > -relax); - assert (stat1.maxPositionsOfTable() == 19); - assert (stat1.maxEntriesPerHash() == 0); - assert (stat1.detailedEntriesPerHash().size() == 19); - - for (int i = 0; i < 1024; ++i) - { - hashTable.insert(Poco::NumberFormatter::format(i), i*i); - } - stat1 = hashTable.currentState(true); - double expAvg = 1024.0/ 19; - assert (stat1.avgEntriesPerHash() < (expAvg + relax) && stat1.avgEntriesPerHash() > (expAvg - relax)); - assert (stat1.maxPositionsOfTable() == 19); - assert (stat1.maxEntriesPerHash() > expAvg); - hashTable.resize(1009); - stat1 = hashTable.currentState(true); - - expAvg = 1024.0/ 1009; - - assert (stat1.avgEntriesPerHash() < (expAvg + relax) && stat1.avgEntriesPerHash() > (expAvg - relax)); - assert (stat1.maxPositionsOfTable() == 1009); - assert (stat1.maxEntriesPerHash() > expAvg); -} - - - - -void HashTest::setUp() -{ -} - - -void HashTest::tearDown() -{ -} - - -CppUnit::Test* HashTest::suite() -{ - CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HashTest"); - - CppUnit_addTest(pSuite, HashTest, testInsert); - CppUnit_addTest(pSuite, HashTest, testUpdate); - CppUnit_addTest(pSuite, HashTest, testOverflow); - CppUnit_addTest(pSuite, HashTest, testSize); - CppUnit_addTest(pSuite, HashTest, testResize); - CppUnit_addTest(pSuite, HashTest, testStatistic); - - return pSuite; -} diff --git a/Foundation/testsuite/src/HashTest.h b/Foundation/testsuite/src/HashTest.h deleted file mode 100644 index c81f2b1ff..000000000 --- a/Foundation/testsuite/src/HashTest.h +++ /dev/null @@ -1,65 +0,0 @@ -// -// HashTest.h -// -// $Id: //poco/1.2/Foundation/testsuite/src/HashTest.h#1 $ -// -// Definition of the HashTest class. -// -// Copyright (c) 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. -// - - -#ifndef HashTest_INCLUDED -#define HashTest_INCLUDED - - -#include "Poco/Foundation.h" -#include "CppUnit/TestCase.h" - - -class HashTest: public CppUnit::TestCase -{ -public: - HashTest(const std::string& name); - ~HashTest(); - - void testInsert(); - void testOverflow(); - void testUpdate(); - void testSize(); - void testResize(); - void testStatistic(); - - void setUp(); - void tearDown(); - - static CppUnit::Test* suite(); - -private: -}; - - -#endif // HashTest_INCLUDED diff --git a/Net/include/Poco/Net/Socket.h b/Net/include/Poco/Net/Socket.h index 03508acdd..405c95600 100644 --- a/Net/include/Poco/Net/Socket.h +++ b/Net/include/Poco/Net/Socket.h @@ -1,7 +1,7 @@ // // Socket.h // -// $Id: //poco/svn/Net/include/Poco/Net/Socket.h#2 $ +// $Id: //poco/svn/Net/include/Poco/Net/Socket.h#3 $ // // Library: Net // Package: Sockets @@ -272,6 +272,11 @@ public: /// Sets the socket in blocking mode if flag is true, /// disables blocking mode if flag is false. + bool getBlocking() const; + /// Returns the blocking mode of the socket. + /// This method will only work if the blocking modes of + /// the socket are changed via the setBlocking method! + SocketAddress address() const; /// Returns the IP address and port number of the socket. @@ -543,6 +548,12 @@ inline void Socket::setBlocking(bool flag) } +inline bool Socket::getBlocking() const +{ + return _pImpl->getBlocking(); +} + + inline SocketImpl* Socket::impl() const { return _pImpl; diff --git a/Net/include/Poco/Net/SocketImpl.h b/Net/include/Poco/Net/SocketImpl.h index d817d417c..c044437b3 100644 --- a/Net/include/Poco/Net/SocketImpl.h +++ b/Net/include/Poco/Net/SocketImpl.h @@ -1,7 +1,7 @@ // // SocketImpl.h // -// $Id: //poco/svn/Net/include/Poco/Net/SocketImpl.h#2 $ +// $Id: //poco/svn/Net/include/Poco/Net/SocketImpl.h#3 $ // // Library: Net // Package: Sockets @@ -323,10 +323,15 @@ public: bool getBroadcast(); /// Returns the value of the SO_BROADCAST socket option. - void setBlocking(bool flag); + virtual void setBlocking(bool flag); /// Sets the socket in blocking mode if flag is true, /// disables blocking mode if flag is false. + virtual bool getBlocking() const; + /// Returns the blocking mode of the socket. + /// This method will only work if the blocking modes of + /// the socket are changed via the setBlocking method! + int socketError(); /// Returns the value of the SO_ERROR socket option. @@ -409,6 +414,7 @@ private: Poco::Timespan _recvTimeout; Poco::Timespan _sndTimeout; #endif + bool _blocking; friend class Socket; friend class SecureSocketImpl; @@ -446,6 +452,12 @@ inline void SocketImpl::invalidate() } +inline bool SocketImpl::getBlocking() const +{ + return _blocking; +} + + } } // namespace Poco::Net diff --git a/Net/src/HTTPStreamFactory.cpp b/Net/src/HTTPStreamFactory.cpp index 2af6fe6bb..8e98c8d91 100644 --- a/Net/src/HTTPStreamFactory.cpp +++ b/Net/src/HTTPStreamFactory.cpp @@ -1,7 +1,7 @@ // // HTTPStreamFactory.cpp // -// $Id: //poco/svn/Net/src/HTTPStreamFactory.cpp#2 $ +// $Id: //poco/svn/Net/src/HTTPStreamFactory.cpp#3 $ // // Library: Net // Package: HTTP @@ -78,14 +78,21 @@ std::istream* HTTPStreamFactory::open(const URI& uri) poco_assert (uri.getScheme() == "http"); URI resolvedURI(uri); + URI proxyUri; HTTPClientSession* pSession = 0; + bool retry = false; + try { - int redirects = 0; do { pSession = new HTTPClientSession(resolvedURI.getHost(), resolvedURI.getPort()); - pSession->setProxy(_proxyHost, _proxyPort); + + if (proxyUri.empty()) + pSession->setProxy(_proxyHost, _proxyPort); + else + pSession->setProxy(proxyUri.getHost(), proxyUri.getPort()); + std::string path = resolvedURI.getPathAndQuery(); if (path.empty()) path = "/"; HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); @@ -93,22 +100,35 @@ std::istream* HTTPStreamFactory::open(const URI& uri) HTTPResponse res; std::istream& rs = pSession->receiveResponse(res); bool moved = (res.getStatus() == HTTPResponse::HTTP_MOVED_PERMANENTLY || - res.getStatus() == HTTPResponse::HTTP_FOUND || - res.getStatus() == HTTPResponse::HTTP_SEE_OTHER); + res.getStatus() == HTTPResponse::HTTP_FOUND || + res.getStatus() == HTTPResponse::HTTP_SEE_OTHER || + res.getStatus() == HTTPResponse::HTTP_TEMPORARY_REDIRECT); if (moved) { resolvedURI.resolve(res.get("Location")); - delete pSession; - if (resolvedURI.getScheme() != "http") throw UnsupportedRedirectException(uri.toString()); - ++redirects; + throw URIRedirection(resolvedURI.toString()); } else if (res.getStatus() == HTTPResponse::HTTP_OK) { return new HTTPResponseStream(rs, pSession); } - else throw HTTPException(res.getReason(), uri.toString()); + else if (res.getStatus() == HTTPResponse::HTTP_USEPROXY && !retry) + { + //The requested resource MUST be accessed through the proxy + //given by the Location field. The Location field gives the + //URI of the proxy. The recipient is expected to repeat this + //single request via the proxy. 305 responses MUST only be generated by origin servers. + // only use for one single request! + proxyUri.resolve(res.get("Location")); + delete pSession; pSession = 0; + retry = true; //only allow useproxy once + } + else + { + throw HTTPException(res.getReason(), uri.toString()); + } } - while (redirects < MAX_REDIRECTS); + while(retry); throw HTTPException("Too many redirects", uri.toString()); } catch (...) diff --git a/Net/src/SocketImpl.cpp b/Net/src/SocketImpl.cpp index b9c5417c0..816482eb8 100644 --- a/Net/src/SocketImpl.cpp +++ b/Net/src/SocketImpl.cpp @@ -1,7 +1,7 @@ // // SocketImpl.cpp // -// $Id: //poco/svn/Net/src/SocketImpl.cpp#2 $ +// $Id: //poco/svn/Net/src/SocketImpl.cpp#3 $ // // Library: Net // Package: Sockets @@ -54,13 +54,15 @@ namespace Net { SocketImpl::SocketImpl(): - _sockfd(POCO_INVALID_SOCKET) + _sockfd(POCO_INVALID_SOCKET), + _blocking(true) { } SocketImpl::SocketImpl(poco_socket_t sockfd): - _sockfd(sockfd) + _sockfd(sockfd), + _blocking(true) { } @@ -718,6 +720,7 @@ void SocketImpl::setBlocking(bool flag) { int arg = flag ? 0 : 1; ioctl(FIONBIO, arg); + _blocking = flag; } diff --git a/Net/testsuite/src/HTTPStreamFactoryTest.cpp b/Net/testsuite/src/HTTPStreamFactoryTest.cpp index da295b43d..c2efd61c1 100644 --- a/Net/testsuite/src/HTTPStreamFactoryTest.cpp +++ b/Net/testsuite/src/HTTPStreamFactoryTest.cpp @@ -1,7 +1,7 @@ // // HTTPStreamFactoryTest.cpp // -// $Id: //poco/svn/Net/testsuite/src/HTTPStreamFactoryTest.cpp#2 $ +// $Id: //poco/svn/Net/testsuite/src/HTTPStreamFactoryTest.cpp#3 $ // // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -36,6 +36,7 @@ #include "Poco/Net/HTTPStreamFactory.h" #include "Poco/Net/NetException.h" #include "Poco/URI.h" +#include "Poco/URIStreamOpener.h" #include "Poco/StreamCopier.h" #include "HTTPTestServer.h" #include @@ -88,10 +89,11 @@ void HTTPStreamFactoryTest::testEmptyPath() void HTTPStreamFactoryTest::testRedirect() { HTTPTestServer server; - HTTPStreamFactory factory; + Poco::URIStreamOpener opener; + opener.registerStreamFactory("http", new HTTPStreamFactory); URI uri("http://localhost/redirect"); uri.setPort(server.port()); - std::auto_ptr pStr(factory.open(uri)); + std::auto_ptr pStr(opener.open(uri)); std::ostringstream ostr; StreamCopier::copyStream(*pStr.get(), ostr); assert (ostr.str() == HTTPTestServer::LARGE_BODY); diff --git a/XML/include/Poco/DOM/DOMBuilder.h b/XML/include/Poco/DOM/DOMBuilder.h index ef461e88f..4fc7a27ed 100644 --- a/XML/include/Poco/DOM/DOMBuilder.h +++ b/XML/include/Poco/DOM/DOMBuilder.h @@ -1,7 +1,7 @@ // // DOMBuilder.h // -// $Id: //poco/svn/XML/include/Poco/DOM/DOMBuilder.h#2 $ +// $Id: //poco/svn/XML/include/Poco/DOM/DOMBuilder.h#3 $ // // Library: XML // Package: DOM @@ -81,6 +81,9 @@ public: virtual Document* parse(InputSource* pInputSource); /// Parse an XML document from a location identified by an InputSource. + virtual Document* parseMemoryNP(const char* xml, std::size_t size); + /// Parses an XML document from memory. + protected: // DTDHandler void notationDecl(const XMLString& name, const XMLString* publicId, const XMLString* systemId); diff --git a/XML/include/Poco/DOM/DOMParser.h b/XML/include/Poco/DOM/DOMParser.h index 8bfb86cec..8ec3ec0a5 100644 --- a/XML/include/Poco/DOM/DOMParser.h +++ b/XML/include/Poco/DOM/DOMParser.h @@ -1,7 +1,7 @@ // // DOMParser.h // -// $Id: //poco/svn/XML/include/Poco/DOM/DOMParser.h#2 $ +// $Id: //poco/svn/XML/include/Poco/DOM/DOMParser.h#3 $ // // Library: XML // Package: DOM @@ -105,6 +105,9 @@ public: Document* parseString(const std::string& xml); /// Parse an XML document from a string. + Document* parseMemory(const char* xml, std::size_t size); + /// Parse an XML document from memory. + EntityResolver* getEntityResolver() const; /// Returns the entity resolver used by the underlying SAXParser. diff --git a/XML/include/Poco/DOM/DOMSerializer.h b/XML/include/Poco/DOM/DOMSerializer.h index 1f39efff2..6c5f276e4 100644 --- a/XML/include/Poco/DOM/DOMSerializer.h +++ b/XML/include/Poco/DOM/DOMSerializer.h @@ -1,7 +1,7 @@ // // DOMSerializer.h // -// $Id: //poco/svn/XML/include/Poco/DOM/DOMSerializer.h#2 $ +// $Id: //poco/svn/XML/include/Poco/DOM/DOMSerializer.h#3 $ // // Library: XML // Package: DOM @@ -109,6 +109,10 @@ protected: /// The DOMSerializer cannot parse from a system identifier, /// so this method simply throws an XMLException when invoked. + void parseMemoryNP(const char* xml, std::size_t size); + /// The DOMSerializer cannot parse from a system identifier, + /// so this method simply throws an XMLException when invoked. + void iterate(const Node* pNode) const; void handleNode(const Node* pNode) const; void handleElement(const Element* pElement) const; diff --git a/XML/include/Poco/DOM/Element.h b/XML/include/Poco/DOM/Element.h index 046eef4e2..d3a8e802f 100644 --- a/XML/include/Poco/DOM/Element.h +++ b/XML/include/Poco/DOM/Element.h @@ -1,7 +1,7 @@ // // Element.h // -// $Id: //poco/svn/XML/include/Poco/DOM/Element.h#2 $ +// $Id: //poco/svn/XML/include/Poco/DOM/Element.h#3 $ // // Library: XML // Package: DOM @@ -101,6 +101,13 @@ public: /// Adds a new attribute. If an attribute with that name is already /// present in the element, it is replaced by the new one. + Attr* addAttributeNodeNP(Attr* oldAttr, Attr* newAttr); + /// For internal use only. + /// Adds a new attribute after oldAttr. + /// If oldAttr is 0, newAttr is set as first attribute. + /// Returns newAttr. + /// Does not fire any events. + Attr* removeAttributeNode(Attr* oldAttr); /// Removes the specified attribute. diff --git a/XML/include/Poco/SAX/Attributes.h b/XML/include/Poco/SAX/Attributes.h index fdaae9d3c..46b5d5a7b 100644 --- a/XML/include/Poco/SAX/Attributes.h +++ b/XML/include/Poco/SAX/Attributes.h @@ -1,7 +1,7 @@ // // Attributes.h // -// $Id: //poco/svn/XML/include/Poco/SAX/Attributes.h#2 $ +// $Id: //poco/svn/XML/include/Poco/SAX/Attributes.h#3 $ // // Library: XML // Package: SAX @@ -83,13 +83,13 @@ public: /// /// Once you know the number of attributes, you can iterate through the list. - virtual XMLString getLocalName(int i) const = 0; + virtual const XMLString& getLocalName(int i) const = 0; /// Look up a local attribute name by index. - virtual XMLString getQName(int i) const = 0; + virtual const XMLString& getQName(int i) const = 0; /// Look up a qualified attribute name by index. - virtual XMLString getType(int i) const = 0; + virtual const XMLString& getType(int i) const = 0; /// Look up an attribute type by index. /// /// The attribute type is one of the strings "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", @@ -102,33 +102,33 @@ public: /// For an enumerated attribute that is not a notation, the parser will report the type /// as "NMTOKEN". - virtual XMLString getType(const XMLString& qname) const = 0; + virtual const XMLString& getType(const XMLString& qname) const = 0; /// Look up an attribute type by a qualified name. /// /// See getType(int) for a description of the possible types. - virtual XMLString getType(const XMLString& namespaceURI, const XMLString& localName) const = 0; + virtual const XMLString& getType(const XMLString& namespaceURI, const XMLString& localName) const = 0; /// Look up an attribute type by a namespace name. /// /// See getType(int) for a description of the possible types. - virtual XMLString getValue(int i) const = 0; + virtual const XMLString& getValue(int i) const = 0; /// Look up an attribute value by index. /// /// If the attribute value is a list of tokens (IDREFS, ENTITIES, or NMTOKENS), the tokens /// will be concatenated into a single string with each token separated by a single space. - virtual XMLString getValue(const XMLString& qname) const = 0; + virtual const XMLString& getValue(const XMLString& qname) const = 0; /// Look up an attribute value by a qualified name. /// /// See getValue(int) for a description of the possible values. - virtual XMLString getValue(const XMLString& uri, const XMLString& localName) const = 0; + virtual const XMLString& getValue(const XMLString& uri, const XMLString& localName) const = 0; /// Look up an attribute value by a namespace name. /// /// See getValue(int) for a description of the possible values. - virtual XMLString getURI(int i) const = 0; + virtual const XMLString& getURI(int i) const = 0; /// Look up a namespace URI by index. protected: diff --git a/XML/include/Poco/SAX/AttributesImpl.h b/XML/include/Poco/SAX/AttributesImpl.h index c91dc8632..cc1ec12be 100644 --- a/XML/include/Poco/SAX/AttributesImpl.h +++ b/XML/include/Poco/SAX/AttributesImpl.h @@ -1,7 +1,7 @@ // // AttributesImpl.h // -// $Id: //poco/svn/XML/include/Poco/SAX/AttributesImpl.h#2 $ +// $Id: //poco/svn/XML/include/Poco/SAX/AttributesImpl.h#3 $ // // Library: XML // Package: SAX @@ -58,6 +58,18 @@ class XML_API AttributesImpl: public Attributes /// 2. to construct or modify an Attributes object in a SAX2 driver or filter. { public: + struct Attribute + { + XMLString localName; + XMLString namespaceURI; + XMLString qname; + XMLString value; + XMLString type; + bool specified; + }; + typedef std::vector AttributeVec; + typedef AttributeVec::const_iterator iterator; + AttributesImpl(); /// Creates the AttributesImpl. @@ -76,15 +88,15 @@ public: int getIndex(const XMLString& name) const; int getIndex(const XMLString& namespaceURI, const XMLString& localName) const; int getLength() const; - XMLString getLocalName(int i) const; - XMLString getQName(int i) const; - XMLString getType(int i) const; - XMLString getType(const XMLString& qname) const; - XMLString getType(const XMLString& namespaceURI, const XMLString& localName) const; - XMLString getValue(int i) const; - XMLString getValue(const XMLString& qname) const; - XMLString getValue(const XMLString& namespaceURI, const XMLString& localName) const; - XMLString getURI(int i) const; + const XMLString& getLocalName(int i) const; + const XMLString& getQName(int i) const; + const XMLString& getType(int i) const; + const XMLString& getType(const XMLString& qname) const; + const XMLString& getType(const XMLString& namespaceURI, const XMLString& localName) const; + const XMLString& getValue(int i) const; + const XMLString& getValue(const XMLString& qname) const; + const XMLString& getValue(const XMLString& namespaceURI, const XMLString& localName) const; + const XMLString& getURI(int i) const; bool isSpecified(int i) const; /// Returns true unless the attribute value was provided by DTD defaulting. @@ -122,6 +134,11 @@ public: void addAttribute(const XMLChar* namespaceURI, const XMLChar* localName, const XMLChar* qname, const XMLChar* type, const XMLChar* value, bool specified); /// Adds an attribute to the end of the list. + Attribute& addAttribute(); + /// Add an (empty) attribute to the end of the list. + /// For internal use only. + /// The returned Attribute element must be filled by the caller. + void removeAttribute(int i); /// Removes an attribute. @@ -133,6 +150,9 @@ public: void clear(); /// Removes all attributes. + + void reserve(std::size_t capacity); + /// Reserves capacity in the internal vector. void setLocalName(int i, const XMLString& localName); /// Sets the local name of an attribute. @@ -146,18 +166,6 @@ public: void setURI(int i, const XMLString& namespaceURI); /// Sets the namespace URI of an attribute. - struct Attribute - { - XMLString localName; - XMLString namespaceURI; - XMLString qname; - XMLString value; - XMLString type; - bool specified; - }; - typedef std::vector AttributeVec; - typedef AttributeVec::const_iterator iterator; - iterator begin() const; /// Iterator support. @@ -170,6 +178,7 @@ protected: private: AttributeVec _attributes; + Attribute _empty; }; @@ -188,6 +197,121 @@ inline AttributesImpl::iterator AttributesImpl::end() const } +inline AttributesImpl::Attribute& AttributesImpl::addAttribute() +{ + _attributes.push_back(_empty); + return _attributes.back(); +} + + +inline int AttributesImpl::getLength() const +{ + return (int) _attributes.size(); +} + + +inline const XMLString& AttributesImpl::getLocalName(int i) const +{ + poco_assert (i < _attributes.size()); + return _attributes[i].localName; +} + + +inline const XMLString& AttributesImpl::getQName(int i) const +{ + poco_assert (i < _attributes.size()); + return _attributes[i].qname; +} + + +inline const XMLString& AttributesImpl::getType(int i) const +{ + poco_assert (i < _attributes.size()); + return _attributes[i].type; +} + + +inline const XMLString& AttributesImpl::getType(const XMLString& qname) const +{ + Attribute* pAttr = find(qname); + if (pAttr) + return pAttr->type; + else + return _empty.type; +} + + +inline const XMLString& AttributesImpl::getType(const XMLString& namespaceURI, const XMLString& localName) const +{ + Attribute* pAttr = find(namespaceURI, localName); + if (pAttr) + return pAttr->type; + else + return _empty.type; +} + + +inline const XMLString& AttributesImpl::getValue(int i) const +{ + poco_assert (i < _attributes.size()); + return _attributes[i].value; +} + + +inline const XMLString& AttributesImpl::getValue(const XMLString& qname) const +{ + Attribute* pAttr = find(qname); + if (pAttr) + return pAttr->value; + else + return _empty.value; +} + + +inline const XMLString& AttributesImpl::getValue(const XMLString& namespaceURI, const XMLString& localName) const +{ + Attribute* pAttr = find(namespaceURI, localName); + if (pAttr) + return pAttr->value; + else + return _empty.value; +} + + +inline const XMLString& AttributesImpl::getURI(int i) const +{ + poco_assert (i < _attributes.size()); + return _attributes[i].namespaceURI; +} + + +inline bool AttributesImpl::isSpecified(int i) const +{ + poco_assert (i < _attributes.size()); + return _attributes[i].specified; +} + + +inline bool AttributesImpl::isSpecified(const XMLString& qname) const +{ + Attribute* pAttr = find(qname); + if (pAttr) + return pAttr->specified; + else + return false; +} + + +inline bool AttributesImpl::isSpecified(const XMLString& namespaceURI, const XMLString& localName) const +{ + Attribute* pAttr = find(namespaceURI, localName); + if (pAttr) + return pAttr->specified; + else + return false; +} + + } } // namespace Poco::XML diff --git a/XML/include/Poco/SAX/SAXParser.h b/XML/include/Poco/SAX/SAXParser.h index e5e8aa456..b351366fd 100644 --- a/XML/include/Poco/SAX/SAXParser.h +++ b/XML/include/Poco/SAX/SAXParser.h @@ -1,7 +1,7 @@ // // SAXParser.h // -// $Id: //poco/svn/XML/include/Poco/SAX/SAXParser.h#2 $ +// $Id: //poco/svn/XML/include/Poco/SAX/SAXParser.h#3 $ // // Library: XML // Package: SAX @@ -98,6 +98,7 @@ public: void* getProperty(const XMLString& propertyId) const; void parse(InputSource* pSource); void parse(const XMLString& systemId); + void parseMemoryNP(const char* xml, std::size_t size); /// Extensions void parseString(const std::string& xml); diff --git a/XML/include/Poco/SAX/XMLFilterImpl.h b/XML/include/Poco/SAX/XMLFilterImpl.h index fe1941339..41d706c8f 100644 --- a/XML/include/Poco/SAX/XMLFilterImpl.h +++ b/XML/include/Poco/SAX/XMLFilterImpl.h @@ -1,7 +1,7 @@ // // XMLFilterImpl.h // -// $Id: //poco/svn/XML/include/Poco/SAX/XMLFilterImpl.h#2 $ +// $Id: //poco/svn/XML/include/Poco/SAX/XMLFilterImpl.h#3 $ // // Library: XML // Package: SAX @@ -94,6 +94,7 @@ public: void* getProperty(const XMLString& propertyId) const; void parse(InputSource* pSource); void parse(const XMLString& systemId); + void parseMemoryNP(const char* xml, std::size_t size); // EntityResolver InputSource* resolveEntity(const XMLString* publicId, const XMLString& systemId); diff --git a/XML/include/Poco/SAX/XMLReader.h b/XML/include/Poco/SAX/XMLReader.h index b1a40ae6f..e4636dd69 100644 --- a/XML/include/Poco/SAX/XMLReader.h +++ b/XML/include/Poco/SAX/XMLReader.h @@ -1,7 +1,7 @@ // // XMLReader.h // -// $Id: //poco/svn/XML/include/Poco/SAX/XMLReader.h#2 $ +// $Id: //poco/svn/XML/include/Poco/SAX/XMLReader.h#3 $ // // Library: XML // Package: SAX @@ -199,6 +199,10 @@ public: virtual void parse(const XMLString& systemId) = 0; /// Parse an XML document from a system identifier. /// See also parse(InputSource*). + + virtual void parseMemoryNP(const char* xml, std::size_t size) = 0; + /// Parse an XML document from memory. + /// See also parse(InputSource*). // SAX Features static const XMLString FEATURE_VALIDATION; diff --git a/XML/include/Poco/XML/NamespaceStrategy.h b/XML/include/Poco/XML/NamespaceStrategy.h index 8a2bcbf0e..c2193bf8a 100644 --- a/XML/include/Poco/XML/NamespaceStrategy.h +++ b/XML/include/Poco/XML/NamespaceStrategy.h @@ -1,7 +1,7 @@ // // NamespaceStrategy.h // -// $Id: //poco/svn/XML/include/Poco/XML/NamespaceStrategy.h#2 $ +// $Id: //poco/svn/XML/include/Poco/XML/NamespaceStrategy.h#3 $ // // Library: XML // Package: XML @@ -43,6 +43,7 @@ #include "Poco/XML/XML.h" #include "Poco/XML/XMLString.h" #include "Poco/SAX/NamespaceSupport.h" +#include "Poco/SAX/AttributesImpl.h" namespace Poco { @@ -73,8 +74,6 @@ protected: static void splitName(const XMLChar* qname, XMLString& uri, XMLString& localName, XMLString& prefix); static const XMLString NOTHING; - static const XMLString CDATA; - static const XMLString COLON; }; @@ -88,6 +87,10 @@ public: void startElement(const XMLChar* name, const XMLChar** atts, int specifiedCount, ContentHandler* pContentHandler); void endElement(const XMLChar* name, ContentHandler* pContentHandler); + +private: + XMLString _name; + AttributesImpl _attrs; }; @@ -101,6 +104,11 @@ public: void startElement(const XMLChar* name, const XMLChar** atts, int specifiedCount, ContentHandler* pContentHandler); void endElement(const XMLChar* name, ContentHandler* pContentHandler); + +private: + XMLString _uri; + XMLString _local; + AttributesImpl _attrs; }; @@ -114,6 +122,12 @@ public: void startElement(const XMLChar* name, const XMLChar** atts, int specifiedCount, ContentHandler* pContentHandler); void endElement(const XMLChar* name, ContentHandler* pContentHandler); + +private: + XMLString _uri; + XMLString _local; + XMLString _qname; + AttributesImpl _attrs; }; diff --git a/XML/include/Poco/XML/ParserEngine.h b/XML/include/Poco/XML/ParserEngine.h index 86c0a5100..5445927e9 100644 --- a/XML/include/Poco/XML/ParserEngine.h +++ b/XML/include/Poco/XML/ParserEngine.h @@ -1,7 +1,7 @@ // // ParserEngine.h // -// $Id: //poco/svn/XML/include/Poco/XML/ParserEngine.h#2 $ +// $Id: //poco/svn/XML/include/Poco/XML/ParserEngine.h#3 $ // // Library: XML // Package: XML @@ -163,6 +163,9 @@ public: void parse(InputSource* pInputSource); /// Parse an XML document from the given InputSource. + + void parse(const char* pBuffer, std::size_t size); + /// Parses an XML document from the given buffer. // Locator XMLString getPublicId() const; diff --git a/XML/src/AttributesImpl.cpp b/XML/src/AttributesImpl.cpp index 34e8c4e29..cf4e49326 100644 --- a/XML/src/AttributesImpl.cpp +++ b/XML/src/AttributesImpl.cpp @@ -1,7 +1,7 @@ // // AttributesImpl.cpp // -// $Id: //poco/svn/XML/src/AttributesImpl.cpp#2 $ +// $Id: //poco/svn/XML/src/AttributesImpl.cpp#3 $ // // Library: XML // Package: SAX @@ -43,18 +43,23 @@ namespace XML { AttributesImpl::AttributesImpl() { + _empty.specified = false; + _empty.type = "CDATA"; } AttributesImpl::AttributesImpl(const Attributes& attributes) { + _empty.specified = false; + _empty.type = "CDATA"; setAttributes(attributes); } -AttributesImpl::AttributesImpl(const AttributesImpl& attributes) +AttributesImpl::AttributesImpl(const AttributesImpl& attributes): + _attributes(attributes._attributes), + _empty(attributes._empty) { - setAttributes(attributes); } @@ -99,114 +104,6 @@ int AttributesImpl::getIndex(const XMLString& namespaceURI, const XMLString& loc } -int AttributesImpl::getLength() const -{ - return (int) _attributes.size(); -} - - -XMLString AttributesImpl::getLocalName(int i) const -{ - poco_assert (i < _attributes.size()); - return _attributes[i].localName; -} - - -XMLString AttributesImpl::getQName(int i) const -{ - poco_assert (i < _attributes.size()); - return _attributes[i].qname; -} - - -XMLString AttributesImpl::getType(int i) const -{ - poco_assert (i < _attributes.size()); - return _attributes[i].type; -} - - -XMLString AttributesImpl::getType(const XMLString& qname) const -{ - Attribute* pAttr = find(qname); - if (pAttr) - return pAttr->type; - else - return XMLString(); -} - - -XMLString AttributesImpl::getType(const XMLString& namespaceURI, const XMLString& localName) const -{ - Attribute* pAttr = find(namespaceURI, localName); - if (pAttr) - return pAttr->type; - else - return XMLString(); -} - - -XMLString AttributesImpl::getValue(int i) const -{ - poco_assert (i < _attributes.size()); - return _attributes[i].value; -} - - -XMLString AttributesImpl::getValue(const XMLString& qname) const -{ - Attribute* pAttr = find(qname); - if (pAttr) - return pAttr->value; - else - return XMLString(); -} - - -XMLString AttributesImpl::getValue(const XMLString& namespaceURI, const XMLString& localName) const -{ - Attribute* pAttr = find(namespaceURI, localName); - if (pAttr) - return pAttr->value; - else - return XMLString(); -} - - -XMLString AttributesImpl::getURI(int i) const -{ - poco_assert (i < _attributes.size()); - return _attributes[i].namespaceURI; -} - - -bool AttributesImpl::isSpecified(int i) const -{ - poco_assert (i < _attributes.size()); - return _attributes[i].specified; -} - - -bool AttributesImpl::isSpecified(const XMLString& qname) const -{ - Attribute* pAttr = find(qname); - if (pAttr) - return pAttr->specified; - else - return false; -} - - -bool AttributesImpl::isSpecified(const XMLString& namespaceURI, const XMLString& localName) const -{ - Attribute* pAttr = find(namespaceURI, localName); - if (pAttr) - return pAttr->specified; - else - return false; -} - - void AttributesImpl::setValue(int i, const XMLString& value) { poco_assert (i < _attributes.size()); @@ -346,6 +243,12 @@ void AttributesImpl::clear() } +void AttributesImpl::reserve(std::size_t capacity) +{ + _attributes.reserve(capacity); +} + + void AttributesImpl::setLocalName(int i, const XMLString& localName) { poco_assert (i < _attributes.size()); diff --git a/XML/src/DOMBuilder.cpp b/XML/src/DOMBuilder.cpp index 2519ce175..b79f46957 100644 --- a/XML/src/DOMBuilder.cpp +++ b/XML/src/DOMBuilder.cpp @@ -1,7 +1,7 @@ // // DOMBuilder.cpp // -// $Id: //poco/svn/XML/src/DOMBuilder.cpp#2 $ +// $Id: //poco/svn/XML/src/DOMBuilder.cpp#3 $ // // Library: XML // Package: DOM @@ -126,6 +126,28 @@ Document* DOMBuilder::parse(InputSource* pInputSource) } +Document* DOMBuilder::parseMemoryNP(const char* xml, std::size_t size) +{ + setupParse(); + _pDocument->suspendEvents(); + try + { + _xmlReader.parseMemoryNP(xml, size); + } + catch (...) + { + _pDocument->release(); + _pDocument = 0; + _pParent = 0; + _pPrevious = 0; + throw; + } + _pDocument->resumeEvents(); + _pDocument->collectGarbage(); + return _pDocument; +} + + void DOMBuilder::setupParse() { _pDocument = new Document(_pNamePool); @@ -191,13 +213,11 @@ void DOMBuilder::startElement(const XMLString& uri, const XMLString& localName, AutoPtr pElem = _namespaces ? _pDocument->createElementNS(uri, qname.empty() ? localName : qname) : _pDocument->createElement(qname); const AttributesImpl& attrs = dynamic_cast(attributes); + Attr* pPrevAttr = 0; for (AttributesImpl::iterator it = attrs.begin(); it != attrs.end(); ++it) { AutoPtr pAttr = new Attr(_pDocument, 0, it->namespaceURI, it->localName, it->qname, it->value, it->specified); - if (_namespaces) - pElem->setAttributeNodeNS(pAttr); - else - pElem->setAttributeNode(pAttr); + pPrevAttr = pElem->addAttributeNodeNP(pPrevAttr, pAttr); } appendNode(pElem); _pParent = pElem; diff --git a/XML/src/DOMParser.cpp b/XML/src/DOMParser.cpp index 81ab49b4a..7f8138859 100644 --- a/XML/src/DOMParser.cpp +++ b/XML/src/DOMParser.cpp @@ -1,7 +1,7 @@ // // DOMParser.cpp // -// $Id: //poco/svn/XML/src/DOMParser.cpp#2 $ +// $Id: //poco/svn/XML/src/DOMParser.cpp#3 $ // // Library: XML // Package: DOM @@ -135,9 +135,23 @@ Document* DOMParser::parse(InputSource* pInputSource) Document* DOMParser::parseString(const std::string& xml) { - std::istringstream istr(xml); - InputSource src(istr); - return parse(&src); + return parseMemory(xml.data(), xml.size()); +} + + +Document* DOMParser::parseMemory(const char* xml, std::size_t size) +{ + if (_whitespace) + { + DOMBuilder builder(_saxParser, _pNamePool); + return builder.parseMemoryNP(xml, size); + } + else + { + WhitespaceFilter filter(&_saxParser); + DOMBuilder builder(filter, _pNamePool); + return builder.parseMemoryNP(xml, size); + } } diff --git a/XML/src/DOMSerializer.cpp b/XML/src/DOMSerializer.cpp index d8d8cb9d3..b29ec47af 100644 --- a/XML/src/DOMSerializer.cpp +++ b/XML/src/DOMSerializer.cpp @@ -1,7 +1,7 @@ // // DOMSerializer.cpp // -// $Id: //poco/svn/XML/src/DOMSerializer.cpp#2 $ +// $Id: //poco/svn/XML/src/DOMSerializer.cpp#3 $ // // Library: XML // Package: DOM @@ -199,6 +199,12 @@ void DOMSerializer::parse(const XMLString& systemId) } +void DOMSerializer::parseMemoryNP(const char* xml, std::size_t size) +{ + throw XMLException("The DOMSerializer cannot parse from memory"); +} + + void DOMSerializer::iterate(const Node* pNode) const { while (pNode) diff --git a/XML/src/Element.cpp b/XML/src/Element.cpp index cca6c52ed..b99cd17c0 100644 --- a/XML/src/Element.cpp +++ b/XML/src/Element.cpp @@ -1,7 +1,7 @@ // // Element.cpp // -// $Id: //poco/svn/XML/src/Element.cpp#2 $ +// $Id: //poco/svn/XML/src/Element.cpp#3 $ // // Library: XML // Package: DOM @@ -173,6 +173,27 @@ Attr* Element::removeAttributeNode(Attr* oldAttr) } +Attr* Element::addAttributeNodeNP(Attr* oldAttr, Attr* newAttr) +{ + newAttr->_pParent = this; + if (oldAttr) + { + oldAttr->_pNext = newAttr; + } + else if (_pFirstAttr) + { + newAttr->_pNext = _pFirstAttr; + _pFirstAttr = newAttr; + } + else + { + _pFirstAttr = newAttr; + } + newAttr->duplicate(); + return newAttr; +} + + NodeList* Element::getElementsByTagName(const XMLString& name) const { return new ElementsByTagNameList(this, name); diff --git a/XML/src/NamespaceStrategy.cpp b/XML/src/NamespaceStrategy.cpp index accbc0143..6103a1c03 100644 --- a/XML/src/NamespaceStrategy.cpp +++ b/XML/src/NamespaceStrategy.cpp @@ -1,7 +1,7 @@ // // NamespaceStrategy.cpp // -// $Id: //poco/svn/XML/src/NamespaceStrategy.cpp#2 $ +// $Id: //poco/svn/XML/src/NamespaceStrategy.cpp#3 $ // // Library: XML // Package: XML @@ -46,8 +46,6 @@ namespace XML { const XMLString NamespaceStrategy::NOTHING; -const XMLString NamespaceStrategy::CDATA = toXMLString("CDATA"); -const XMLString NamespaceStrategy::COLON = toXMLString(":"); NamespaceStrategy::~NamespaceStrategy() @@ -83,13 +81,21 @@ void NamespaceStrategy::splitName(const XMLChar* qname, XMLString& uri, XMLStrin localName.assign(loc, p - loc); if (*p) prefix.assign(++p); + else + prefix.assign(""); } - else localName = qname; + else + { + uri.assign(""); + localName = qname; + prefix.assign(""); + } } NoNamespacesStrategy::NoNamespacesStrategy() { + _attrs.reserve(32); } @@ -102,14 +108,16 @@ void NoNamespacesStrategy::startElement(const XMLChar* name, const XMLChar** att { poco_assert_dbg (name && atts && pContentHandler); - AttributesImpl attributes; + _attrs.clear(); for (int i = 0; *atts; ++i) { - const XMLChar* attrName = *atts++; - const XMLChar* attrValue = *atts++; - attributes.addAttribute(NOTHING, NOTHING, attrName, CDATA, attrValue, i < specifiedCount); + AttributesImpl::Attribute& attr = _attrs.addAttribute(); + attr.qname.assign(*atts++); + attr.value.assign(*atts++); + attr.specified = i < specifiedCount; } - pContentHandler->startElement(NOTHING, NOTHING, name, attributes); + _name.assign(name); + pContentHandler->startElement(NOTHING, NOTHING, _name, _attrs); } @@ -117,12 +125,14 @@ void NoNamespacesStrategy::endElement(const XMLChar* name, ContentHandler* pCont { poco_assert_dbg (name && pContentHandler); - pContentHandler->endElement(NOTHING, NOTHING, name); + _name.assign(name); + pContentHandler->endElement(NOTHING, NOTHING, _name); } NoNamespacePrefixesStrategy::NoNamespacePrefixesStrategy() { + _attrs.reserve(32); } @@ -135,20 +145,18 @@ void NoNamespacePrefixesStrategy::startElement(const XMLChar* name, const XMLCha { poco_assert_dbg (name && atts && pContentHandler); - AttributesImpl attributes; + _attrs.clear(); for (int i = 0; *atts; ++i) { const XMLChar* attrName = *atts++; const XMLChar* attrValue = *atts++; - XMLString attrURI; - XMLString attrLocal; - splitName(attrName, attrURI, attrLocal); - attributes.addAttribute(attrURI, attrLocal, NOTHING, CDATA, attrValue, i < specifiedCount); + AttributesImpl::Attribute& attr = _attrs.addAttribute(); + splitName(attrName, attr.namespaceURI, attr.localName); + attr.value.assign(attrValue); + attr.specified = i < specifiedCount; } - XMLString uri; - XMLString local; - splitName(name, uri, local); - pContentHandler->startElement(uri, local, NOTHING, attributes); + splitName(name, _uri, _local); + pContentHandler->startElement(_uri, _local, NOTHING, _attrs); } @@ -156,15 +164,14 @@ void NoNamespacePrefixesStrategy::endElement(const XMLChar* name, ContentHandler { poco_assert_dbg (name && pContentHandler); - XMLString uri; - XMLString local; - splitName(name, uri, local); - pContentHandler->endElement(uri, local, NOTHING); + splitName(name, _uri, _local); + pContentHandler->endElement(_uri, _local, NOTHING); } NamespacePrefixesStrategy::NamespacePrefixesStrategy() { + _attrs.reserve(32); } @@ -177,26 +184,22 @@ void NamespacePrefixesStrategy::startElement(const XMLChar* name, const XMLChar* { poco_assert_dbg (name && atts && pContentHandler); - AttributesImpl attributes; + _attrs.clear(); for (int i = 0; *atts; ++i) { const XMLChar* attrName = *atts++; const XMLChar* attrValue = *atts++; - XMLString attrURI; - XMLString attrLocal; - XMLString attrQName; - splitName(attrName, attrURI, attrLocal, attrQName); - if (!attrQName.empty()) attrQName += ':'; - attrQName.append(attrLocal); - attributes.addAttribute(attrURI, attrLocal, attrQName, CDATA, attrValue, i < specifiedCount); + AttributesImpl::Attribute& attr = _attrs.addAttribute(); + splitName(attrName, attr.namespaceURI, attr.localName, attr.qname); + if (!attr.qname.empty()) attr.qname += ':'; + attr.qname.append(attr.localName); + attr.value.assign(attrValue); + attr.specified = i < specifiedCount; } - XMLString uri; - XMLString local; - XMLString qname; - splitName(name, uri, local, qname); - if (!qname.empty()) qname += ':'; - qname.append(local); - pContentHandler->startElement(uri, local, qname, attributes); + splitName(name, _uri, _local, _qname); + if (!_qname.empty()) _qname += ':'; + _qname.append(_local); + pContentHandler->startElement(_uri, _local, _qname, _attrs); } @@ -204,13 +207,10 @@ void NamespacePrefixesStrategy::endElement(const XMLChar* name, ContentHandler* { poco_assert_dbg (name && pContentHandler); - XMLString uri; - XMLString local; - XMLString qname; - splitName(name, uri, local, qname); - if (!qname.empty()) qname += ':'; - qname.append(local); - pContentHandler->endElement(uri, local, qname); + splitName(name, _uri, _local, _qname); + if (!_qname.empty()) _qname += ':'; + _qname.append(_local); + pContentHandler->endElement(_uri, _local, _qname); } diff --git a/XML/src/ParserEngine.cpp b/XML/src/ParserEngine.cpp index bb0b289ee..4f2e628d4 100644 --- a/XML/src/ParserEngine.cpp +++ b/XML/src/ParserEngine.cpp @@ -1,7 +1,7 @@ // // ParserEngine.cpp // -// $Id: //poco/svn/XML/src/ParserEngine.cpp#2 $ +// $Id: //poco/svn/XML/src/ParserEngine.cpp#3 $ // // Library: XML // Package: XML @@ -249,6 +249,21 @@ void ParserEngine::parse(InputSource* pInputSource) } +void ParserEngine::parse(const char* pBuffer, std::size_t size) +{ + init(); + resetContext(); + InputSource src; + pushContext(_parser, &src); + if (_pContentHandler) _pContentHandler->setDocumentLocator(this); + if (_pContentHandler) _pContentHandler->startDocument(); + if (!XML_Parse(_parser, pBuffer, static_cast(size), 1)) + handleError(XML_GetErrorCode(_parser)); + if (_pContentHandler) _pContentHandler->endDocument(); + popContext(); +} + + void ParserEngine::parseByteInputStream(XMLByteInputStream& istr) { istr.read(_pBuffer, PARSE_BUFFER_SIZE); diff --git a/XML/src/SAXParser.cpp b/XML/src/SAXParser.cpp index 56fbfe55d..80880cac0 100644 --- a/XML/src/SAXParser.cpp +++ b/XML/src/SAXParser.cpp @@ -1,7 +1,7 @@ // // SAXParser.cpp // -// $Id: //poco/svn/XML/src/SAXParser.cpp#2 $ +// $Id: //poco/svn/XML/src/SAXParser.cpp#3 $ // // Library: XML // Package: SAX @@ -228,9 +228,14 @@ void SAXParser::parse(const XMLString& systemId) void SAXParser::parseString(const std::string& xml) { - std::istringstream istr(xml); - InputSource src(istr); - parse(&src); + parseMemoryNP(xml.data(), xml.size()); +} + + +void SAXParser::parseMemoryNP(const char* xml, std::size_t size) +{ + setupParse(); + _engine.parse(xml, size); } diff --git a/XML/src/XMLFilterImpl.cpp b/XML/src/XMLFilterImpl.cpp index 94e828287..939f9d614 100644 --- a/XML/src/XMLFilterImpl.cpp +++ b/XML/src/XMLFilterImpl.cpp @@ -1,7 +1,7 @@ // // XMLFilterImpl.cpp // -// $Id: //poco/svn/XML/src/XMLFilterImpl.cpp#2 $ +// $Id: //poco/svn/XML/src/XMLFilterImpl.cpp#3 $ // // Library: XML // Package: SAX @@ -186,6 +186,13 @@ void XMLFilterImpl::parse(const XMLString& systemId) } +void XMLFilterImpl::parseMemoryNP(const char* xml, std::size_t size) +{ + setupParse(); + _pParent->parseMemoryNP(xml, size); +} + + InputSource* XMLFilterImpl::resolveEntity(const XMLString* publicId, const XMLString& systemId) { if (_pEntityResolver)