--- /dev/null
+#include <msp/strings/format.h>
+#include "packcollection.h"
+
+using namespace std;
+
+namespace Msp {
+namespace DataFile {
+
+void PackCollection::add_pack_file(const string &fn)
+{
+ packs.push_back(Pack(fn));
+ Pack &pack = packs.back();
+ load(pack, fn);
+
+ ObjectMap pack_objs;
+ pack.collect_objects(pack_objs);
+ for(ObjectMap::const_iterator i=pack_objs.begin(); i!=pack_objs.end(); ++i)
+ {
+ if(i->second->get_keyword().empty())
+ add_future(i->first);
+ else
+ add_future_with_keyword(i->first, i->second->get_keyword());
+ }
+
+ objects.insert(pack_objs.begin(), pack_objs.end());
+}
+
+
+PackCollection::Pack::Pack(const string &fn):
+ filename(fn),
+ base_offset(0)
+{ }
+
+void PackCollection::Pack::collect_objects(ObjectMap &objs) const
+{
+ for(list<File>::const_iterator i=files.begin(); i!=files.end(); ++i)
+ i->collect_objects(objs);
+}
+
+
+PackCollection::File::File(const Pack &p, const string &fn):
+ pack(p),
+ filename(fn),
+ offset(0),
+ length(0),
+ collection(false),
+ loaded(false)
+{ }
+
+RefPtr<IO::Base> PackCollection::File::open() const
+{
+ RefPtr<IO::BufferedFile> io_file = new IO::BufferedFile(pack.get_filename());
+ io_file->seek(pack.get_base_offset()+offset, IO::S_BEG);
+ return io_file;
+}
+
+string PackCollection::File::get_full_name() const
+{
+ return format("%s/%s", pack.get_filename(), filename);
+}
+
+void PackCollection::File::set_loaded()
+{
+ loaded = true;
+}
+
+void PackCollection::File::collect_objects(ObjectMap &objs) const
+{
+ for(list<Object>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+ objs[i->get_name()] = &*i;
+}
+
+
+PackCollection::Object::Object(File &f, const string &n, const string &k):
+ file(f),
+ name(n),
+ keyword(k)
+{ }
+
+
+PackCollection::Pack::Loader::Loader(Pack &p):
+ ObjectLoader<Pack>(p)
+{
+ add("file", &Loader::file);
+ add("base_offset", &Pack::base_offset);
+}
+
+void PackCollection::Pack::Loader::file(const string &fn)
+{
+ obj.files.push_back(File(obj, fn));
+ load_sub(obj.files.back());
+}
+
+
+PackCollection::File::Loader::Loader(File &f):
+ ObjectLoader<File>(f)
+{
+ add("object", &Loader::object);
+ add("slice", &File::offset, &File::length);
+}
+
+void PackCollection::File::Loader::finish()
+{
+ if(!obj.collection)
+ {
+ PackCollection::Object ob(obj, obj.filename, string());
+ obj.objects.push_back(ob);
+ }
+}
+
+void PackCollection::File::Loader::object(const string &name, const string &kwd)
+{
+ obj.objects.push_back(PackCollection::Object(obj, name, kwd));
+ obj.collection = true;
+}
+
+} // namespace DataFile
+} // namespace Msp