]> git.tdb.fi Git - libs/datafile.git/blob - source/packsource.h
Redesign automatic object loading
[libs/datafile.git] / source / packsource.h
1 #ifndef MSP_DATAFILE_PACKSOURCE_H_
2 #define MSP_DATAFILE_PACKSOURCE_H_
3
4 #include <msp/core/refptr.h>
5 #include "collectionsource.h"
6 #include "objectloader.h"
7
8 namespace Msp {
9 namespace DataFile {
10
11 /**
12 A source that loads data from pack files.  As opposed to plain collection
13 files, pack files are composed from a number of logical files.  They also
14 contain an index of objects contained in the pack and which logical files they
15 are in.  This allows the pack to be loaded in a piecewise manner instead of all
16 at once.
17
18 It's possible for a pack file to contain plain collection files as well.  When
19 an object from such a file is requested, the entire sub-collection it is stored
20 in is loaded.
21 */
22 class PackSource: public CollectionSource
23 {
24 private:
25         class File;
26         struct Object;
27
28         typedef std::map<std::string, const Object *> ObjectMap;
29
30         class Pack
31         {
32         public:
33                 class Loader: public ObjectLoader<Pack>
34                 {
35                 public:
36                         Loader(Pack &);
37                 private:
38                         void file(const std::string &);
39                 };
40
41         private:
42                 std::string filename;
43                 unsigned base_offset;
44                 std::list<File> files;
45
46         public:
47                 Pack(const std::string &);
48
49                 const std::string &get_filename() const { return filename; }
50                 unsigned get_base_offset() const { return base_offset; }
51
52                 void collect_objects(ObjectMap &) const;
53         };
54
55         class File
56         {
57         public:
58                 class Loader: public ObjectLoader<File>
59                 {
60                 public:
61                         Loader(File &);
62                 private:
63                         virtual void finish();
64                         void object(const std::string &, const std::string &);
65                 };
66
67         private:
68                 const Pack &pack;
69                 std::string filename;
70                 unsigned offset;
71                 unsigned length;
72                 bool collection;
73                 std::list<Object> objects;
74                 bool loaded;
75
76         public:
77                 File(const Pack &, const std::string &);
78
79                 RefPtr<IO::Base> open() const;
80                 const std::string &get_filename() const { return filename; }
81                 std::string get_full_name() const;
82                 bool is_collection() const { return collection; }
83
84                 void set_loaded();
85                 bool is_loaded() const { return loaded; }
86
87                 void collect_objects(ObjectMap &) const;
88         };
89
90         class Object
91         {
92         private:
93                 File &file;
94                 std::string name;
95                 std::string keyword;
96
97         public:
98                 Object(File &, const std::string &, const std::string &);
99
100                 File &get_file() const { return file; }
101                 const std::string &get_name() const { return name; }
102                 const std::string &get_keyword() const { return keyword; }
103         };
104
105         std::list<Pack> packs;
106         ObjectMap objects;
107
108 public:
109         /// Adds a pack file to load objects from.  The index is read immediately.
110         void add_pack_file(const std::string &);
111
112
113         virtual bool is_loadable(const CollectionItemTypeBase &, const std::string &) const;
114         virtual NameList get_names(const CollectionItemTypeBase &) const;
115         virtual void load(Collection &, const CollectionItemTypeBase &, const std::string &) const;
116 };
117
118 } // namespace DataFile
119 } // namespace Msp
120
121 #endif