From 375652641509b75e93a284deea44f6f1be13e7b3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 18:24:54 +0000 Subject: Swap @ prefix for p. prefix for special value names --- lib/persistence.cpp | 4 ++-- lib/persistence.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/persistence.cpp b/lib/persistence.cpp index 239e425..543f2fd 100644 --- a/lib/persistence.cpp +++ b/lib/persistence.cpp @@ -81,12 +81,12 @@ namespace Persistence { void PersistenceWrite::setType(const std::string_view tn, const Persistable * p) { - out.pushKey("@typeid"); + out.pushKey("p.typeid"); out.pushValue(tn); first = false; if (shared) { out.nextValue(); - out.pushKey("@id"); + out.pushKey("p.id"); out.pushValue(p->getId()); } } diff --git a/lib/persistence.h b/lib/persistence.h index 4fbff4c..c311067 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -340,14 +340,14 @@ namespace Persistence { select(const std::string & mbr) override { using namespace std::literals; - if (mbr == "@typeid"sv) { + if (mbr == "p.typeid"sv) { if (this->v) { throw std::runtime_error("cannot set object type after creation"); } return this->template make_s(this->v); } if constexpr (shared) { - if (mbr == "@id"sv) { + if (mbr == "p.id"sv) { return this->template make_s(this->v); } } -- cgit v1.2.3 From 0724047fbbbf02e053e2686299d726fcb2c7d295 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 18:42:30 +0000 Subject: Add SAXParse base class --- lib/saxParse.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ lib/saxParse.h | 21 +++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 lib/saxParse.cpp create mode 100644 lib/saxParse.h (limited to 'lib') diff --git a/lib/saxParse.cpp b/lib/saxParse.cpp new file mode 100644 index 0000000..d592a1f --- /dev/null +++ b/lib/saxParse.cpp @@ -0,0 +1,41 @@ +#include "saxParse.h" +#include "mxml.h" + +namespace Persistence { + void + SAXParse::comment(mxml_node_t *) + { + // Default to just ignore comments + } + + void + SAXParse::parseFile(FILE * file) + { + mxmlSAXLoadFile( + nullptr, file, MXML_TEXT_CALLBACK, + [](mxml_node_t * n, mxml_sax_event_t e, void * data) { + SAXParse * self = static_cast(data); + switch (e) { + case MXML_SAX_ELEMENT_OPEN: + return self->elementOpen(n); + break; + case MXML_SAX_ELEMENT_CLOSE: + return self->elementClose(n); + break; + case MXML_SAX_COMMENT: + return self->comment(n); + break; + case MXML_SAX_DATA: + return self->data(n); + break; + case MXML_SAX_DIRECTIVE: + return self->directive(n); + break; + case MXML_SAX_CDATA:; + return self->cdata(n); + break; + } + }, + this); + } +} diff --git a/lib/saxParse.h b/lib/saxParse.h new file mode 100644 index 0000000..d5baaca --- /dev/null +++ b/lib/saxParse.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +typedef struct _mxml_node_s mxml_node_t; + +namespace Persistence { + class SAXParse { + public: + virtual ~SAXParse() = default; + + virtual void elementOpen(mxml_node_t *) = 0; + virtual void elementClose(mxml_node_t *) = 0; + virtual void comment(mxml_node_t *); + virtual void data(mxml_node_t *) = 0; + virtual void directive(mxml_node_t *) = 0; + virtual void cdata(mxml_node_t *) = 0; + + void parseFile(FILE * file); + }; +} -- cgit v1.2.3 From eeb3bceceacff5807011c83eeaa1f1497429b3ab Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 18:59:18 +0000 Subject: Make sure an object is created before remembering it --- lib/persistence.h | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index c311067..dbaee44 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -348,6 +348,7 @@ namespace Persistence { } if constexpr (shared) { if (mbr == "p.id"sv) { + make_default_as_needed(this->v); return this->template make_s(this->v); } } -- cgit v1.2.3 From 223ecbc450fede9f8ca246895d5f82495f8665e8 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 19:14:55 +0000 Subject: Allow override member variable names and selection helper when mapping members for persistence --- lib/persistence.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index dbaee44..e1f7605 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -113,14 +113,14 @@ namespace Persistence { template [[nodiscard]] inline bool persistType(const T * const, const std::type_info & ti); enum class NameAction { Push, HandleAndContinue, Ignore }; - template + template [[nodiscard]] inline bool persistValue(const std::string_view key, T & value) { - SelectionT s {value}; - const auto act {setName(key, s)}; + auto s = std::make_unique(value); + const auto act {setName(key, *s)}; if (act != NameAction::Ignore) { - sel = std::make_unique(std::move(s)); + sel = std::move(s); if (act == NameAction::HandleAndContinue) { selHandler(); } @@ -462,4 +462,7 @@ namespace Persistence { } #define STORE_TYPE store.persistType(this, typeid(*this)) -#define STORE_MEMBER(mbr) store.persistValue(#mbr, mbr) +#define STORE_MEMBER(mbr) STORE_NAME_MEMBER(#mbr, mbr) +#define STORE_NAME_MEMBER(name, mbr) store.persistValue>(name, mbr) +#define STORE_HELPER(mbr, Helper) STORE_NAME_HELPER(#mbr, mbr, Helper) +#define STORE_NAME_HELPER(name, mbr, Helper) store.persistValue(name, mbr) -- cgit v1.2.3 From a142b8da33e6c6657a7aa529ddf0f1c0882ff0d5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 20 Feb 2023 23:59:24 +0000 Subject: Accept a CSV for glm::vec data --- lib/persistence.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index e1f7605..01b2a7e 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,17 @@ namespace Persistence { }; using SelectionV::SelectionV; + using SelectionV::setValue; + + void + setValue(std::string && s) override + { + std::stringstream ss {std::move(s)}; + for (glm::length_t n = 0; n < L; n += 1) { + ss >> this->v[n]; + ss.get(); + } + } void beginArray(Stack & stk) override -- cgit v1.2.3 From bf0a1a219e48007ca51e23ea45d08d295e398fcd Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Feb 2023 00:03:08 +0000 Subject: Add helper Selection to insert into a map based on a member value as key --- lib/persistence.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index 01b2a7e..d55062a 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -256,6 +256,23 @@ namespace Persistence { } }; + template + struct MapByMember : public Persistence::SelectionT> { + MapByMember(Map & m) : Persistence::SelectionT> {s}, map {m} { } + + using Persistence::SelectionT>::SelectionT; + void + endObject(Persistence::Stack & stk) override + { + map.emplace(std::invoke(Key, s), s); + stk.pop(); + } + + private: + std::shared_ptr s; + Map & map; + }; + struct Persistable { Persistable() = default; virtual ~Persistable() = default; -- cgit v1.2.3 From e2dae4345b7cb9ec92e204a8bf2ab3dee8fcb9ac Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Feb 2023 00:48:02 +0000 Subject: Add checked_fopen wrapper and FileStar container --- lib/filesystem.cpp | 9 +++++++++ lib/filesystem.h | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/filesystem.cpp b/lib/filesystem.cpp index 0e19e8d..7e8ab9c 100644 --- a/lib/filesystem.cpp +++ b/lib/filesystem.cpp @@ -62,4 +62,13 @@ namespace filesystem { { return memmap {length, prot, flags, h, static_cast(offset)}; } + + FILE * + checked_fopen(const char * pathname, const char * mode) + { + if (auto file = fopen(pathname, mode)) { + return file; + } + throw_filesystem_error("fopen", errno, pathname); + } } diff --git a/lib/filesystem.h b/lib/filesystem.h index 0c44236..5315183 100644 --- a/lib/filesystem.h +++ b/lib/filesystem.h @@ -1,7 +1,9 @@ #pragma once +#include "ptr.hpp" #include "special_members.hpp" #include +#include #include namespace filesystem { @@ -39,4 +41,7 @@ namespace filesystem { private: int h; }; + + FILE * checked_fopen(const char * pathname, const char * mode); + using FileStar = wrapped_ptrt; } -- cgit v1.2.3 From 15d7196bf3a3244f078f63645783c4c3f2534d92 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Feb 2023 00:57:37 +0000 Subject: Implement XML deserializer with SAXParse --- lib/saxParse-persistence.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++ lib/saxParse-persistence.h | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 lib/saxParse-persistence.cpp create mode 100644 lib/saxParse-persistence.h (limited to 'lib') diff --git a/lib/saxParse-persistence.cpp b/lib/saxParse-persistence.cpp new file mode 100644 index 0000000..a6a0d23 --- /dev/null +++ b/lib/saxParse-persistence.cpp @@ -0,0 +1,50 @@ +#include "saxParse-persistence.h" + +namespace Persistence { + + void + SAXParsePersistence::loadStateInternal(FILE * in) + { + stk.top()->beforeValue(stk); + stk.top()->beginObject(stk); + parseFile(in); + stk.pop(); + stk.pop(); + } + + void + SAXParsePersistence::elementOpen(mxml_node_t * n) + { + stk.push(stk.top()->select(mxmlGetElement(n))); + stk.top()->beforeValue(stk); + stk.top()->beginObject(stk); + for (int attrCount = mxmlElementGetAttrCount(n), attrIdx {0}; attrIdx < attrCount; ++attrIdx) { + const char *name, *value = mxmlElementGetAttrByIndex(n, attrIdx, &name); + auto sel = stk.top()->select(name); + sel->beforeValue(stk); + sel->setValue(std::string {value}); + } + } + + void + SAXParsePersistence::elementClose(mxml_node_t *) + { + stk.top()->endObject(stk); + stk.top()->endObject(stk); + } + + void + SAXParsePersistence::data(mxml_node_t *) + { + } + + void + SAXParsePersistence::directive(mxml_node_t *) + { + } + + void + SAXParsePersistence::cdata(mxml_node_t *) + { + } +} diff --git a/lib/saxParse-persistence.h b/lib/saxParse-persistence.h new file mode 100644 index 0000000..91daecc --- /dev/null +++ b/lib/saxParse-persistence.h @@ -0,0 +1,43 @@ +#pragma once + +#include "persistence.h" +#include "saxParse.h" +#include +#include + +namespace Persistence { + class SAXParsePersistence : public SAXParse { + private: + template struct Root : public Persistable { + T t {}; + bool + persist(PersistenceStore & store) + { + return STORE_TYPE && STORE_NAME_MEMBER("ilt", t); + } + }; + + void loadStateInternal(FILE * in); + + public: + template + auto + loadState(FILE * in) + { + std::unique_ptr> root; + stk.push(std::make_unique>(std::ref(root))); + loadStateInternal(in); + return std::move(root->t); + } + + protected: + void elementOpen(mxml_node_t * n) override; + void elementClose(mxml_node_t *) override; + void data(mxml_node_t *) override; + void directive(mxml_node_t *) override; + void cdata(mxml_node_t *) override; + + private: + Stack stk; + }; +} -- cgit v1.2.3 From f91e2ea8d9e30b1e62c4f8784fddfd4eb9578d2d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 21 Feb 2023 20:09:41 +0000 Subject: Move Appender in Persistence NS and simplify types --- lib/persistence.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index d55062a..5c8454c 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -273,6 +273,22 @@ namespace Persistence { Map & map; }; + template + struct Appender : public Persistence::SelectionT { + Appender(Container & c) : Persistence::SelectionT {s}, container {c} { } + using Persistence::SelectionT::SelectionT; + void + endObject(Persistence::Stack & stk) override + { + container.emplace_back(std::move(s)); + stk.pop(); + } + + private: + Type s; + Container & container; + }; + struct Persistable { Persistable() = default; virtual ~Persistable() = default; -- cgit v1.2.3 From 320e5cc574f0c8f83def034e36f6d0c57b1f75ac Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 22 Feb 2023 20:54:39 +0000 Subject: Fixup MapByMember to work with shared or unique ptr --- lib/persistence.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index 5c8454c..0fc0200 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -256,20 +256,20 @@ namespace Persistence { } }; - template - struct MapByMember : public Persistence::SelectionT> { - MapByMember(Map & m) : Persistence::SelectionT> {s}, map {m} { } + template + struct MapByMember : public Persistence::SelectionT { + MapByMember(Map & m) : Persistence::SelectionT {s}, map {m} { } - using Persistence::SelectionT>::SelectionT; + using Persistence::SelectionT::SelectionT; void endObject(Persistence::Stack & stk) override { - map.emplace(std::invoke(Key, s), s); + map.emplace(std::invoke(Key, s), std::move(s)); stk.pop(); } private: - std::shared_ptr s; + Type s; Map & map; }; -- cgit v1.2.3 From b59ba638083122456bfeab0ff1fc7e3f3af99423 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 23 Feb 2023 00:39:06 +0000 Subject: Support parsing string values in persistence read --- lib/persistence.h | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index 0fc0200..bfd27f0 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -87,13 +88,53 @@ namespace Persistence { T & v; }; - template struct SelectionT : public SelectionV { + template + concept Scalar = std::is_scalar_v; + template + concept NotScalar = (!Scalar); + + template struct SelectionT : public SelectionV { + using SelectionV::SelectionV; + using Selection::setValue; + + void + setValue(T evalue) override + { + std::swap(this->v, evalue); + } + + void + setValue(std::string && evalue) override + { + if constexpr (std::same_as) { + using namespace std::literals; + if (!(this->v = evalue == "true"sv)) { + if (evalue != "false"sv) { + throw std::runtime_error("Value conversion failure"); + } + } + } + else { + if (auto res = std::from_chars(evalue.c_str(), evalue.c_str() + evalue.length(), this->v).ec; + res != std::errc {}) { + throw std::runtime_error("Value conversion failure"); + } + } + } + + void + write(const Writer & out) const override + { + out.pushValue(this->v); + } + }; + + template struct SelectionT : public SelectionV { using SelectionV::SelectionV; using Selection::setValue; - using P = std::conditional_t, T, T &&>; void - setValue(P evalue) override + setValue(T && evalue) override { std::swap(this->v, evalue); } -- cgit v1.2.3 From ba761a571ab9d62fa21e78d1b53f885f82b48446 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 24 Feb 2023 19:26:57 +0000 Subject: Fixed up vector operator+ element --- lib/collections.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/collections.hpp b/lib/collections.hpp index 47967b2..31e5ab8 100644 --- a/lib/collections.hpp +++ b/lib/collections.hpp @@ -82,13 +82,13 @@ operator+=(std::vector & in, std::vector && src) return in; } -template +template constexpr auto -operator+(std::vector && in, std::vector && src) +operator+(const std::vector & in, Vn && vn) { - in.reserve(in.size() + src.size()); - std::move(src.begin(), src.end(), std::back_inserter(in)); - return in; + auto out(in); + out.emplace_back(std::forward(vn)); + return out; } template typename Direction = std::plus> -- cgit v1.2.3 From f25a47f022e45137149a0726a73cbd8b1fda4f04 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 25 Feb 2023 03:23:07 +0000 Subject: Helpers to create container instances from ranges --- lib/collections.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'lib') diff --git a/lib/collections.hpp b/lib/collections.hpp index 31e5ab8..18e6147 100644 --- a/lib/collections.hpp +++ b/lib/collections.hpp @@ -15,6 +15,8 @@ concept SequentialCollection = requires(T c) { c.data() } -> std::same_as; }; +template +concept IterableCollection = std::is_same_v().begin()), decltype(std::declval().end())>; template constexpr std::array @@ -102,3 +104,17 @@ vectorOfN(std::integral auto N, unsigned int start = {}, unsigned int step = 1) }); return v; } + +template typename Rtn = std::vector, IterableCollection In> +auto +materializeRange(In && in) +{ + return Rtn(in.begin(), in.end()); +} + +template typename Rtn = std::vector, typename In> +auto +materializeRange(const std::pair & in) +{ + return Rtn(in.first, in.second); +} -- cgit v1.2.3 From aac5672de67798337618d0bceb93b2c799d3edc3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 27 Feb 2023 01:05:11 +0000 Subject: Add nodiscard to many collections helpers --- lib/collections.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/collections.hpp b/lib/collections.hpp index 18e6147..391647e 100644 --- a/lib/collections.hpp +++ b/lib/collections.hpp @@ -19,7 +19,7 @@ template concept IterableCollection = std::is_same_v().begin()), decltype(std::declval().end())>; template -constexpr std::array +[[nodiscard]] constexpr std::array operator+(const std::array & a, const std::array & b) { std::array r; @@ -30,7 +30,7 @@ operator+(const std::array & a, const std::array & b) } template -constexpr std::array, first * second> +[[nodiscard]] constexpr std::array, first * second> operator*(const std::array & a, const std::array & b) { std::array, first * second> r; @@ -44,7 +44,7 @@ operator*(const std::array & a, const std::array & b) } template -constexpr auto +[[nodiscard]] constexpr auto operator*(const std::array & in, auto && f) { std::array out; @@ -66,7 +66,7 @@ operator*=(std::span & in, auto && f) } template typename C, typename... T> -constexpr auto +[[nodiscard]] constexpr auto operator*(const C & in, auto && f) { C out; @@ -85,7 +85,7 @@ operator+=(std::vector & in, std::vector && src) } template -constexpr auto +[[nodiscard]] constexpr auto operator+(const std::vector & in, Vn && vn) { auto out(in); @@ -94,7 +94,7 @@ operator+(const std::vector & in, Vn && vn) } template typename Direction = std::plus> -static auto +[[nodiscard]] static auto vectorOfN(std::integral auto N, unsigned int start = {}, unsigned int step = 1) { std::vector v; @@ -106,14 +106,14 @@ vectorOfN(std::integral auto N, unsigned int start = {}, unsigned int step = 1) } template typename Rtn = std::vector, IterableCollection In> -auto +[[nodiscard]] auto materializeRange(In && in) { return Rtn(in.begin(), in.end()); } template typename Rtn = std::vector, typename In> -auto +[[nodiscard]] auto materializeRange(const std::pair & in) { return Rtn(in.first, in.second); -- cgit v1.2.3 From 90b4839af82e9c0188f4d37c0587e613756abcf9 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 27 Feb 2023 19:37:05 +0000 Subject: operator*= can work on any iterable collection --- lib/collections.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/collections.hpp b/lib/collections.hpp index 391647e..16870be 100644 --- a/lib/collections.hpp +++ b/lib/collections.hpp @@ -55,9 +55,8 @@ operator*(const std::array & in, auto && f) return out; } -template constexpr auto & -operator*=(std::span & in, auto && f) +operator*=(IterableCollection auto & in, auto && f) { for (auto & v : in) { f(v); -- cgit v1.2.3 From 7a70e75656d31428c9bbbd51fbf1ca920e577ed1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 28 Feb 2023 01:24:18 +0000 Subject: Remove to specify if the Selection pointer type is shared or not Inferred based on whether the pointer is copyable or not. --- lib/persistence.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/persistence.h b/lib/persistence.h index bfd27f0..458ba4d 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -381,7 +381,8 @@ namespace Persistence { using SeenSharedObjects = std::map; inline SeenSharedObjects seenSharedObjects; - template struct SelectionPtrBase : public SelectionV { + template struct SelectionPtrBase : public SelectionV { + static constexpr auto shared = std::is_copy_assignable_v; using T = typename Ptr::element_type; struct SelectionObj : public SelectionV { struct MakeObjectByTypeName : public SelectionV { @@ -526,13 +527,13 @@ namespace Persistence { } }; - template struct SelectionT> : public SelectionPtrBase, false> { - using SelectionPtrBase, false>::SelectionPtrBase; + template struct SelectionT> : public SelectionPtrBase> { + using SelectionPtrBase>::SelectionPtrBase; }; - template struct SelectionT> : public SelectionPtrBase, true> { - using SelectionPtrBase, true>::SelectionPtrBase; - using SelectionPtrBase, true>::setValue; + template struct SelectionT> : public SelectionPtrBase> { + using SelectionPtrBase>::SelectionPtrBase; + using SelectionPtrBase>::setValue; void setValue(std::string && id) override -- cgit v1.2.3 From 17ac090dd1dd245cf1e24b62b7333ba9be571bde Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 2 Mar 2023 18:36:34 +0000 Subject: Add ParseBase Acts as a base class for persistence parser, encompasses the parse stack and manages shared objects --- lib/jsonParse-persistence.h | 4 +--- lib/persistence.cpp | 5 +++++ lib/persistence.h | 35 +++++++++++++++++++++++++++++++---- lib/saxParse-persistence.h | 5 +---- 4 files changed, 38 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/jsonParse-persistence.h b/lib/jsonParse-persistence.h index fa5e772..a676282 100644 --- a/lib/jsonParse-persistence.h +++ b/lib/jsonParse-persistence.h @@ -9,7 +9,7 @@ #include namespace Persistence { - class JsonParsePersistence : public json::jsonParser { + class JsonParsePersistence : public json::jsonParser, ParseBase { public: template inline T @@ -34,8 +34,6 @@ namespace Persistence { void endArray() override; void endObject() override; - Stack stk; - template inline void pushValue(T && value); inline SelectionPtr & current(); }; diff --git a/lib/persistence.cpp b/lib/persistence.cpp index 543f2fd..8c7c6a4 100644 --- a/lib/persistence.cpp +++ b/lib/persistence.cpp @@ -157,4 +157,9 @@ namespace Persistence { throw std::logic_error("Default write op shouldn't ever get called"); } /// LCOV_EXCL_STOP + + ParseBase::ParseBase() : sharedObjectsInstance {std::make_shared()} + { + sharedObjects = sharedObjectsInstance; + } } diff --git a/lib/persistence.h b/lib/persistence.h index 458ba4d..05cb49b 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -375,9 +375,36 @@ namespace Persistence { return true; } + class ParseBase { + public: + using SharedObjects = std::map>; + using SharedObjectsWPtr = std::weak_ptr; + using SharedObjectsPtr = std::shared_ptr; + + ParseBase(); + DEFAULT_MOVE_NO_COPY(ParseBase); + + template + static auto + getShared(auto && k) + { + return std::dynamic_pointer_cast(Persistence::ParseBase::sharedObjects.lock()->at(k)); + } + template + static auto + emplaceShared(T &&... v) + { + return sharedObjects.lock()->emplace(std::forward(v)...); + } + + protected: + Stack stk; + + private: + inline static thread_local SharedObjectsWPtr sharedObjects; + SharedObjectsPtr sharedObjectsInstance; + }; // TODO Move these - using SharedObjects = std::map>; - inline SharedObjects sharedObjects; using SeenSharedObjects = std::map; inline SeenSharedObjects seenSharedObjects; @@ -417,7 +444,7 @@ namespace Persistence { void setValue(std::string && id) override { - sharedObjects.emplace(id, this->v); + ParseBase::emplaceShared(id, this->v); } }; @@ -538,7 +565,7 @@ namespace Persistence { void setValue(std::string && id) override { - if (auto teo = std::dynamic_pointer_cast(sharedObjects.at(id))) { + if (auto teo = ParseBase::getShared(id)) { this->v = std::move(teo); } else { diff --git a/lib/saxParse-persistence.h b/lib/saxParse-persistence.h index 91daecc..6043b25 100644 --- a/lib/saxParse-persistence.h +++ b/lib/saxParse-persistence.h @@ -6,7 +6,7 @@ #include namespace Persistence { - class SAXParsePersistence : public SAXParse { + class SAXParsePersistence : public SAXParse, ParseBase { private: template struct Root : public Persistable { T t {}; @@ -36,8 +36,5 @@ namespace Persistence { void data(mxml_node_t *) override; void directive(mxml_node_t *) override; void cdata(mxml_node_t *) override; - - private: - Stack stk; }; } -- cgit v1.2.3 From d1390c8673b178744acd6aa3a681f7b51ed9438f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 2 Mar 2023 23:41:10 +0000 Subject: Don't leak root node when parsing XML --- lib/saxParse.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/saxParse.cpp b/lib/saxParse.cpp index d592a1f..5c597aa 100644 --- a/lib/saxParse.cpp +++ b/lib/saxParse.cpp @@ -11,7 +11,7 @@ namespace Persistence { void SAXParse::parseFile(FILE * file) { - mxmlSAXLoadFile( + mxmlRelease(mxmlSAXLoadFile( nullptr, file, MXML_TEXT_CALLBACK, [](mxml_node_t * n, mxml_sax_event_t e, void * data) { SAXParse * self = static_cast(data); @@ -36,6 +36,6 @@ namespace Persistence { break; } }, - this); + this)); } } -- cgit v1.2.3