]> git.tdb.fi Git - libs/datafile.git/blobdiff - source/packsource.h
Redesign automatic object loading
[libs/datafile.git] / source / packsource.h
diff --git a/source/packsource.h b/source/packsource.h
new file mode 100644 (file)
index 0000000..e2c84a0
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef MSP_DATAFILE_PACKSOURCE_H_
+#define MSP_DATAFILE_PACKSOURCE_H_
+
+#include <msp/core/refptr.h>
+#include "collectionsource.h"
+#include "objectloader.h"
+
+namespace Msp {
+namespace DataFile {
+
+/**
+A source that loads data from pack files.  As opposed to plain collection
+files, pack files are composed from a number of logical files.  They also
+contain an index of objects contained in the pack and which logical files they
+are in.  This allows the pack to be loaded in a piecewise manner instead of all
+at once.
+
+It's possible for a pack file to contain plain collection files as well.  When
+an object from such a file is requested, the entire sub-collection it is stored
+in is loaded.
+*/
+class PackSource: public CollectionSource
+{
+private:
+       class File;
+       struct Object;
+
+       typedef std::map<std::string, const Object *> ObjectMap;
+
+       class Pack
+       {
+       public:
+               class Loader: public ObjectLoader<Pack>
+               {
+               public:
+                       Loader(Pack &);
+               private:
+                       void file(const std::string &);
+               };
+
+       private:
+               std::string filename;
+               unsigned base_offset;
+               std::list<File> files;
+
+       public:
+               Pack(const std::string &);
+
+               const std::string &get_filename() const { return filename; }
+               unsigned get_base_offset() const { return base_offset; }
+
+               void collect_objects(ObjectMap &) const;
+       };
+
+       class File
+       {
+       public:
+               class Loader: public ObjectLoader<File>
+               {
+               public:
+                       Loader(File &);
+               private:
+                       virtual void finish();
+                       void object(const std::string &, const std::string &);
+               };
+
+       private:
+               const Pack &pack;
+               std::string filename;
+               unsigned offset;
+               unsigned length;
+               bool collection;
+               std::list<Object> objects;
+               bool loaded;
+
+       public:
+               File(const Pack &, const std::string &);
+
+               RefPtr<IO::Base> open() const;
+               const std::string &get_filename() const { return filename; }
+               std::string get_full_name() const;
+               bool is_collection() const { return collection; }
+
+               void set_loaded();
+               bool is_loaded() const { return loaded; }
+
+               void collect_objects(ObjectMap &) const;
+       };
+
+       class Object
+       {
+       private:
+               File &file;
+               std::string name;
+               std::string keyword;
+
+       public:
+               Object(File &, const std::string &, const std::string &);
+
+               File &get_file() const { return file; }
+               const std::string &get_name() const { return name; }
+               const std::string &get_keyword() const { return keyword; }
+       };
+
+       std::list<Pack> packs;
+       ObjectMap objects;
+
+public:
+       /// Adds a pack file to load objects from.  The index is read immediately.
+       void add_pack_file(const std::string &);
+
+
+       virtual bool is_loadable(const CollectionItemTypeBase &, const std::string &) const;
+       virtual NameList get_names(const CollectionItemTypeBase &) const;
+       virtual void load(Collection &, const CollectionItemTypeBase &, const std::string &) const;
+};
+
+} // namespace DataFile
+} // namespace Msp
+
+#endif