]> git.tdb.fi Git - libs/datafile.git/blob - source/packcollection.cpp
Add an intelligent packed collection class
[libs/datafile.git] / source / packcollection.cpp
1 #include <msp/strings/format.h>
2 #include "packcollection.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace DataFile {
8
9 void PackCollection::add_pack_file(const string &fn)
10 {
11         packs.push_back(Pack(fn));
12         Pack &pack = packs.back();
13         load(pack, fn);
14
15         ObjectMap pack_objs;
16         pack.collect_objects(pack_objs);
17         for(ObjectMap::const_iterator i=pack_objs.begin(); i!=pack_objs.end(); ++i)
18         {
19                 if(i->second->get_keyword().empty())
20                         add_future(i->first);
21                 else
22                         add_future_with_keyword(i->first, i->second->get_keyword());
23         }
24
25         objects.insert(pack_objs.begin(), pack_objs.end());
26 }
27
28
29 PackCollection::Pack::Pack(const string &fn):
30         filename(fn),
31         base_offset(0)
32 { }
33
34 void PackCollection::Pack::collect_objects(ObjectMap &objs) const
35 {
36         for(list<File>::const_iterator i=files.begin(); i!=files.end(); ++i)
37                 i->collect_objects(objs);
38 }
39
40
41 PackCollection::File::File(const Pack &p, const string &fn):
42         pack(p),
43         filename(fn),
44         offset(0),
45         length(0),
46         collection(false),
47         loaded(false)
48 { }
49
50 RefPtr<IO::Base> PackCollection::File::open() const
51 {
52         RefPtr<IO::BufferedFile> io_file = new IO::BufferedFile(pack.get_filename());
53         io_file->seek(pack.get_base_offset()+offset, IO::S_BEG);
54         return io_file;
55 }
56
57 string PackCollection::File::get_full_name() const
58 {
59         return format("%s/%s", pack.get_filename(), filename);
60 }
61
62 void PackCollection::File::set_loaded()
63 {
64         loaded = true;
65 }
66
67 void PackCollection::File::collect_objects(ObjectMap &objs) const
68 {
69         for(list<Object>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
70                 objs[i->get_name()] = &*i;
71 }
72
73
74 PackCollection::Object::Object(File &f, const string &n, const string &k):
75         file(f),
76         name(n),
77         keyword(k)
78 { }
79
80
81 PackCollection::Pack::Loader::Loader(Pack &p):
82         ObjectLoader<Pack>(p)
83 {
84         add("file",        &Loader::file);
85         add("base_offset", &Pack::base_offset);
86 }
87
88 void PackCollection::Pack::Loader::file(const string &fn)
89 {
90         obj.files.push_back(File(obj, fn));
91         load_sub(obj.files.back());
92 }
93
94
95 PackCollection::File::Loader::Loader(File &f):
96         ObjectLoader<File>(f)
97 {
98         add("object", &Loader::object);
99         add("slice",  &File::offset, &File::length);
100 }
101
102 void PackCollection::File::Loader::finish()
103 {
104         if(!obj.collection)
105         {
106                 PackCollection::Object ob(obj, obj.filename, string());
107                 obj.objects.push_back(ob);
108         }
109 }
110
111 void PackCollection::File::Loader::object(const string &name, const string &kwd)
112 {
113         obj.objects.push_back(PackCollection::Object(obj, name, kwd));
114         obj.collection = true;
115 }
116
117 } // namespace DataFile
118 } // namespace Msp