]> git.tdb.fi Git - libs/datafile.git/commitdiff
Implement proper copy semantics
authorMikko Rasa <tdb@tdb.fi>
Sun, 17 Jan 2021 10:41:50 +0000 (12:41 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 17 Jan 2021 10:51:34 +0000 (12:51 +0200)
All classes are now either safe to copy or are marked noncopyable.

13 files changed:
source/argumentstore.cpp
source/argumentstore.h
source/collection.h
source/input.h
source/loadabletyperegistry.h
source/loader.h
source/output.h
source/packsource.cpp
source/packsource.h
source/parser.h
source/parsermode.h
source/writer.h
source/writermode.h

index 532d66aaa230e49a63209be828de19ab3b5ed5aa..22cb11f5f7ccdca7547ccb3474a3eed09d27f967 100644 (file)
@@ -1,5 +1,8 @@
+#include <stdexcept>
 #include "argumentstore.h"
 
 #include "argumentstore.h"
 
+using namespace std;
+
 namespace Msp {
 namespace DataFile {
 
 namespace Msp {
 namespace DataFile {
 
@@ -19,7 +22,30 @@ ArgumentStore::ArgumentStore(const StatementInfo &n):
                }
 }
 
                }
 }
 
+ArgumentStore::ArgumentStore(const ArgumentStore &other):
+       info(other.info),
+       store(new char[info.args_size])
+{
+       copy_from(other.store);
+}
+
+ArgumentStore &ArgumentStore::operator=(const ArgumentStore &other)
+{
+       if(&other.info!=&info)
+               throw invalid_argument("ArgumentStore::operator=");
+
+       destroy();
+       copy_from(other.store);
+
+       return *this;
+}
+
 ArgumentStore::~ArgumentStore()
 ArgumentStore::~ArgumentStore()
+{
+       destroy();
+}
+
+void ArgumentStore::destroy()
 {
        for(unsigned i=0; i<info.key.signature.size(); ++i)
                switch(info.key.signature[i])
 {
        for(unsigned i=0; i<info.key.signature.size(); ++i)
                switch(info.key.signature[i])
@@ -35,5 +61,22 @@ ArgumentStore::~ArgumentStore()
        delete[] store;
 }
 
        delete[] store;
 }
 
+void ArgumentStore::copy_from(const char *other)
+{
+       for(unsigned i=0; i<info.key.signature.size(); ++i)
+               switch(info.key.signature[i])
+               {
+               case StringType::signature:
+                       new(store+info.arg_offsets[i]) StringType::Store(*reinterpret_cast<const StringType::Store *>(other+info.arg_offsets[i]));
+                       break;
+               case SymbolType::signature:
+                       new(store+info.arg_offsets[i]) SymbolType::Store(*reinterpret_cast<const SymbolType::Store *>(other+info.arg_offsets[i]));
+                       break;
+               default:
+                       copy(other+info.arg_offsets[i], other+(i+1<info.arg_offsets.size() ? info.arg_offsets[i+1] : info.args_size), store+info.arg_offsets[i]);
+                       break;
+               }
+}
+
 } // namespace DataFile
 } // namespace Msp
 } // namespace DataFile
 } // namespace Msp
index c2d5d76f3dbb473c613840c7f92dd9320fa07d5b..5f4c9dd066159831bfa60a6a40e6e8d1ded198ae 100644 (file)
@@ -14,8 +14,14 @@ private:
 
 public:
        ArgumentStore(const StatementInfo &);
 
 public:
        ArgumentStore(const StatementInfo &);
+       ArgumentStore(const ArgumentStore &);
+       ArgumentStore &operator=(const ArgumentStore &);
        ~ArgumentStore();
        ~ArgumentStore();
+private:
+       void destroy();
+       void copy_from(const char *);
 
 
+public:
        const StatementInfo &get_info() const { return info; }
 
        template<typename T>
        const StatementInfo &get_info() const { return info; }
 
        template<typename T>
index 87af3a2c2c606cde35d00abd8a20bf092744e19d..38d93213b770a167ab606f9760dc9d2fe1d50b65 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <msp/core/attributes.h>
 #include <msp/core/maputils.h>
 
 #include <msp/core/attributes.h>
 #include <msp/core/maputils.h>
+#include <msp/core/noncopyable.h>
 #include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "loader.h"
 #include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "loader.h"
@@ -49,7 +50,7 @@ that are not present.  Items retrieted from the fallback collection are shared
 between the collections, and are only deleted when all collections in the chain
 have been destroyed.
 */
 between the collections, and are only deleted when all collections in the chain
 have been destroyed.
 */
-class Collection
+class Collection: private NonCopyable
 {
 public:
        /**
 {
 public:
        /**
@@ -91,8 +92,6 @@ private:
        SourceList sources;
        Collection *fallback;
 
        SourceList sources;
        Collection *fallback;
 
-       Collection(const Collection &);
-       Collection &operator=(const Collection &);
 public:
        Collection();
        virtual ~Collection();
 public:
        Collection();
        virtual ~Collection();
index a9c96f48abce9cdf9e533e640f3913c8849e0d7f..d30abd618b755c6e4c524ba1174345a1b2da08c8 100644 (file)
@@ -1,12 +1,13 @@
 #ifndef MSP_DATAFILE_INPUT_H_
 #define MSP_DATAFILE_INPUT_H_
 
 #ifndef MSP_DATAFILE_INPUT_H_
 #define MSP_DATAFILE_INPUT_H_
 
+#include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
 
 namespace Msp {
 namespace DataFile {
 
 #include <msp/io/base.h>
 
 namespace Msp {
 namespace DataFile {
 
-class Input
+class Input: private NonCopyable
 {   
 private:
        IO::Base *in;
 {   
 private:
        IO::Base *in;
index ace98cbc11d0e09d5aa2842d67c6677c87b2ecd5..7b027cd5737d62bc4022ec71b3bb25635e96ded5 100644 (file)
@@ -16,7 +16,7 @@ must be given as a template parameter, as well as a helper template struct to
 handle the actual adding of keywords.
 */
 template<typename L, template<typename> class A>
 handle the actual adding of keywords.
 */
 template<typename L, template<typename> class A>
-class LoadableTypeRegistry: public NonCopyable
+class LoadableTypeRegistry: private NonCopyable
 {
 private:
        class TypeBase
 {
 private:
        class TypeBase
index 5dac2e6b46fd8d35b38f35fafcc3f8cdb3549387..9736d269d90ffdde9e83ea7a835032cad98ebd16 100644 (file)
@@ -33,7 +33,7 @@ destructor.
 
 See also classes ObjectLoader and CollectionObjectLoader in objectloader.h.
 */
 
 See also classes ObjectLoader and CollectionObjectLoader in objectloader.h.
 */
-class Loader
+class Loader: private NonCopyable
 {
 protected:
        typedef std::map<StatementKey, LoaderAction *> ActionMap;
 {
 protected:
        typedef std::map<StatementKey, LoaderAction *> ActionMap;
index 13dc829adaf7d3968f5f0ac78b60387e7b5db418..bd75651d1ebaef4f0ba3108918126b1d76bda144 100644 (file)
@@ -1,12 +1,13 @@
 #ifndef MSP_DATAFILE_OUTPUT_H_
 #define MSP_DATAFILE_OUTPUT_H_
 
 #ifndef MSP_DATAFILE_OUTPUT_H_
 #define MSP_DATAFILE_OUTPUT_H_
 
+#include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
 
 namespace Msp {
 namespace DataFile {
 
 #include <msp/io/base.h>
 
 namespace Msp {
 namespace DataFile {
 
-class Output
+class Output: private NonCopyable
 {
 private:
        IO::Base *out;
 {
 private:
        IO::Base *out;
index ec7232aa3f057fb51786d146675142483a788490..b9f601668e44f13be8f7b5ae017d5dc13ed5be1d 100644 (file)
@@ -18,6 +18,31 @@ void delete_io(Msp::IO::Base *io)
 namespace Msp {
 namespace DataFile {
 
 namespace Msp {
 namespace DataFile {
 
+PackSource::PackSource(const PackSource &other):
+       packs(other.packs),
+       files(other.files),
+       objects(other.objects)
+{
+       translate_maps(other);
+}
+
+PackSource &PackSource::operator=(const PackSource &other)
+{
+       packs = list<Pack>(other.packs.begin(), other.packs.end());
+       files = other.files;
+       objects = other.objects;
+       translate_maps(other);
+       return *this;
+}
+
+void PackSource::translate_maps(const PackSource &other)
+{
+       for(list<Pack>::const_iterator i=packs.begin(), j=other.packs.begin(); (i!=packs.end() && j!=other.packs.end()); ++i, ++j)
+               i->translate_files(files, *j);
+       for(FileMap::const_iterator i=files.begin(), j=other.files.begin(); (i!=files.end() && j!=other.files.end()); ++i, ++j)
+               i->second->translate_objects(objects, *j->second);
+}
+
 void PackSource::add_pack_file(const string &fn)
 {
        add_pack_file(fn, string());
 void PackSource::add_pack_file(const string &fn)
 {
        add_pack_file(fn, string());
@@ -142,6 +167,15 @@ PackSource::Pack::Pack(IO::Seekable *i, const string &fn):
        base_offset(0)
 { }
 
        base_offset(0)
 { }
 
+PackSource::Pack::Pack(const Pack &other):
+       filename(other.filename),
+       io(other.io),
+       base_offset(other.base_offset)
+{
+       for(list<File>::const_iterator i=other.files.begin(); i!=other.files.end(); ++i)
+               files.push_back(File(*i, *this));
+}
+
 void PackSource::Pack::collect_files(FileMap &fm, const string &filter) const
 {
        if(filter.empty())
 void PackSource::Pack::collect_files(FileMap &fm, const string &filter) const
 {
        if(filter.empty())
@@ -158,6 +192,16 @@ void PackSource::Pack::collect_files(FileMap &fm, const string &filter) const
        }
 }
 
        }
 }
 
+void PackSource::Pack::translate_files(FileMap &fm, const Pack &source) const
+{
+       for(list<File>::const_iterator i=files.begin(), j=source.files.begin(); (i!=files.end() && j!=source.files.end()); ++i, ++j)
+       {
+               FileMap::iterator k = fm.find(i->get_filename());
+               if(k!=fm.end() && k->second==&*j)
+                       k->second = &*i;
+       }
+}
+
 
 PackSource::File::File(const Pack &p, const string &fn):
        pack(p),
 
 PackSource::File::File(const Pack &p, const string &fn):
        pack(p),
@@ -167,6 +211,17 @@ PackSource::File::File(const Pack &p, const string &fn):
        collection(false)
 { }
 
        collection(false)
 { }
 
+PackSource::File::File(const File &other, const Pack &p):
+       pack(p),
+       filename(other.filename),
+       offset(other.offset),
+       length(other.length),
+       collection(other.collection)
+{
+       for(list<Object>::const_iterator i=other.objects.begin(); i!=other.objects.end(); ++i)
+               objects.push_back(Object(*i, *this));
+}
+
 RefPtr<IO::Seekable> PackSource::File::open() const
 {
        if(pack.get_io())
 RefPtr<IO::Seekable> PackSource::File::open() const
 {
        if(pack.get_io())
@@ -200,6 +255,16 @@ void PackSource::File::collect_objects(ObjectMap &objs) const
                objs[i->get_name()] = &*i;
 }
 
                objs[i->get_name()] = &*i;
 }
 
+void PackSource::File::translate_objects(ObjectMap &objs, const File &source) const
+{
+       for(list<Object>::const_iterator i=objects.begin(), j=source.objects.begin(); (i!=objects.end() && j!=source.objects.end()); ++i, ++j)
+       {
+               ObjectMap::iterator k = objs.find(i->get_name());
+               if(k!=objs.end() && k->second==&*j)
+                       k->second = &*i;
+       }
+}
+
 
 PackSource::Object::Object(const File &f, const string &n, const string &k):
        file(f),
 
 PackSource::Object::Object(const File &f, const string &n, const string &k):
        file(f),
@@ -207,6 +272,12 @@ PackSource::Object::Object(const File &f, const string &n, const string &k):
        keyword(k)
 { }
 
        keyword(k)
 { }
 
+PackSource::Object::Object(const Object &other, const File &f):
+       file(f),
+       name(other.name),
+       keyword(other.keyword)
+{ }
+
 
 PackSource::Pack::Loader::Loader(Pack &p):
        ObjectLoader<Pack>(p)
 
 PackSource::Pack::Loader::Loader(Pack &p):
        ObjectLoader<Pack>(p)
index 56590b16cf222f82b5b0c90ad1ab0ce7ecd53c61..3694a3bf8b530e22d0ccf366cc4e251e1ce2793c 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_PACKSOURCE_H_
 #define MSP_DATAFILE_PACKSOURCE_H_
 
 #ifndef MSP_DATAFILE_PACKSOURCE_H_
 #define MSP_DATAFILE_PACKSOURCE_H_
 
+#include <msp/core/noncopyable.h>
 #include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "objectloader.h"
 #include <msp/core/refptr.h>
 #include "collectionsource.h"
 #include "objectloader.h"
@@ -54,12 +55,14 @@ private:
 
        public:
                Pack(IO::Seekable *, const std::string &);
 
        public:
                Pack(IO::Seekable *, const std::string &);
+               Pack(const Pack &);
 
                const std::string &get_filename() const { return filename; }
                IO::Seekable *get_io() const { return io; }
                IO::SeekOffset get_base_offset() const { return base_offset; }
 
                void collect_files(FileMap &, const std::string &) const;
 
                const std::string &get_filename() const { return filename; }
                IO::Seekable *get_io() const { return io; }
                IO::SeekOffset get_base_offset() const { return base_offset; }
 
                void collect_files(FileMap &, const std::string &) const;
+               void translate_files(FileMap &, const Pack &) const;
        };
 
        class File
        };
 
        class File
@@ -84,6 +87,7 @@ private:
 
        public:
                File(const Pack &, const std::string &);
 
        public:
                File(const Pack &, const std::string &);
+               File(const File &, const Pack &);
 
                RefPtr<IO::Seekable> open() const;
                const std::string &get_filename() const { return filename; }
 
                RefPtr<IO::Seekable> open() const;
                const std::string &get_filename() const { return filename; }
@@ -92,6 +96,7 @@ private:
                bool is_collection() const { return collection; }
 
                void collect_objects(ObjectMap &) const;
                bool is_collection() const { return collection; }
 
                void collect_objects(ObjectMap &) const;
+               void translate_objects(ObjectMap &, const File &) const;
        };
 
        class Object
        };
 
        class Object
@@ -103,6 +108,7 @@ private:
 
        public:
                Object(const File &, const std::string &, const std::string &);
 
        public:
                Object(const File &, const std::string &, const std::string &);
+               Object(const Object &, const File &);
 
                const File &get_file() const { return file; }
                const std::string &get_name() const { return name; }
 
                const File &get_file() const { return file; }
                const std::string &get_name() const { return name; }
@@ -113,6 +119,13 @@ private:
        FileMap files;
        ObjectMap objects;
 
        FileMap files;
        ObjectMap objects;
 
+public:
+       PackSource() { }
+       PackSource(const PackSource &);
+       PackSource &operator=(const PackSource &);
+private:
+       void translate_maps(const PackSource &);
+
 public:
        /// Adds a pack file to load objects from.  The index is read immediately.
        void add_pack_file(const std::string &);
 public:
        /// Adds a pack file to load objects from.  The index is read immediately.
        void add_pack_file(const std::string &);
index 1437190b606b89640afabd4619a62c4fe21f65c8..d1879604b5fd8f566dd21829fbe042e7fcee3381 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_DATAFILE_PARSER_H_
 
 #include <string>
 #define MSP_DATAFILE_PARSER_H_
 
 #include <string>
+#include <msp/core/noncopyable.h>
 #include "input.h"
 
 namespace Msp {
 #include "input.h"
 
 namespace Msp {
@@ -18,7 +19,7 @@ Frontend for loading datafiles.  Handles switching between text and binary
 formats.  A Parser evaluates into a boolean value indicating whether more
 statements may be read.
 */
 formats.  A Parser evaluates into a boolean value indicating whether more
 statements may be read.
 */
-class Parser
+class Parser: private NonCopyable
 {
 private:
        Input in;
 {
 private:
        Input in;
index 491647e4b09a0b9c307d4f4aa32a6078403ed9a5..5c9deceb7d2c289b224c7b5a20ed8dc9cf69131d 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_DATAFILE_PARSERMODE_H_
 #define MSP_DATAFILE_PARSERMODE_H_
 
 #ifndef MSP_DATAFILE_PARSERMODE_H_
 #define MSP_DATAFILE_PARSERMODE_H_
 
+#include <msp/core/noncopyable.h>
 #include "statement.h"
 
 namespace Msp {
 #include "statement.h"
 
 namespace Msp {
@@ -13,7 +14,7 @@ class LoaderAction;
 /**
 Base class for parse modes.
 */
 /**
 Base class for parse modes.
 */
-class ParserMode
+class ParserMode: private NonCopyable
 {
 protected:
        Input &in;
 {
 protected:
        Input &in;
index 18fb3141b2c8c83edb526da13ef76c981b0c4c1e..c209947986a5d70a861a3859983aa597cee61bc3 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_DATAFILE_WRITER_H_
 
 #include <map>
 #define MSP_DATAFILE_WRITER_H_
 
 #include <map>
+#include <msp/core/noncopyable.h>
 #include <msp/io/base.h>
 #include "output.h"
 
 #include <msp/io/base.h>
 #include "output.h"
 
@@ -14,7 +15,7 @@ class WriterMode;
 /**
 Frontend for writing data.
 */
 /**
 Frontend for writing data.
 */
-class Writer
+class Writer: private NonCopyable
 {
 private:
        Output out;
 {
 private:
        Output out;
index 05058abe94138dad630dd46281fc721618ac2196..cc37710e9e5f7a26e08f5fd66b30708d2cda6a48 100644 (file)
@@ -1,13 +1,15 @@
 #ifndef MSP_DATAFILE_WRITERMODE_H_
 #define MSP_DATAFILE_WRITERMODE_H_
 
 #ifndef MSP_DATAFILE_WRITERMODE_H_
 #define MSP_DATAFILE_WRITERMODE_H_
 
+#include <msp/core/noncopyable.h>
+
 namespace Msp {
 namespace DataFile {
 
 class Output;
 class Statement;
 
 namespace Msp {
 namespace DataFile {
 
 class Output;
 class Statement;
 
-class WriterMode
+class WriterMode: private NonCopyable
 {
 protected:
        Output &out;
 {
 protected:
        Output &out;