X-Git-Url: http://git.tdb.fi/?p=libs%2Fdatafile.git;a=blobdiff_plain;f=source%2Fcollection.cpp;h=984fb74da8e7a6007645e6f85aa002b8ae6f894a;hp=ea1095b39a93f61e0a14930b8e8edf039da9089e;hb=9b1656018f783eb4aad2fbdc1de1404691e89bb1;hpb=1d9c21a8a301007fb242e05b69cc6390ec566273 diff --git a/source/collection.cpp b/source/collection.cpp index ea1095b..984fb74 100644 --- a/source/collection.cpp +++ b/source/collection.cpp @@ -1,37 +1,166 @@ -/* $Id$ - -This file is part of libmspdatafile -Copyright © 2006 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - #include "collection.h" +using namespace std; + namespace Msp { namespace DataFile { +Collection::Collection(): + fallback(0) +{ } + Collection::~Collection() { - for(ItemMap::iterator i=items.begin(); i!=items.end(); ++i) - delete i->second; - for(ItemKeywordSeq::iterator i=keywords.begin(); i!=keywords.end(); ++i) - delete *i; - for(ItemCreatorSeq::iterator i=creators.begin(); i!=creators.end(); ++i) + for(TypeList::iterator i = types.begin(); i!=types.end(); ++i) delete *i; } -bool Collection::contains(const std::string &n) const +const Variant &Collection::get_var(const string &name, const CollectionItemTypeBase *type) +{ + ItemMap::iterator i = items.find(name); + if(i!=items.end()) + return i->second; + + if(type) + { + bool loaded = false; + if(type->can_create()) + { + type->create_item(*this, name); + loaded = items.count(name); + } + for(SourceList::iterator j=sources.begin(); (!loaded && j!=sources.end()); ++j) + { + (*j)->load(*this, *type, name); + loaded = items.count(name); + } + if(!loaded && fallback) + { + for(TypeList::const_iterator j=fallback->types.begin(); j!=fallback->types.end(); ++j) + if((*j)->is_same_type(*type)) + { + if(fallback->get_status(name, **j)) + return fallback->get_var(name, *j); + break; + } + } + } + + return get_item(items, name); +} + +void Collection::gather_items(list *vars, list *names, const CollectionItemTypeBase &type, bool include_sources) const +{ + for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i) + if(type.check_item_type(i->second)) + { + if(vars) + vars->push_back(&i->second); + if(names) + names->push_back(i->first); + } + + if(include_sources && names) + gather_names_from_sources(*names, type); +} + +unsigned Collection::get_status(const string &name, const CollectionItemTypeBase &type) const +{ + ItemMap::const_iterator i = items.find(name); + if(i==items.end()) + { + for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j) + if((*j)->is_loadable(type, name)) + return 2; + return 0; + } + + return type.check_item_type(i->second); +} + +CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const +{ + for(TypeList::const_iterator i=types.begin(); i!=types.end(); ++i) + if((*i)->check_item_type(var)) + return *i; + return 0; +} + +void Collection::add_source(CollectionSource &s) +{ + sources.push_back(&s); +} + +IO::Seekable *Collection::open_from_sources(const string &name) { - return items.count(n); + 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) + { + std::list available_names = (*i)->get_names(type); + for(std::list::iterator j=available_names.begin(); j!=available_names.end(); ++j) + if(!items.count(*j)) + names.push_back(*j); + } +} + +void Collection::load_items_from_sources(const CollectionItemTypeBase &type) +{ + for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) + { + std::list available_names = (*i)->get_names(type); + for(std::list::iterator j=available_names.begin(); j!=available_names.end(); ++j) + if(!items.count(*j)) + (*i)->load(*this, type, *j); + } +} + +void Collection::set_fallback(Collection *f) +{ + fallback = f; } Collection::Loader::Loader(Collection &c): coll(c) { - for(ItemKeywordSeq::const_iterator i=coll.keywords.begin(); i!=coll.keywords.end(); ++i) + for(TypeList::const_iterator i = coll.types.begin(); i!=coll.types.end(); ++i) (*i)->add_to_loader(*this); } + +CollectionItemTypeBase::~CollectionItemTypeBase() +{ + for(vector::iterator i=extractors.begin(); i!=extractors.end(); ++i) + delete *i; +} + +void CollectionItemTypeBase::set_keyword(const string &k) +{ + kwd = k; + if(suffixes.empty()) + add_suffix("."+kwd); +} + +void CollectionItemTypeBase::add_suffix(const string &s) +{ + suffixes.push_back(s); +} + +bool CollectionItemTypeBase::match_name(const string &name) const +{ + for(vector::const_iterator i=suffixes.begin(); i!=suffixes.end(); ++i) + if(name.size()>i->size() && !name.compare(name.size()-i->size(), string::npos, *i)) + return true; + return false; +} + } // namespace DataFile } // namespace Msp