From 6805e6dfeaa1897de9fe97a500a47aaa0eada14e Mon Sep 17 00:00:00 2001 From: Michal Maciola Date: Thu, 17 Jun 2021 15:43:47 +0200 Subject: [PATCH] loaders: added copy param for Picture::load @API Changed: Result Picture::load(const char* data, uint32_t size, bool copy /*=false*/) noexcept TVG_EXPORT Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size, bool copy); --- inc/thorvg.h | 3 ++- src/bindings/capi/thorvg_capi.h | 3 ++- src/bindings/capi/tvgCapi.cpp | 4 ++-- src/lib/tvgLoader.h | 2 +- src/lib/tvgLoaderMgr.cpp | 4 ++-- src/lib/tvgLoaderMgr.h | 2 +- src/lib/tvgPicture.cpp | 4 ++-- src/lib/tvgPictureImpl.h | 4 ++-- src/loaders/svg/tvgSvgLoader.cpp | 25 ++++++++++++++++++++++--- src/loaders/svg/tvgSvgLoader.h | 6 +++++- src/loaders/tvg/tvgTvgLoader.cpp | 14 +++++++++++--- src/loaders/tvg/tvgTvgLoader.h | 2 +- 12 files changed, 53 insertions(+), 20 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index d1edb41..7ecf6a9 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -989,6 +989,7 @@ public: * * @param[in] data A pointer to a memory location where the content of the picture file is stored. * @param[in] size The size in bytes of the memory occupied by the @p data. + * @param[in] copy Decides whether the data should be copied into the local buffer. * * @retval Result::Success When succeed. * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. @@ -997,7 +998,7 @@ public: * * @note: This api supports only SVG format */ - Result load(const char* data, uint32_t size) noexcept; + Result load(const char* data, uint32_t size, bool copy = false) noexcept; /** * @brief Resize the picture content with the given width and height. diff --git a/src/bindings/capi/thorvg_capi.h b/src/bindings/capi/thorvg_capi.h index 6775640..6487d6b 100644 --- a/src/bindings/capi/thorvg_capi.h +++ b/src/bindings/capi/thorvg_capi.h @@ -1676,6 +1676,7 @@ TVG_EXPORT Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uin * \param[in] paint Tvg_Paint pointer * \param[in] data raw data pointer * \param[in] size of data +* \param[in] copy Decides whether the data should be copied into the local buffer * * \return Tvg_Result return value * \retval TVG_RESULT_SUCCESS: if ok. @@ -1683,7 +1684,7 @@ TVG_EXPORT Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uin * * \warning Please do not use it, this API is not official one. It can be modified in the next version. */ -TVG_EXPORT Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size); +TVG_EXPORT Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size, bool copy); /*! diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index cfafb8a..0809f5d 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -462,10 +462,10 @@ TVG_EXPORT Tvg_Result tvg_picture_load_raw(Tvg_Paint* paint, uint32_t *data, uin } -TVG_EXPORT Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size) +TVG_EXPORT Tvg_Result tvg_picture_load_data(Tvg_Paint* paint, const char *data, uint32_t size, bool copy) { if (!paint) return TVG_RESULT_INVALID_ARGUMENT; - return (Tvg_Result) reinterpret_cast(paint)->load(data, size); + return (Tvg_Result) reinterpret_cast(paint)->load(data, size, copy); } diff --git a/src/lib/tvgLoader.h b/src/lib/tvgLoader.h index a15eb6e..8887e89 100644 --- a/src/lib/tvgLoader.h +++ b/src/lib/tvgLoader.h @@ -41,7 +41,7 @@ public: virtual ~Loader() {} virtual bool open(const string& path) { /* Not supported */ return false; }; - virtual bool open(const char* data, uint32_t size) { /* Not supported */ return false; }; + virtual bool open(const char* data, uint32_t size, bool copy) { /* Not supported */ return false; }; virtual bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { /* Not supported */ return false; }; virtual bool read() = 0; virtual bool close() = 0; diff --git a/src/lib/tvgLoaderMgr.cpp b/src/lib/tvgLoaderMgr.cpp index b1ad1e8..84b29a4 100644 --- a/src/lib/tvgLoaderMgr.cpp +++ b/src/lib/tvgLoaderMgr.cpp @@ -139,12 +139,12 @@ shared_ptr LoaderMgr::loader(const string& path) } -shared_ptr LoaderMgr::loader(const char* data, uint32_t size) +shared_ptr LoaderMgr::loader(const char* data, uint32_t size, bool copy) { for (int i = 0; i < static_cast(FileType::Unknown); i++) { auto loader = _find(static_cast(i)); if (loader) { - if (loader->open(data, size)) return shared_ptr(loader); + if (loader->open(data, size, copy)) return shared_ptr(loader); else delete(loader); } } diff --git a/src/lib/tvgLoaderMgr.h b/src/lib/tvgLoaderMgr.h index 4592cb1..849b99f 100644 --- a/src/lib/tvgLoaderMgr.h +++ b/src/lib/tvgLoaderMgr.h @@ -31,7 +31,7 @@ struct LoaderMgr static bool init(); static bool term(); static shared_ptr loader(const string& path); - static shared_ptr loader(const char* data, uint32_t size); + static shared_ptr loader(const char* data, uint32_t size, bool copy); static shared_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); }; diff --git a/src/lib/tvgPicture.cpp b/src/lib/tvgPicture.cpp index f4ddcfa..db12e44 100644 --- a/src/lib/tvgPicture.cpp +++ b/src/lib/tvgPicture.cpp @@ -53,11 +53,11 @@ Result Picture::load(const std::string& path) noexcept } -Result Picture::load(const char* data, uint32_t size) noexcept +Result Picture::load(const char* data, uint32_t size, bool copy /*=false*/) noexcept { if (!data || size <= 0) return Result::InvalidArguments; - return pImpl->load(data, size); + return pImpl->load(data, size, copy); } diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index 4424a60..3a8ec26 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -175,10 +175,10 @@ struct Picture::Impl return Result::Success; } - Result load(const char* data, uint32_t size) + Result load(const char* data, uint32_t size, bool copy) { if (loader) loader->close(); - loader = LoaderMgr::loader(data, size); + loader = LoaderMgr::loader(data, size, copy); if (!loader) return Result::NonSupport; if (!loader->read()) return Result::Unknown; w = loader->w; diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 8c3afb6..1c6f78b 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -2563,6 +2563,15 @@ static bool _svgLoaderParserForValidCheck(void* data, SimpleXMLType type, const } +void SvgLoader::clearBuffer() +{ + free(buffer); + size = 0; + buffer = nullptr; + content = nullptr; +} + + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -2633,11 +2642,18 @@ bool SvgLoader::header() } -bool SvgLoader::open(const char* data, uint32_t size) +bool SvgLoader::open(const char* data, uint32_t size, bool copy) { - //TODO: verify memory leak if open() is called multiple times. + clearBuffer(); + if (copy) { + buffer = (char*)malloc(size); + if (!buffer) return false; + memcpy(buffer, data, size); + this->content = buffer; + } else { + this->content = data; + } - this->content = data; this->size = size; return header(); @@ -2647,6 +2663,7 @@ bool SvgLoader::open(const char* data, uint32_t size) bool SvgLoader::open(const string& path) { //TODO: verify memory leak if open() is called multiple times. + clearBuffer(); ifstream f; f.open(path); @@ -2694,6 +2711,8 @@ bool SvgLoader::close() loaderData.doc = nullptr; loaderData.stack.reset(); + clearBuffer(); + return true; } diff --git a/src/loaders/svg/tvgSvgLoader.h b/src/loaders/svg/tvgSvgLoader.h index 29ec944..abddeb7 100644 --- a/src/loaders/svg/tvgSvgLoader.h +++ b/src/loaders/svg/tvgSvgLoader.h @@ -29,6 +29,7 @@ class SvgLoader : public Loader, public Task { public: string filePath; + char* buffer = nullptr; const char* content = nullptr; uint32_t size = 0; @@ -40,7 +41,7 @@ public: using Loader::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size) override; + bool open(const char* data, uint32_t size, bool copy) override; bool header(); bool read() override; @@ -48,6 +49,9 @@ public: void run(unsigned tid) override; unique_ptr scene() override; + +private: + void clearBuffer(); }; diff --git a/src/loaders/tvg/tvgTvgLoader.cpp b/src/loaders/tvg/tvgTvgLoader.cpp index be3bfc4..9bab82b 100644 --- a/src/loaders/tvg/tvgTvgLoader.cpp +++ b/src/loaders/tvg/tvgTvgLoader.cpp @@ -21,6 +21,7 @@ */ #include +#include #include "tvgLoaderMgr.h" #include "tvgTvgLoader.h" #include "tvgTvgLoadParser.h" @@ -82,11 +83,18 @@ bool TvgLoader::open(const string &path) return tvgValidateData(pointer, size); } -bool TvgLoader::open(const char *data, uint32_t size) +bool TvgLoader::open(const char *data, uint32_t size, bool copy) { - //TODO: verify memory leak if open() is called multiple times. + if (copy) { + if (buffer) clearBuffer(); + buffer = (char*)malloc(size); + if (!buffer) return false; + memcpy(buffer, data, size); + this->pointer = buffer; + } else { + this->pointer = data; + } - this->pointer = data; this->size = size; return tvgValidateData(pointer, size); diff --git a/src/loaders/tvg/tvgTvgLoader.h b/src/loaders/tvg/tvgTvgLoader.h index 3c6c72f..d0aec4f 100644 --- a/src/loaders/tvg/tvgTvgLoader.h +++ b/src/loaders/tvg/tvgTvgLoader.h @@ -38,7 +38,7 @@ public: using Loader::open; bool open(const string &path) override; - bool open(const char *data, uint32_t size) override; + bool open(const char *data, uint32_t size, bool copy) override; bool read() override; bool close() override; -- 2.7.4