From ccbd23d20abdc055260654889f50b064e4ce5085 Mon Sep 17 00:00:00 2001 From: DennisPopovDn Date: Sat, 22 Aug 2015 16:10:17 +0300 Subject: [PATCH 1/4] Fixed Windows VS2013 compilation --- .../Windows/ReadiumSDK/ReadiumSDK.vcxproj | 401 ++++++++++++++---- .../Windows/ReadiumSDK/ePub3/ePub3.vcxproj | 24 +- .../ReadiumSDK/ePub3/ePub3.vcxproj.filters | 66 +++ ePub3/ThirdParty/google-url/base/logging.h | 12 +- ePub3/ePub/PassThroughFilter.h | 2 +- ePub3/ePub/filter_chain.cpp | 2 +- ePub3/ePub/font_obfuscation.cpp | 1 + ePub3/utilities/integer_sequence.h | 2 + ePub3/utilities/iri.cpp | 8 +- ePub3/utilities/optional.h | 2 +- ePub3/utilities/ref_counted.cpp | 4 +- ePub3/utilities/run_loop_windows.cpp | 2 +- 12 files changed, 423 insertions(+), 103 deletions(-) diff --git a/Platform/Windows/ReadiumSDK/ReadiumSDK.vcxproj b/Platform/Windows/ReadiumSDK/ReadiumSDK.vcxproj index 9b0a5b21e..ed9ab562e 100644 --- a/Platform/Windows/ReadiumSDK/ReadiumSDK.vcxproj +++ b/Platform/Windows/ReadiumSDK/ReadiumSDK.vcxproj @@ -13,20 +13,23 @@ {033B6AAA-D741-4696-B687-F5BA0520436F} ReadiumSDK + ePub3 - Application + DynamicLibrary true - v110 - MultiByte + v120 + Unicode + Dynamic - Application + StaticLibrary false - v110 + v120 true - MultiByte + Unicode + Dynamic @@ -38,15 +41,36 @@ - + + C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath) + C:\Program Files %28x86%29\Visual Leak Detector\lib\Win32;$(LibraryPath) + Level3 Disabled + $(MSBuildProjectDirectory)\include;$(MSBuildProjectDirectory)\..\..\ePub3;$(MSBuildProjectDirectory)\..\..\ePub3\utilities;$(MSBuildProjectDirectory)\..\..\ePub3\ePub;$(MSBuildProjectDirectory)\..\..\ePub3\xml;$(MSBuildProjectDirectory)\Prebuilt\Include;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty\google-url\src;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty\utf8-cpp\include;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty\icu4c\include;$(MSBuildProjectDirectory)\..\..\Platform\Windows\include\libzip + HAVE_CONFIG_H;WIN32;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;BUILDING_EPUB3;_DEBUG;_LIB;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + NotUsing + true + true + true + false + StreamingSIMDExtensions2 + true + CompileAsCpp true + $(MSBuildProjectDirectory)\Prebuilt\Lib\x86\libxml2_a.lib;$(MSBuildProjectDirectory)\Prebuilt\Lib\x86\zlib.lib;Advapi32.lib;ws2_32.lib;%(AdditionalDependencies) + + cd $(MSBuildProjectDirectory) +cscript MakeHeaders.js + + + Build canonical headers + @@ -54,97 +78,302 @@ MaxSpeed true true + WIN32;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;BUILDING_EPUB3;NDEBUG;_LIB;HAVE_CONFIG_H;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + NotUsing + $(MSBuildProjectDirectory)\include;$(MSBuildProjectDirectory)\..\..\ePub3;$(MSBuildProjectDirectory)\..\..\ePub3\utilities;$(MSBuildProjectDirectory)\..\..\ePub3\ePub;$(MSBuildProjectDirectory)\..\..\ePub3\xml;$(MSBuildProjectDirectory)\Prebuilt\Include;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty\google-url\src;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty\utf8-cpp\include;$(MSBuildProjectDirectory)\..\..\ePub3\ThirdParty\icu4c\include;$(MSBuildProjectDirectory)\..\..\Platform\Windows\include\libzip;%(AdditionalIncludeDirectories) true true true + + cd $(MSBuildProjectDirectory) +cscript MakeHeaders.js + + + Build canonical headers + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj b/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj index f5571dbcb..7c24917ee 100644 --- a/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj +++ b/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj @@ -27,7 +27,7 @@ DynamicLibrary true - v110 + v120 Unicode @@ -261,16 +261,29 @@ cscript MakeHeaders.js + + + + + + + + + + + + + @@ -323,6 +336,8 @@ cscript MakeHeaders.js + + @@ -352,9 +367,16 @@ cscript MakeHeaders.js + + + + + + + diff --git a/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj.filters b/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj.filters index 8dbf59a90..bf4c2fd09 100644 --- a/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj.filters +++ b/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj.filters @@ -638,5 +638,71 @@ Source Files\ePub\Components\Properties + + Source Files\utilities + + + Source Files\utilities + + + Source Files\utilities + + + Source Files\utilities + + + Source Files\utilities + + + Source Files\utilities + + + Source Files\utilities + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ePub + + + Source Files\ThirdParty\libzip + + + Source Files\ThirdParty\libzip + \ No newline at end of file diff --git a/ePub3/ThirdParty/google-url/base/logging.h b/ePub3/ThirdParty/google-url/base/logging.h index 22c328618..ab75a2576 100644 --- a/ePub3/ThirdParty/google-url/base/logging.h +++ b/ePub3/ThirdParty/google-url/base/logging.h @@ -417,7 +417,7 @@ enum { DEBUG_MODE = 0 }; // above. class LogMessage { public: - LogMessage(const char* file, int line, LogSeverity severity, int ctr) {} + LogMessage(const char* file, int line, LogSeverity severity, int ctr);// {} // Two special constructors that generate reduced amounts of code at // LOG call sites for common cases. @@ -427,22 +427,22 @@ class LogMessage { // // Using this constructor instead of the more complex constructor above // saves a couple of bytes per call site. - LogMessage(const char* file, int line) {} + LogMessage(const char* file, int line);// {} // Used for LOG(severity) where severity != INFO. Implied // are: ctr = 0 // // Using this constructor instead of the more complex constructor above // saves a couple of bytes per call site. - LogMessage(const char* file, int line, LogSeverity severity) {} + LogMessage(const char* file, int line, LogSeverity severity);// {} // A special constructor used for check failures. // Implied severity = LOG_FATAL - LogMessage(const char* file, int line, const CheckOpString& result) {} + LogMessage(const char* file, int line, const CheckOpString& result);// {} - ~LogMessage() {} + ~LogMessage();// {} - std::ostream& stream() { return stream_; } + std::ostream& stream() { return stream_; } private: void Init(const char* file, int line); diff --git a/ePub3/ePub/PassThroughFilter.h b/ePub3/ePub/PassThroughFilter.h index c1c584e87..b00721d4e 100644 --- a/ePub3/ePub/PassThroughFilter.h +++ b/ePub3/ePub/PassThroughFilter.h @@ -26,7 +26,7 @@ #include #include REGEX_INCLUDE #include -#import +#include //#import EPUB3_BEGIN_NAMESPACE diff --git a/ePub3/ePub/filter_chain.cpp b/ePub3/ePub/filter_chain.cpp index 9cc26339c..6cd40ee5d 100644 --- a/ePub3/ePub/filter_chain.cpp +++ b/ePub3/ePub/filter_chain.cpp @@ -138,7 +138,7 @@ std::shared_ptr FilterChain::GetFilterChainByteStreamRange(ConstMani std::unique_ptr FilterChain::GetFilterChainByteStreamRange(ConstManifestItemPtr item, SeekableByteStream *rawInput) const { unique_ptr resultStream; - uint nFilters = 0; + int nFilters = 0; for (ContentFilterPtr filter : _filters) { if (filter->TypeSniffer()(item)) diff --git a/ePub3/ePub/font_obfuscation.cpp b/ePub3/ePub/font_obfuscation.cpp index 76789040c..577257b42 100644 --- a/ePub3/ePub/font_obfuscation.cpp +++ b/ePub3/ePub/font_obfuscation.cpp @@ -27,6 +27,7 @@ #elif EPUB_PLATFORM(WIN) #include #include +#include "error_handler.h" #elif EPUB_PLATFORM(WINRT) using namespace ::Platform; using namespace ::Windows::Security::Cryptography; diff --git a/ePub3/utilities/integer_sequence.h b/ePub3/utilities/integer_sequence.h index d9de89231..deb4af3d1 100644 --- a/ePub3/utilities/integer_sequence.h +++ b/ePub3/utilities/integer_sequence.h @@ -1,3 +1,4 @@ +#if 1 // // integer_sequence.h // ePub3 @@ -80,3 +81,4 @@ using make_index_sequence = make_integer_sequence; EPUB3_END_NAMESPACE #endif +#endif \ No newline at end of file diff --git a/ePub3/utilities/iri.cpp b/ePub3/utilities/iri.cpp index 3fe3a6a61..8bd31ce3c 100644 --- a/ePub3/utilities/iri.cpp +++ b/ePub3/utilities/iri.cpp @@ -44,7 +44,7 @@ void IRI::AddStandardScheme(const string& scheme) url_util::AddStandardScheme(scheme.c_str()); } -IRI::IRI(const string& iriStr) : _urnComponents(), _url(make_unique(iriStr.stl_str())), _pureIRI(iriStr) +IRI::IRI(const string& iriStr) : _urnComponents(), _url(ePub3::make_unique(iriStr.stl_str())), _pureIRI(iriStr) { // is it a URN? if ( iriStr.find("urn:", 0, 4) == 0 ) @@ -64,7 +64,7 @@ IRI::IRI(const string& nameID, const string& namespacedString) : _urnComponents({gURNScheme, nameID, namespacedString}), #endif _pureIRI(_Str("urn:", nameID, ":", namespacedString)), - _url(make_unique(_pureIRI.stl_str())) + _url(ePub3::make_unique(_pureIRI.stl_str())) { #if !EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS) _urnComponents.push_back(gURNScheme); @@ -87,7 +87,7 @@ IRI::IRI(const string& scheme, const string& host, const string& path, const str if ( !fragment.empty() ) _pureIRI += _Str("#", fragment); - _url = make_unique(_pureIRI.stl_str()); + _url = ePub3::make_unique(_pureIRI.stl_str()); } IRI::~IRI() { @@ -127,7 +127,7 @@ IRI& IRI::operator=(const string& str) } } - auto newURL = make_unique(str.stl_str()); + auto newURL = ePub3::make_unique(str.stl_str()); if ( !newURL->is_valid() && !isURN ) throw std::invalid_argument(_Str("IRI: '", str, "' is not a valid URL string.")); diff --git a/ePub3/utilities/optional.h b/ePub3/utilities/optional.h index c617730a9..f4e9555b6 100644 --- a/ePub3/utilities/optional.h +++ b/ePub3/utilities/optional.h @@ -208,7 +208,7 @@ void fail(const char* expr, const char* file, unsigned line) # elif defined(__GNUC__) || EPUB_PLATFORM(ANDROID) __assert(file, line, expr); # else -# warning I dont know how to fire assertion internals on this compiler. +//# warning I dont know how to fire assertion internals on this compiler. # endif } #endif diff --git a/ePub3/utilities/ref_counted.cpp b/ePub3/utilities/ref_counted.cpp index 209cfc3f2..116b8f0ca 100644 --- a/ePub3/utilities/ref_counted.cpp +++ b/ePub3/utilities/ref_counted.cpp @@ -19,6 +19,6 @@ // Affero General Public License along with this program. If not, see . #if BUILDING_EPUB3 || !EPUB_COMPILER_SUPPORTS(CXX_CONSTEXPR) -#include -const adopt_ref_t adopt_ref = {}; +//#include +//const adopt_ref_t adopt_ref = {}; #endif diff --git a/ePub3/utilities/run_loop_windows.cpp b/ePub3/utilities/run_loop_windows.cpp index a3311d8d7..df8f17f68 100644 --- a/ePub3/utilities/run_loop_windows.cpp +++ b/ePub3/utilities/run_loop_windows.cpp @@ -572,7 +572,7 @@ RunLoop::Timer::Timer(Clock::time_point& fireDate, Clock::duration& interval, Ti } #else - _handle = CreateWaitableTimer(NULL, FALSE); + _handle = CreateWaitableTimer(NULL, FALSE, nullptr); if ( _handle == NULL ) _THROW_LAST_ERROR(); From c7542a0b2bb0d1ba645ebda444b34671fe5172d7 Mon Sep 17 00:00:00 2001 From: DennisPopovDn Date: Sat, 22 Aug 2015 17:23:52 +0300 Subject: [PATCH 2/4] Fixed ReadiumSDK to be compiled with current Windows Launcher --- ePub3/ePub/container.h | 1 + ePub3/ePub/initialization.cpp | 32 +++++++++++++++++++++++++- ePub3/ePub/initialization.h | 18 +++++++++++++-- ePub3/ePub/media-overlays_smil_model.h | 12 +++++----- ePub3/ePub/nav_point.h | 1 + ePub3/ePub/spine.h | 1 + 6 files changed, 56 insertions(+), 9 deletions(-) diff --git a/ePub3/ePub/container.h b/ePub3/ePub/container.h index e63adb4da..cabe40c46 100644 --- a/ePub3/ePub/container.h +++ b/ePub3/ePub/container.h @@ -102,6 +102,7 @@ class Container : public PointerType /// /// Creates and returns a new Container instance by calling OpenContainerAsync() and blocking. + EPUB3_EXPORT static ContainerPtr OpenContainer(const string& path); diff --git a/ePub3/ePub/initialization.cpp b/ePub3/ePub/initialization.cpp index ab54f6f4c..8b4faeeda 100644 --- a/ePub3/ePub/initialization.cpp +++ b/ePub3/ePub/initialization.cpp @@ -53,5 +53,35 @@ void PopulateFilterManager() }); } -EPUB3_END_NAMESPACE +SDKInitializeAndRelease g_instance; + +SDKInitializeAndRelease::SDKInitializeAndRelease() +{ + if (this != &g_instance) + throw std::exception("SDKInitializeAndRelease should be a global static"); + + Initialize(); +} +SDKInitializeAndRelease::~SDKInitializeAndRelease() +{ + Teardown(); +} +void SDKInitializeAndRelease::Initialize() +{ +#if EPUB_USE(LIBXML2) + xmlInitParser(); // Please check this invocation before any libxml2 parsing +#endif +} +void SDKInitializeAndRelease::Teardown() +{ +#if EPUB_USE(LIBXML2) + // One should call xmlCleanupParser() only when the process has finished using the library and all XML/HTML documents built with it. + xmlCleanupParser(); +#endif +} +SDKInitializeAndRelease& SDKInitializeAndRelease::Instance() +{ + return g_instance; // returns the global static instance (for memory debugging purposes as the example) +} +EPUB3_END_NAMESPACE diff --git a/ePub3/ePub/initialization.h b/ePub3/ePub/initialization.h index 50a4ea1c8..9cf9e6bb0 100644 --- a/ePub3/ePub/initialization.h +++ b/ePub3/ePub/initialization.h @@ -25,9 +25,23 @@ EPUB3_BEGIN_NAMESPACE -void InitializeSdk(); +EPUB3_EXPORT void InitializeSdk(); + +EPUB3_EXPORT void PopulateFilterManager(); + +// The static signleton object, to initialize and teardown the SDK +// TODO: Add your global initialization and release code into Initialize() and Teardown() methods respectively +class SDKInitializeAndRelease +{ +private: +public: + SDKInitializeAndRelease(); + ~SDKInitializeAndRelease(); + EPUB3_EXPORT void Initialize(); // helper function, can be called to initialize the SDK memory (i.e. in case of memory leak debugging) + EPUB3_EXPORT void Teardown(); // helper function, can be called to release the SDK memory (i.e. in case of memory leak debugging) + EPUB3_EXPORT static SDKInitializeAndRelease& Instance(); +}; -void PopulateFilterManager(); EPUB3_END_NAMESPACE diff --git a/ePub3/ePub/media-overlays_smil_model.h b/ePub3/ePub/media-overlays_smil_model.h index 1ef9bcffc..d4635a507 100644 --- a/ePub3/ePub/media-overlays_smil_model.h +++ b/ePub3/ePub/media-overlays_smil_model.h @@ -134,14 +134,14 @@ Parser that reads SMIL XML files into an in-memory data model const void PercentToPosition(double percent, SMILDataPtr & smilData, uint32_t & smilIndex, shared_ptr& par, uint32_t & parIndex, uint32_t & milliseconds) const; - //EPUB3_EXPORT + EPUB3_EXPORT static std::vector::size_type GetSkippablesCount() { return _Skippables.size(); } - //EPUB3_EXPORT + EPUB3_EXPORT static string GetSkippable(std::vector::size_type i) { @@ -154,14 +154,14 @@ Parser that reads SMIL XML files into an in-memory data model return str; } - //EPUB3_EXPORT + EPUB3_EXPORT static std::vector::size_type GetEscapablesCount() { return _Escapables.size(); } - //EPUB3_EXPORT + EPUB3_EXPORT static string GetEscapable(std::vector::size_type i) { @@ -174,10 +174,10 @@ Parser that reads SMIL XML files into an in-memory data model return str; } - private: + public: static const std::vector _Skippables; static const std::vector _Escapables; - + private: bool _excludeAudioDuration; void resetData(); diff --git a/ePub3/ePub/nav_point.h b/ePub3/ePub/nav_point.h index a9f1b1822..ecb3eda3e 100644 --- a/ePub3/ePub/nav_point.h +++ b/ePub3/ePub/nav_point.h @@ -60,6 +60,7 @@ class NavigationPoint : public NavigationElement, public PointerType, public OwnedBy, public const string& Idref() const { return _idref; } /// /// Obtains the manifest item corresponding to this spine item. + EPUB3_EXPORT shared_ptr ManifestItem() const; /// /// Returns `true` if this item is linear, `false` otherwise. From b1bf8ab27f22a2aaff59819b2536de104630eee3 Mon Sep 17 00:00:00 2001 From: DennisPopovDn Date: Sat, 22 Aug 2015 17:42:19 +0300 Subject: [PATCH 3/4] Fixed Windows VS2013 'Release' configuration build --- Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj b/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj index 7c24917ee..e692e3163 100644 --- a/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj +++ b/Platform/Windows/ReadiumSDK/ePub3/ePub3.vcxproj @@ -39,7 +39,7 @@ DynamicLibrary false - v110 + v120 true Unicode From 28e90bb0bc5be39c6cd23a69abbb7fedecb3a065 Mon Sep 17 00:00:00 2001 From: DennisPopovDn Date: Sat, 22 Aug 2015 17:44:54 +0300 Subject: [PATCH 4/4] Finally, added the XML weak_ptr memory leak fix --- ePub3/xml/tree/node.cpp | 34 +++++++++++++++++++++++----------- ePub3/xml/utilities/base.h | 34 +++++++++++++++++++++++++++------- ePub3/xml/validation/ns.cpp | 8 +++++--- ePub3/xml/validation/ns.h | 5 +++-- 4 files changed, 58 insertions(+), 23 deletions(-) diff --git a/ePub3/xml/tree/node.cpp b/ePub3/xml/tree/node.cpp index a4a6254c4..3662d5b51 100644 --- a/ePub3/xml/tree/node.cpp +++ b/ePub3/xml/tree/node.cpp @@ -170,7 +170,8 @@ Node::Node(const string & name, NodeType type, const string & content, const cla Node::Node(Node && o) : _xml(o._xml) { typedef LibXML2Private _Private; _Private* priv = reinterpret_cast<_Private*>(_xml->_private); - priv->__ptr.reset(this); + //priv->__ptr.reset(this); + priv->__ptr=std::shared_ptr(this); o._xml = NULL; } Node::~Node() @@ -181,14 +182,17 @@ Node::~Node() return; _Private* priv = reinterpret_cast<_Private*>(_xml->_private); - if ( priv->__sig != _READIUM_XML_SIGNATURE || priv->__ptr.get() != this ) + if (priv->__sig != _READIUM_XML_SIGNATURE || (priv->__ptr.lock()!=nullptr && priv->__ptr.lock().get() != this)) return; - // free the underlying node if *and only if* it is detached + if (!bool(priv->__ptr.lock())) + { + _xml->_private = nullptr; + delete priv; + } + // free the underlying node if *and only if* it is detached if ( _xml->parent == nullptr && _xml->prev == nullptr && _xml->next == nullptr ) { - _xml->_private = nullptr; - delete priv; xmlFreeNode(_xml); } } @@ -213,7 +217,9 @@ string Node::Content() const const xmlChar* ch = xmlNodeGetContent(_xml); if (ch == nullptr) return string::EmptyString; - return ch; + string result(ch); + xmlFree((void*)ch); + return result; } void Node::SetContent(const string &content) { @@ -251,7 +257,9 @@ string Node::Language() const const xmlChar * ch = xmlNodeGetLang(_xml); if ( ch == nullptr ) return string(); - return ch; + string result(ch); + xmlFree((void*)ch); + return result; } void Node::SetLanguage(const string &language) { @@ -270,7 +278,9 @@ string Node::BaseURL() const const xmlChar * ch = xmlNodeGetBase(_xml->doc, _xml); if ( ch == nullptr ) return string(); - return ch; + string result(ch); + xmlFree((void*)ch); + return result; } void Node::SetBaseURL(const string &baseURL) { @@ -352,7 +362,9 @@ string Node::StringValue() const const xmlChar * content = xmlNodeGetContent(_xml); if ( content == nullptr ) return string(); - return content; + string result(content); + xmlFree((void*)content); + return result; } int Node::IntValue() const { @@ -634,7 +646,7 @@ void Node::Unwrap(_xmlNode *aNode) NsPrivate* ptr = reinterpret_cast(__ns->_private); if (ptr->__sig == _READIUM_XML_SIGNATURE) { - ptr->__ptr->release(); + //ptr->__ptr->release(); delete ptr; } __ns->_private = nullptr; @@ -645,7 +657,7 @@ void Node::Unwrap(_xmlNode *aNode) NodePrivate* ptr = reinterpret_cast(aNode->_private); if (ptr->__sig == _READIUM_XML_SIGNATURE) { - ptr->__ptr->release(); + //ptr->__ptr->release(); delete ptr; } aNode->_private = nullptr; diff --git a/ePub3/xml/utilities/base.h b/ePub3/xml/utilities/base.h index 1715c4fda..5b4f03c77 100644 --- a/ePub3/xml/utilities/base.h +++ b/ePub3/xml/utilities/base.h @@ -123,7 +123,7 @@ struct LibXML2Private : __sig(_READIUM_XML_SIGNATURE), __ptr(nullptr) {} LibXML2Private(_Tp* __p) - : __sig(_READIUM_XML_SIGNATURE), __ptr(__p) + : __sig(_READIUM_XML_SIGNATURE), __ptr(std::shared_ptr<_Tp>(__p)) {} LibXML2Private(std::shared_ptr<_Tp>& __p) : __sig(_READIUM_XML_SIGNATURE), __ptr(__p) @@ -133,7 +133,7 @@ struct LibXML2Private // data member-- used to determine if this is a Readium-made pointer unsigned int __sig; - std::shared_ptr<_Tp> __ptr; + std::weak_ptr<_Tp> __ptr; }; #endif @@ -162,7 +162,24 @@ static inline std::shared_ptr<_Tp> Wrapped(_Nm * __n) _PrivatePtr __p = reinterpret_cast<_PrivatePtr>(__n->_private); if (__p->__sig == _READIUM_XML_SIGNATURE) { - return __p->__ptr; + std::shared_ptr<_Tp> toRet = __p->__ptr.lock(); + if (!bool(toRet))// if there is no live reference to the readium wrapper, but + { + delete __p; // release unreferenced memory, if any + __n->_private = nullptr; + + std::shared_ptr<_Tp> toRet = std::shared_ptr<_Tp>(new _Tp(__n)); + + //_PrivatePtr __p = new LibXML2Private<_Tp>(new _Tp(__n)); + _PrivatePtr __p = new LibXML2Private<_Tp>(toRet); + __n->_private = __p; + //return __p->__ptr; + return toRet; + } + /////////////////////////////////////////////////// + return toRet; + //return __p->__ptr; + } else { @@ -175,11 +192,14 @@ static inline std::shared_ptr<_Tp> Wrapped(_Nm * __n) if (__n->_private != nullptr) throw std::logic_error("XML _private already carries a value!"); } + + std::shared_ptr<_Tp> toRet = std::shared_ptr<_Tp>(new _Tp(__n)); - - _PrivatePtr __p = new LibXML2Private<_Tp>(new _Tp(__n)); + //_PrivatePtr __p = new LibXML2Private<_Tp>(new _Tp(__n)); + _PrivatePtr __p = new LibXML2Private<_Tp>(toRet); __n->_private = __p; - return __p->__ptr; + //return __p->__ptr; + return toRet; } /** @@ -198,7 +218,7 @@ static inline void Rewrap(_Nm* __n, std::shared_ptr<_Tp> __t) if (IS_READIUM_WRAPPED_XML(__n)) { _Private* __p = reinterpret_cast<_Private*>(__n->_private); - if (__p->__ptr == __t) + if (__p->__ptr.lock() && __p->__ptr.lock() == __t) return; delete __p; diff --git a/ePub3/xml/validation/ns.cpp b/ePub3/xml/validation/ns.cpp index e1400bd02..d097afe52 100644 --- a/ePub3/xml/validation/ns.cpp +++ b/ePub3/xml/validation/ns.cpp @@ -26,7 +26,9 @@ EPUB3_XML_BEGIN_NAMESPACE Namespace::Namespace(std::shared_ptr doc, const string &prefix, const string &uri) { xmlDocPtr d = doc->xml(); + _xml = xmlNewNs(reinterpret_cast(d), uri.utf8(), prefix.utf8()); + bShouldxmlFreeNs = true; if (_xml->_private != nullptr) Node::Unwrap((xmlNodePtr)_xml); @@ -38,13 +40,13 @@ Namespace::~Namespace() return; LibXML2Private* priv = reinterpret_cast*>(_xml->_private); - if (priv->__sig == _READIUM_XML_SIGNATURE && priv->__ptr.get() == this) + if (priv->__sig == _READIUM_XML_SIGNATURE && priv->__ptr.lock() == nullptr/* && priv->__ptr.lock().get() == this*/) { delete priv; _xml->_private = nullptr; } - - xmlFreeNs(_xml); + if (bShouldxmlFreeNs) + xmlFreeNs(_xml); } EPUB3_XML_END_NAMESPACE diff --git a/ePub3/xml/validation/ns.h b/ePub3/xml/validation/ns.h index 8f017ddba..2c5a0cbc7 100644 --- a/ePub3/xml/validation/ns.h +++ b/ePub3/xml/validation/ns.h @@ -47,8 +47,8 @@ typedef std::vector> NamespaceList; class Namespace : public WrapperBase { public: - explicit Namespace(_xmlNs * ns) : _xml(ns) {} - Namespace() : _xml(nullptr) {} + explicit Namespace(_xmlNs * ns) : _xml(ns), bShouldxmlFreeNs(false) {} + Namespace() : _xml(nullptr), bShouldxmlFreeNs(false) {} Namespace(std::shared_ptr doc, const string & prefix, const string & uri); virtual ~Namespace(); @@ -67,6 +67,7 @@ class Namespace : public WrapperBase { _xml = nullptr; } protected: + bool bShouldxmlFreeNs; _xmlNs * _xml; };