From: Mikko Rasa Date: Sun, 10 Dec 2023 21:10:08 +0000 (+0200) Subject: Use standard smart pointers for memory management X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=9623a5c031fbae41e1eeb23d728ca441427d5de8;p=libs%2Fdatafile.git Use standard smart pointers for memory management Collection and related classes now use std::unique_ptr to make ownership transfers explicit. --- diff --git a/Build b/Build index d934f3f..5e962e6 100644 --- a/Build +++ b/Build @@ -8,7 +8,7 @@ package "mspdatafile" build_info { - standard CXX "c++11"; + standard CXX "c++14"; }; library "mspdatafile" diff --git a/source/builtinsource.cpp b/source/builtinsource.cpp index 5645467..836d15d 100644 --- a/source/builtinsource.cpp +++ b/source/builtinsource.cpp @@ -43,11 +43,11 @@ void BuiltinSource::load(Collection &coll, const CollectionItemTypeBase &type, c } } -IO::Seekable *BuiltinSource::open(const string &name) const +unique_ptr BuiltinSource::open(const string &name) const { auto i = objects.find(name); if(i!=objects.end()) - return new IO::Memory(i->second.data, i->second.size); + return make_unique(i->second.data, i->second.size); return nullptr; } diff --git a/source/builtinsource.h b/source/builtinsource.h index 5224286..1a78b14 100644 --- a/source/builtinsource.h +++ b/source/builtinsource.h @@ -28,7 +28,7 @@ public: bool is_loadable(const CollectionItemTypeBase &, const std::string &) const override; NameList get_names(const CollectionItemTypeBase &) const override; void load(Collection &, const CollectionItemTypeBase &, const std::string &) const override; - IO::Seekable *open(const std::string &) const override; + std::unique_ptr open(const std::string &) const override; }; } // namespace DataFile diff --git a/source/collection.cpp b/source/collection.cpp index e1c25dd..b9b17f4 100644 --- a/source/collection.cpp +++ b/source/collection.cpp @@ -7,12 +7,6 @@ using namespace std; namespace Msp { namespace DataFile { -Collection::~Collection() -{ - for(CollectionItemTypeBase *t: types) - delete t; -} - void Collection::add_var(const string &name, const CollectionItemTypeBase *type, const Variant &var) { insert_unique(items, name, var); @@ -100,17 +94,17 @@ unsigned Collection::get_status(const string &name, const CollectionItemTypeBase CollectionItemTypeBase *Collection::get_type(const CollectionItemTypeBase &type) const { - for(CollectionItemTypeBase *t: types) + for(const auto &t: types) if(t->is_same_type(type)) - return t; + return t.get(); return nullptr; } CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const { - for(CollectionItemTypeBase *t: types) + for(const auto &t: types) if(t->check_item_type(var)) - return t; + return t.get(); return nullptr; } @@ -119,10 +113,10 @@ void Collection::add_source(const CollectionSource &s) sources.push_back(&s); } -IO::Seekable *Collection::open_raw(const string &name) const +unique_ptr Collection::open_raw(const string &name) const { for(const CollectionSource *s: sources) - if(IO::Seekable *io = s->open(name)) + if(unique_ptr io = s->open(name)) return io; return nullptr; @@ -164,17 +158,11 @@ void Collection::set_fallback(Collection *f) Collection::Loader::Loader(Collection &c): coll(c) { - for(const CollectionItemTypeBase *t: coll.types) + for(const auto &t: coll.types) t->add_to_loader(*this); } -CollectionItemTypeBase::~CollectionItemTypeBase() -{ - for(ExtractorBase *e: extractors) - delete e; -} - void CollectionItemTypeBase::set_keyword(const string &k) { kwd = k; diff --git a/source/collection.h b/source/collection.h index 3a4bf9d..ad66523 100644 --- a/source/collection.h +++ b/source/collection.h @@ -1,11 +1,11 @@ #ifndef MSP_DATAFILE_COLLECTION_H_ #define MSP_DATAFILE_COLLECTION_H_ +#include #include #include #include #include -#include #include "collectionsource.h" #include "loader.h" #include "meta.h" @@ -73,11 +73,10 @@ public: template void item(const std::string &n) { - RefPtr it = new T; + std::unique_ptr it = std::make_unique(); ItemLoader ldr(*it, coll); load_sub_with(ldr); - coll.add(n, it.get()); - it.release(); + coll.add(n, std::move(it)); } }; @@ -87,34 +86,24 @@ public: private: using ItemMap = std::map; - std::vector types; + std::vector> types; ItemMap items; std::vector sources; Collection *fallback = nullptr; public: - virtual ~Collection(); + virtual ~Collection() = default; /** Adds an object into the collection. The name must not pre-exist. The collection takes ownership of the object. */ template - void add(const std::string &name, T *item) + void add(const std::string &name, std::unique_ptr item) { if(!item) throw std::invalid_argument("Collection::add(item)"); using NCT = typename std::remove_cv::type; - RefPtr ptr(item); - try - { - add_var(name, get_type(name), ptr); - } - catch(...) - { - // Avoid deleting the object - ptr.release(); - throw; - } + add_var(name, get_type(name), std::shared_ptr(std::move(item))); } /// Gets a typed object from the collection. @@ -234,7 +223,7 @@ private: return get_status(name, *type); ItemMap::const_iterator i = items.find(name); - return (i!=items.end() && i->second.has_type >()); + return (i!=items.end() && i->second.has_type>()); } public: @@ -253,11 +242,11 @@ public: template const std::string &get_name(T *d) const { - using RPNCT = RefPtr::type>; + using PNCT = std::shared_ptr::type>; for(const auto &kvp: items) - if(kvp.second.has_type()) - if(kvp.second.value().get()==d) + if(kvp.second.has_type()) + if(kvp.second.value().get()==d) return kvp.first; // XXX Need better exception class @@ -296,7 +285,7 @@ public: /** Opens a raw resource, without interpreting it as object data. Null is returned if no such file is found. The caller must dispose of the returned object when done with it. */ - IO::Seekable *open_raw(const std::string &) const; + std::unique_ptr open_raw(const std::string &) const; private: void gather_names_from_sources(std::list &, const CollectionItemTypeBase &) const; @@ -346,13 +335,10 @@ protected: std::string kwd; std::vector suffixes; - std::vector extractors; + std::vector> extractors; CollectionItemTypeBase() = default; -public: - virtual ~CollectionItemTypeBase(); -protected: void set_keyword(const std::string &); void add_suffix(const std::string &); public: @@ -369,8 +355,8 @@ public: template bool can_extract() const { - for(ExtractorBase *e: extractors) - if(dynamic_cast *>(e)) + for(const auto &e: extractors) + if(dynamic_cast *>(e.get())) return true; return false; } @@ -378,8 +364,8 @@ public: template T *extract(const Variant &var) const { - for(ExtractorBase *e: extractors) - if(Extractor *ex = dynamic_cast *>(e)) + for(const auto &e: extractors) + if(Extractor *ex = dynamic_cast *>(e.get())) return &ex->extract(var); return 0; } @@ -398,10 +384,10 @@ private: struct Extractor: CollectionItemTypeBase::Extractor { B &extract(const Variant &var) const override - { return *var.value >(); } + { return *var.value>(); } }; - std::function create_func; + std::function (const std::string &)> create_func; std::vector> notify_funcs; public: @@ -441,7 +427,7 @@ public: template CollectionItemType &base() { - extractors.push_back(new Extractor); + extractors.push_back(std::make_unique>()); return *this; } @@ -456,7 +442,7 @@ public: { return dynamic_cast *>(&other); } bool check_item_type(const Variant &var) const override - { return var.has_type >(); } + { return var.has_type>(); } void add_to_loader(Collection::Loader &) const override { } @@ -468,9 +454,9 @@ public: { if(!create_func) throw std::runtime_error("no creator"); - T *obj = create_func(name); + std::unique_ptr obj = create_func(name); if(obj) - coll.add(name, obj); + coll.add(name, move(obj)); } void load_item(Collection &, Parser &, const std::string &) const override @@ -480,7 +466,7 @@ public: void notify_item(const std::string &name, const Variant &var) const override { - RefPtr obj = var.value >(); + std::shared_ptr obj = var.value>(); for(const auto &n: notify_funcs) n(name, *obj); } @@ -496,11 +482,10 @@ public: void load_item(Collection &coll, Parser &parser, const std::string &name) const override { - RefPtr obj = new T; + std::unique_ptr obj = std::make_unique(); Collection::ItemLoader ldr(*obj, coll); ldr.load(parser); - coll.add(name, obj.get()); - obj.release(); + coll.add(name, std::move(obj)); } }; @@ -508,20 +493,19 @@ public: template T &Collection::extract(const Variant &var) const { - if(!var.has_type >()) + if(!var.has_type>()) if(CollectionItemTypeBase *type = get_type_for_item(var)) if(T *item = type->extract(var)) return *item; - return *var.value >(); + return *var.value>(); } template typename CollectionItemTypeChooser::Type &Collection::add_type() { - typename CollectionItemTypeChooser::Type *type = new typename CollectionItemTypeChooser::Type; - types.push_back(type); - return *type; + types.emplace_back(std::make_unique::Type>()); + return static_cast::Type &>(*types.back()); } template @@ -537,16 +521,16 @@ typename CollectionItemTypeChooser::Type &Collection::modify_type() template CollectionItemTypeBase *Collection::get_type(const std::string &name) const { - for(CollectionItemTypeBase *t: types) - if(dynamic_cast *>(t)) - return t; + for(const auto &t: types) + if(dynamic_cast *>(t.get())) + return t.get(); CollectionItemTypeBase *type = nullptr; - for(CollectionItemTypeBase *t: types) + for(const auto &t: types) if(t->can_extract()) { if(!name.empty() && t->match_name(name)) - return t; - type = t; + return t.get(); + type = t.get(); } return type; } diff --git a/source/collectionsource.h b/source/collectionsource.h index e2757a0..10f71ba 100644 --- a/source/collectionsource.h +++ b/source/collectionsource.h @@ -2,6 +2,7 @@ #define COLLECTIONSOURCE_H_ #include +#include #include #include #include "mspdatafile_api.h" @@ -38,7 +39,7 @@ public: /** Opens a raw resource. The caller is responsible for deleting the returned object when done with it. */ - virtual IO::Seekable *open(const std::string &) const = 0; + virtual std::unique_ptr open(const std::string &) const = 0; }; } // namespace DataFile diff --git a/source/directorysource.cpp b/source/directorysource.cpp index 7e1e438..a933977 100644 --- a/source/directorysource.cpp +++ b/source/directorysource.cpp @@ -40,11 +40,11 @@ void DirectorySource::load(Collection &coll, const CollectionItemTypeBase &type, } } -IO::Seekable *DirectorySource::open(const string &name) const +unique_ptr DirectorySource::open(const string &name) const { FS::Path file; if(lookup_file(name, file)) - return new IO::BufferedFile(file.str()); + return make_unique(file.str()); return nullptr; } diff --git a/source/directorysource.h b/source/directorysource.h index df1fc1f..7e2066b 100644 --- a/source/directorysource.h +++ b/source/directorysource.h @@ -24,7 +24,7 @@ public: bool is_loadable(const CollectionItemTypeBase &, const std::string &) const override; NameList get_names(const CollectionItemTypeBase &) const override; void load(Collection &, const CollectionItemTypeBase &, const std::string &) const override; - IO::Seekable *open(const std::string &) const override; + std::unique_ptr open(const std::string &) const override; bool lookup_file(const std::string &, FS::Path &) const; }; diff --git a/source/dynamicobjectloader.h b/source/dynamicobjectloader.h index fd4e153..43c4b1f 100644 --- a/source/dynamicobjectloader.h +++ b/source/dynamicobjectloader.h @@ -1,6 +1,7 @@ #ifndef MSP_DATAFILE_DYNAMICOBJECTLOADER_H_ #define MSP_DATAFILE_DYNAMICOBJECTLOADER_H_ +#include #include #include "collection.h" #include "except.h" @@ -31,23 +32,21 @@ protected: using TypeRegistry = Msp::TypeRegistry; Collection *coll = nullptr; - T *object = nullptr; + std::unique_ptr object = nullptr; private: - Loader *obj_loader = nullptr; - void (*store_func)(Collection &, const std::string &, T *) = nullptr; + std::unique_ptr obj_loader = nullptr; + void (*store_func)(Collection &, const std::string &, std::unique_ptr) = nullptr; static ActionMap shared_actions; protected: DynamicObjectLoader(Collection *); -public: - ~DynamicObjectLoader() { delete object; delete obj_loader; } private: void init_actions() override; public: - T *get_object() { T *o = object; object = 0; return o; } + std::unique_ptr get_object() { return std::move(object); } T *store_object(Collection &, const std::string &); protected: @@ -55,10 +54,10 @@ protected: private: template - typename std::enable_if::value, typename U::Loader *>::type create_object_loader(U &obj) const; + typename std::enable_if::value, std::unique_ptr>::type create_object_loader(U &obj) const; template - typename std::enable_if::value, typename U::Loader *>::type create_object_loader(U &obj) const; + typename std::enable_if::value, std::unique_ptr>::type create_object_loader(U &obj) const; protected: virtual const TypeRegistry &get_type_registry() const = 0; @@ -87,9 +86,8 @@ T *DynamicObjectLoader::store_object(Collection &c, const std::string &nam if(!store_func) throw std::logic_error("no store function"); - T *o = object; - store_func(c, name, object); - object = 0; + T *o = object.get(); + store_func(c, name, std::move(object)); return o; } @@ -104,18 +102,18 @@ void DynamicObjectLoader::type(const Symbol &t) template template -typename std::enable_if::value, typename U::Loader *>::type DynamicObjectLoader::create_object_loader(U &obj) const +typename std::enable_if::value, std::unique_ptr>::type DynamicObjectLoader::create_object_loader(U &obj) const { if(!coll) throw no_collection(typeid(U)); - return new typename U::Loader(obj, *coll); + return std::make_unique(obj, *coll); } template template -typename std::enable_if::value, typename U::Loader *>::type DynamicObjectLoader::create_object_loader(U &obj) const +typename std::enable_if::value, std::unique_ptr>::type DynamicObjectLoader::create_object_loader(U &obj) const { - return new typename U::Loader(obj); + return std::make_unique(obj); } @@ -123,11 +121,10 @@ template template void DynamicObjectLoader::CreateObject::operator()(const std::string &, DynamicObjectLoader &ldr) const { - U *obj = new U; - ldr.object = obj; - ldr.obj_loader = ldr.create_object_loader(*obj); + ldr.object = std::make_unique(); + ldr.obj_loader = ldr.create_object_loader(static_cast(*ldr.object)); ldr.add_auxiliary_loader(*ldr.obj_loader); - ldr.store_func = [](Collection &c, const std::string &n, T *o){ c.add(n, static_cast(o)); }; + ldr.store_func = [](Collection &c, const std::string &n, std::unique_ptr o){ c.add(n, std::unique_ptr(static_cast(o.release()))); }; } } // namespace DataFile diff --git a/source/input.cpp b/source/input.cpp index 4496439..1482e09 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -1,6 +1,8 @@ #include #include "input.h" +using namespace std; + namespace Msp { namespace DataFile { @@ -8,15 +10,10 @@ Input::Input(IO::Base &i): in(&i) { } -Input::~Input() -{ - delete compressed; -} - void Input::set_decompress() { - compressed = new IO::ZlibCompressed(*in, IO::M_READ); - in = compressed; + compressed = make_unique(*in, IO::M_READ); + in = compressed.get(); } int Input::get() diff --git a/source/input.h b/source/input.h index 7f4dd7b..c335ecc 100644 --- a/source/input.h +++ b/source/input.h @@ -1,6 +1,7 @@ #ifndef MSP_DATAFILE_INPUT_H_ #define MSP_DATAFILE_INPUT_H_ +#include #include #include @@ -11,13 +12,12 @@ class Input: private NonCopyable { private: IO::Base *in = nullptr; - IO::Base *compressed = nullptr; + std::unique_ptr compressed; unsigned line = 1; int next = -1; public: Input(IO::Base &); - ~Input(); void set_decompress(); int get(); diff --git a/source/loader.cpp b/source/loader.cpp index 75638a6..afd803b 100644 --- a/source/loader.cpp +++ b/source/loader.cpp @@ -167,20 +167,13 @@ void Loader::set_actions(ActionMap &a) init_actions(); } -void Loader::add(const string &kwd, LoaderAction *act) +void Loader::add(const string &kwd, unique_ptr act) { if(!actions) actions = &local_actions; StatementKey key(kwd, act->get_signature()); - ActionMap::iterator i = actions->find(key); - if(i!=actions->end()) - { - delete i->second; - i->second = act; - } - else - (*actions)[key] = act; + (*actions)[key] = move(act); } void Loader::add_auxiliary_loader(Loader &ldr) @@ -218,7 +211,7 @@ LoaderAction *Loader::find_action(const StatementKey &key) const int m = signature_match(key.signature, i->first.signature); if(m>match) { - act = i->second; + act = i->second.get(); match = m; } } @@ -261,12 +254,5 @@ const string &Loader::get_keyword() const return cur_st->keyword; } - -Loader::ActionMap::~ActionMap() -{ - for(const auto &kvp: *this) - delete kvp.second; -} - } // namespace DataFile } // namespace Msp diff --git a/source/loader.h b/source/loader.h index 59ebc23..0cab090 100644 --- a/source/loader.h +++ b/source/loader.h @@ -1,8 +1,9 @@ #ifndef MSP_DATAFILE_LOADER_H_ #define MSP_DATAFILE_LOADER_H_ -#include +#include #include +#include #include #include "loaderaction.h" #include "meta.h" @@ -38,11 +39,7 @@ See also classes ObjectLoader and CollectionObjectLoader in objectloader.h. class MSPDATAFILE_API Loader: private NonCopyable { protected: - class MSPDATAFILE_API ActionMap: public std::map, private NonCopyable - { - public: - ~ActionMap(); - }; + using ActionMap = std::map>; private: ActionMap local_actions; @@ -104,41 +101,41 @@ protected: /** Adds a keyword that is loaded by calling a function. */ template void add(const std::string &k, void (L::*func)()) - { add(k, new LoaderFunc0(func)); } + { add(k, std::make_unique>(func)); } template void add(const std::string &k, void (L::*func)(A0)) - { add(k, new LoaderFunc1(func)); } + { add(k, std::make_unique>(func)); } template void add(const std::string &k, void (L::*func)(Args...)) - { add(k, new LoaderFuncN(func)); } + { add(k, std::make_unique>(func)); } /** Adds a keyword that is loaded by calling a function with a bound first argument. */ template void add(const std::string &k, void (L::*func)(B0, Args...), const typename std::remove_reference::type &b0) - { add(k, new LoaderFuncNBound1(func, b0)); } + { add(k, std::make_unique>(func, b0)); } template void add(const std::string &k, void (L::*func)(B0, Args...), B0 &&b0) - { add(k, new LoaderFuncNBound1(func, std::forward(b0))); } + { add(k, std::make_unique>(func, std::forward(b0))); } /** Adds a keyword that is loaded into a member of the loaded object. */ template void add(const std::string &k, T0 L::*p0) - { add(k, new LoadValue1(p0)); } + { add(k, std::make_unique>(p0)); } template void add(const std::string &k, T0 L::*p0, T1 L::*p1) - { add(k, new LoadValue2(p0, p1)); } + { add(k, std::make_unique>(p0, p1)); } /** Adds a keyword that is recognized but ignored. */ void add(const std::string &k) - { add(k, new LoaderDiscard); } + { add(k, std::make_unique()); } private: - void add(const std::string &, LoaderAction *); + void add(const std::string &, std::unique_ptr); protected: void add_auxiliary_loader(Loader &); @@ -185,7 +182,7 @@ followed by any extra arguments. template void load(T &obj, typename T::Loader::Collection &coll, const std::string &fn, Args &&... args) { - RefPtr in = coll.open_raw(fn); + std::unique_ptr in = coll.open_raw(fn); if(!in) throw IO::file_not_found(fn); @@ -201,7 +198,7 @@ public Loader class. Any extra arguments are passed to the Loader constructor. template typename std::enable_if::value>::type load(T &obj, C &coll, const std::string &fn, Args &&... args) { - RefPtr in = coll.open_raw(fn); + std::unique_ptr in = coll.open_raw(fn); if(!in) throw IO::file_not_found(fn); diff --git a/source/output.cpp b/source/output.cpp index 46d270a..5388716 100644 --- a/source/output.cpp +++ b/source/output.cpp @@ -10,15 +10,10 @@ Output::Output(IO::Base &o): out(&o) { } -Output::~Output() -{ - delete compressed; -} - void Output::set_compressed() { - compressed = new IO::ZlibCompressed(*out, IO::M_WRITE); - out = compressed; + compressed = make_unique(*out, IO::M_WRITE); + out = compressed.get(); } size_t Output::put(char c) diff --git a/source/output.h b/source/output.h index 4a4bc81..351e292 100644 --- a/source/output.h +++ b/source/output.h @@ -1,6 +1,7 @@ #ifndef MSP_DATAFILE_OUTPUT_H_ #define MSP_DATAFILE_OUTPUT_H_ +#include #include #include @@ -11,11 +12,10 @@ class Output: private NonCopyable { private: IO::Base *out = nullptr; - IO::Base *compressed = nullptr; + std::unique_ptr compressed; public: Output(IO::Base &); - ~Output(); void set_compressed(); diff --git a/source/packsource.cpp b/source/packsource.cpp index 0fb6484..84cdebd 100644 --- a/source/packsource.cpp +++ b/source/packsource.cpp @@ -138,7 +138,7 @@ void PackSource::load(Collection &coll, const CollectionItemTypeBase &type, cons const File &file = i->second->get_file(); - RefPtr in = file.open(); + unique_ptr in = file.open(); Parser parser(*in, file.get_full_name()); if(file.is_collection()) { @@ -149,11 +149,11 @@ void PackSource::load(Collection &coll, const CollectionItemTypeBase &type, cons type.load_item(coll, parser, name); } -IO::Seekable *PackSource::open(const string &fn) const +unique_ptr PackSource::open(const string &fn) const { auto i = files.find(fn); if(i!=files.end()) - return i->second->open().release(); + return i->second->open(); return nullptr; } @@ -216,15 +216,15 @@ PackSource::File::File(const File &other, const Pack &p): objects.push_back(Object(o, *this)); } -RefPtr PackSource::File::open() const +unique_ptr PackSource::File::open() const { if(pack.get_io()) // TODO Performance may be poor without buffering - return new IO::Slice(*pack.get_io(), pack.get_base_offset()+offset, length); + return make_unique(*pack.get_io(), pack.get_base_offset()+offset, length); else { IO::BufferedFile *io_file = new IO::BufferedFile(pack.get_filename()); - IO::Slice *io_slice = new IO::Slice(*io_file, pack.get_base_offset()+offset, length); + unique_ptr io_slice = make_unique(*io_file, pack.get_base_offset()+offset, length); io_slice->signal_deleted.connect(sigc::bind(sigc::ptr_fun(delete_io), io_file)); return io_slice; } diff --git a/source/packsource.h b/source/packsource.h index c30e8f6..16d72ad 100644 --- a/source/packsource.h +++ b/source/packsource.h @@ -1,8 +1,8 @@ #ifndef MSP_DATAFILE_PACKSOURCE_H_ #define MSP_DATAFILE_PACKSOURCE_H_ +#include #include -#include #include "collectionsource.h" #include "mspdatafile_api.h" #include "objectloader.h" @@ -90,7 +90,7 @@ private: File(const Pack &, const std::string &); File(const File &, const Pack &); - RefPtr open() const; + std::unique_ptr open() const; const std::string &get_filename() const { return filename; } FileInfo get_info() const; std::string get_full_name() const; @@ -154,7 +154,7 @@ public: bool is_loadable(const CollectionItemTypeBase &, const std::string &) const override; NameList get_names(const CollectionItemTypeBase &) const override; void load(Collection &, const CollectionItemTypeBase &, const std::string &) const override; - IO::Seekable *open(const std::string &) const override; + std::unique_ptr open(const std::string &) const override; }; } // namespace DataFile diff --git a/source/parser.cpp b/source/parser.cpp index e0ad854..3dfd9ae 100644 --- a/source/parser.cpp +++ b/source/parser.cpp @@ -18,15 +18,12 @@ Parser::Parser(IO::Base &i, const string &s): { char c = in.peek(); if(c=='{' || c=='[') - mode = new JsonParser(in, src); + mode = make_unique(in, src); else - mode = new TextParser(in, src); + mode = make_unique(in, src); } -Parser::~Parser() -{ - delete mode; -} +Parser::~Parser() = default; Statement Parser::parse(bool raw) { @@ -64,17 +61,13 @@ void Parser::process_control_statement(const Statement &st) { if(st.keyword=="__bin") { - delete mode; - mode = new BinaryParser(in, src); + mode = make_unique(in, src); while(in.peek()=='\n') in.get(); } else if(st.keyword=="__text") - { - delete mode; - mode = new TextParser(in, src); - } + mode = make_unique(in, src); else if(st.keyword=="__z") in.set_decompress(); else if(st.keyword=="__src") diff --git a/source/parser.h b/source/parser.h index 84ba9de..0b87296 100644 --- a/source/parser.h +++ b/source/parser.h @@ -1,6 +1,7 @@ #ifndef MSP_DATAFILE_PARSER_H_ #define MSP_DATAFILE_PARSER_H_ +#include #include #include #include "input.h" @@ -27,7 +28,7 @@ private: std::string main_src; std::string src; bool good = true; - ParserMode *mode = nullptr; + std::unique_ptr mode; public: Parser(IO::Base &i, const std::string &s); diff --git a/source/rawdata.cpp b/source/rawdata.cpp index a8eb5f1..7b6a019 100644 --- a/source/rawdata.cpp +++ b/source/rawdata.cpp @@ -15,9 +15,6 @@ const char RawData::signature[4] = { 'M', 'D', 'R', 1 }; RawData::~RawData() { delete[] owned_data; - delete compressed; - if(in_owned) - delete in; } bool RawData::detect_signature(const std::string &sig) @@ -30,13 +27,12 @@ void RawData::open_file(Collection &coll, const string &fn) if(in) throw logic_error("input already exists"); - RefPtr opened = coll.open_raw(fn); + unique_ptr opened = coll.open_raw(fn); if(!opened) throw IO::file_not_found(fn); open_io(*opened, fn); - opened.release(); - in_owned = true; + owned_in = move(opened); } void RawData::open_io(IO::Base &i, const string &fn) @@ -60,7 +56,7 @@ void RawData::open_io(IO::Base &i, const string &fn) src_name = fn; in = &i; if(flags&COMPRESSED) - compressed = new IO::ZlibCompressed(*in, IO::M_READ); + compressed = make_unique(*in, IO::M_READ); } void RawData::load() @@ -81,7 +77,7 @@ void RawData::load_into(void *buffer) data = static_cast(buffer); - IO::Base *src = (compressed ? compressed : in); + IO::Base *src = (compressed ? compressed.get() : in); size_t pos = 0; while(pos #include #include #include @@ -20,9 +21,9 @@ private: }; std::string src_name; + std::unique_ptr owned_in; IO::Base *in = nullptr; - bool in_owned = false; - IO::Base *compressed = nullptr; + std::unique_ptr compressed; std::size_t size = 0; char *data = nullptr; char *owned_data = nullptr; diff --git a/source/writer.cpp b/source/writer.cpp index bb3ff5e..832ac12 100644 --- a/source/writer.cpp +++ b/source/writer.cpp @@ -11,13 +11,10 @@ namespace DataFile { Writer::Writer(IO::Base &o): out(o), - mode(new TextWriter(out)) + mode(make_unique(out)) { } -Writer::~Writer() -{ - delete mode; -} +Writer::~Writer() = default; void Writer::write(const Statement &st) { @@ -39,11 +36,10 @@ void Writer::set_binary(bool b) mode->write(st); - delete mode; if(binary) - mode = new BinaryWriter(out); + mode = make_unique(out); else - mode = new TextWriter(out); + mode = make_unique(out); } void Writer::set_compressed() diff --git a/source/writer.h b/source/writer.h index 05ab369..a3c5257 100644 --- a/source/writer.h +++ b/source/writer.h @@ -2,6 +2,7 @@ #define MSP_DATAFILE_WRITER_H_ #include +#include #include #include #include "mspdatafile_api.h" @@ -20,7 +21,7 @@ class MSPDATAFILE_API Writer: private NonCopyable { private: Output out; - WriterMode *mode = nullptr; + std::unique_ptr mode; bool binary = false; public: diff --git a/tool/packer.cpp b/tool/packer.cpp index 3f175d9..dddf81d 100644 --- a/tool/packer.cpp +++ b/tool/packer.cpp @@ -17,7 +17,7 @@ Packer::Packer(DataTool &t): tmp_file(tempfile(tmp_path)) { } -IO::BufferedFile *Packer::tempfile(FS::Path &out_fn) +unique_ptr Packer::tempfile(FS::Path &out_fn) { FS::Path tmpdir = FS::get_temp_dir(); @@ -26,7 +26,7 @@ IO::BufferedFile *Packer::tempfile(FS::Path &out_fn) try { FS::Path filename = tmpdir/format("mspdatatool.%d", i); - IO::BufferedFile *file = new IO::BufferedFile(filename.str(), IO::M_RDWR, IO::File::C_NEW); + unique_ptr file = make_unique(filename.str(), IO::M_RDWR, IO::File::C_NEW); out_fn = filename; return file; } @@ -39,7 +39,7 @@ IO::BufferedFile *Packer::tempfile(FS::Path &out_fn) Packer::~Packer() { - delete tmp_file; + tmp_file.reset(); FS::unlink(tmp_path); } @@ -103,7 +103,7 @@ void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, Ob { DataFile::Parser parser(in, fn); - DataFile::Writer *writer = tool.create_writer(out); + unique_ptr writer = tool.create_writer(out); bool collection = FS::extpart(fn)==".mdc"; while(parser) @@ -128,7 +128,6 @@ void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, Ob } } writer->write(DataFile::Statement("__end")); - delete writer; } void Packer::transfer_raw_data(IO::Base &in, const string &fn, IO::Base &out) @@ -161,7 +160,7 @@ void Packer::create_pack(const string &fn) { mem.seek(0, IO::S_BEG); - DataFile::Writer *writer = tool.create_writer(mem); + unique_ptr writer = tool.create_writer(mem); for(list::const_iterator i=directory.begin(); i!=directory.end(); ++i) writer->write(*i); @@ -169,7 +168,7 @@ void Packer::create_pack(const string &fn) base_offset = mem.tell(); writer->write((DataFile::Statement("base_offset"), base_offset)); writer->write(DataFile::Statement("__end")); - delete writer; + writer.reset(); unsigned dir_size = mem.tell(); if(dir_size<=base_offset) diff --git a/tool/packer.h b/tool/packer.h index 141a2a1..4e370de 100644 --- a/tool/packer.h +++ b/tool/packer.h @@ -1,6 +1,7 @@ #ifndef PACKER_H_ #define PACKER_H_ +#include #include #include #include @@ -21,14 +22,14 @@ private: DataTool &tool; Msp::FS::Path tmp_path; - Msp::IO::BufferedFile *tmp_file = nullptr; + std::unique_ptr tmp_file; std::list directory; unsigned dir_alloc = 0; public: Packer(DataTool &); private: - static Msp::IO::BufferedFile *tempfile(Msp::FS::Path &); + static std::unique_ptr tempfile(Msp::FS::Path &); public: ~Packer(); diff --git a/tool/tool.cpp b/tool/tool.cpp index cf34474..a6b0944 100644 --- a/tool/tool.cpp +++ b/tool/tool.cpp @@ -74,12 +74,12 @@ int DataTool::main() void DataTool::do_transfer() { - IO::Base *out = open_output(out_fn); - DataFile::Writer *writer = create_writer(*out); + unique_ptr out = open_output(out_fn); + unique_ptr writer = create_writer(*out); for(list::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i) { - IO::Base *in = open_input(*i); + unique_ptr in = open_input(*i); DataFile::Parser parser(*in, *i); while(parser) @@ -88,30 +88,21 @@ void DataTool::do_transfer() if(st.valid && (!st.control || st.keyword=="__src" || debug)) writer->write(st); } - - delete in; } - - delete writer; - delete out; } void DataTool::do_compile() { - IO::Base *out = open_output(out_fn); - DataFile::Writer *writer = create_writer(*out); + unique_ptr out = open_output(out_fn); + unique_ptr writer = create_writer(*out); Compiler compiler(*writer); for(list::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i) { - IO::Base *in = open_input(*i); + unique_ptr in = open_input(*i); DataFile::Parser parser(*in, *i); compiler.load(parser); - delete in; } - - delete writer; - delete out; } void DataTool::do_pack() @@ -131,8 +122,8 @@ void DataTool::do_unpack() list files = source.list_files(); for(list::const_iterator i=files.begin(); i!=files.end(); ++i) { - IO::Seekable *in = source.open(i->name); - IO::Base *out = open_output(i->name); + unique_ptr in = source.open(i->name); + unique_ptr out = open_output(i->name); char buf[16384]; while(1) { @@ -141,41 +132,38 @@ void DataTool::do_unpack() if(len out = open_output(out_fn); BuiltinGenerator generator(*out); generator.begin(builtin_ns); for(list::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i) generator.add_file(*i); generator.end(builtin_module); - delete out; } -IO::Base *DataTool::open_output(const string &fn) +unique_ptr DataTool::open_output(const string &fn) { if(fn=="-") - return new IO::Buffered(IO::cout); + return make_unique(IO::cout); else - return new IO::BufferedFile(fn, IO::M_WRITE); + return make_unique(fn, IO::M_WRITE); } -IO::Base *DataTool::open_input(const string &fn) +unique_ptr DataTool::open_input(const string &fn) { if(fn=="-") - return new IO::Buffered(IO::cin); + return make_unique(IO::cin); else - return new IO::BufferedFile(fn, IO::M_READ); + return make_unique(fn, IO::M_READ); } -DataFile::Writer *DataTool::create_writer(IO::Base &out) +unique_ptr DataTool::create_writer(IO::Base &out) { - DataFile::Writer *writer = new DataFile::Writer(out); + unique_ptr writer = make_unique(out); if(compress) writer->set_compressed(); if(binary) diff --git a/tool/tool.h b/tool/tool.h index 2012429..f14658b 100644 --- a/tool/tool.h +++ b/tool/tool.h @@ -1,6 +1,7 @@ #ifndef TOOL_H_ #define TOOL_H_ +#include #include #include #include @@ -31,11 +32,11 @@ private: void do_pack(); void do_unpack(); void do_generate_builtin(); - Msp::IO::Base *open_output(const std::string &); - Msp::IO::Base *open_input(const std::string &); + std::unique_ptr open_output(const std::string &); + std::unique_ptr open_input(const std::string &); public: bool is_compressed() const { return compress; } - Msp::DataFile::Writer *create_writer(Msp::IO::Base &); + std::unique_ptr create_writer(Msp::IO::Base &); }; #endif