From: Mikko Rasa Date: Wed, 16 Jan 2013 14:01:28 +0000 (+0200) Subject: Add an API to open files from a collection's sources X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=9b1656018f783eb4aad2fbdc1de1404691e89bb1;p=libs%2Fdatafile.git Add an API to open files from a collection's sources --- diff --git a/source/collection.cpp b/source/collection.cpp index 0709919..984fb74 100644 --- a/source/collection.cpp +++ b/source/collection.cpp @@ -91,6 +91,15 @@ void Collection::add_source(CollectionSource &s) sources.push_back(&s); } +IO::Seekable *Collection::open_from_sources(const string &name) +{ + for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) + if(IO::Seekable *io = (*i)->open(name)) + return io; + + throw IO::file_not_found(name); +} + void Collection::gather_names_from_sources(list &names, const CollectionItemTypeBase &type) const { for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) diff --git a/source/collection.h b/source/collection.h index ee7eb46..0d2dc6b 100644 --- a/source/collection.h +++ b/source/collection.h @@ -264,6 +264,8 @@ private: protected: void add_source(CollectionSource &); + IO::Seekable *open_from_sources(const std::string &); + private: void gather_names_from_sources(std::list &, const CollectionItemTypeBase &) const; diff --git a/source/collectionsource.h b/source/collectionsource.h index 61bb115..398f794 100644 --- a/source/collectionsource.h +++ b/source/collectionsource.h @@ -3,6 +3,7 @@ #include #include +#include namespace Msp { namespace DataFile { @@ -31,6 +32,10 @@ public: virtual NameList get_names(const CollectionItemTypeBase &type) const = 0; virtual void load(Collection &, const CollectionItemTypeBase &, const std::string &) const = 0; + + /** Opens a file from the source. The caller is responsible for deleting + the returned object when done with it. */ + virtual IO::Seekable *open(const std::string &) const = 0; }; } // namespace DataFile diff --git a/source/directorysource.cpp b/source/directorysource.cpp index 5d70bb5..4bf9f5c 100644 --- a/source/directorysource.cpp +++ b/source/directorysource.cpp @@ -40,6 +40,15 @@ void DirectorySource::load(Collection &coll, const CollectionItemTypeBase &type, } } +IO::Seekable *DirectorySource::open(const string &name) const +{ + FS::Path file; + if(lookup_file(name, file)) + return new IO::BufferedFile(file.str()); + + return 0; +} + bool DirectorySource::lookup_file(const string &name, FS::Path &result) const { ObjectMap::const_iterator i = objects.find(name); diff --git a/source/directorysource.h b/source/directorysource.h index dfce833..b1324a7 100644 --- a/source/directorysource.h +++ b/source/directorysource.h @@ -23,6 +23,7 @@ public: 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; + virtual IO::Seekable *open(const std::string &) const; bool lookup_file(const std::string &, FS::Path &) const; }; diff --git a/source/packsource.cpp b/source/packsource.cpp index d22c7dc..c896866 100644 --- a/source/packsource.cpp +++ b/source/packsource.cpp @@ -38,6 +38,7 @@ void PackSource::add_pack_file(const string &fn, const string &filter) FileMap pack_files; pack->collect_files(pack_files, filter); + files.insert(pack_files.begin(), pack_files.end()); for(FileMap::const_iterator i=pack_files.begin(); i!=pack_files.end(); ++i) i->second->collect_objects(objects); } @@ -96,6 +97,15 @@ void PackSource::load(Collection &coll, const CollectionItemTypeBase &type, cons type.load_item(coll, parser, name); } +IO::Seekable *PackSource::open(const string &fn) const +{ + FileMap::const_iterator i = files.find(fn); + if(i!=files.end()) + return i->second->open().release(); + + return 0; +} + PackSource::Pack::Pack(const string &fn): filename(fn), @@ -128,7 +138,7 @@ PackSource::File::File(const Pack &p, const string &fn): loaded(false) { } -RefPtr PackSource::File::open() const +RefPtr PackSource::File::open() const { IO::BufferedFile *io_file = new IO::BufferedFile(pack.get_filename()); IO::Slice *io_slice = new IO::Slice(*io_file, pack.get_base_offset()+offset, length); diff --git a/source/packsource.h b/source/packsource.h index f552d2a..10e1433 100644 --- a/source/packsource.h +++ b/source/packsource.h @@ -77,7 +77,7 @@ private: public: File(const Pack &, const std::string &); - RefPtr open() const; + RefPtr open() const; const std::string &get_filename() const { return filename; } std::string get_full_name() const; bool is_collection() const { return collection; } @@ -104,6 +104,7 @@ private: }; std::list packs; + FileMap files; ObjectMap objects; public: @@ -117,6 +118,7 @@ public: 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; + virtual IO::Seekable *open(const std::string &) const; }; } // namespace DataFile