]> git.tdb.fi Git - libs/datafile.git/commitdiff
Give DirectoryCollection the ability to add files as future objects
authorMikko Rasa <tdb@tdb.fi>
Wed, 26 Sep 2012 19:18:24 +0000 (22:18 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Sep 2012 19:18:24 +0000 (22:18 +0300)
source/collection.cpp
source/collection.h
source/directorycollection.cpp
source/directorycollection.h

index d52ee22399ba7500c880798f2fcf3036d9cd095c..a16ae5a9dc2e7a9f70f638093348b59c8bd561eb 100644 (file)
@@ -1,5 +1,7 @@
 #include "collection.h"
 
+using namespace std;
+
 namespace Msp {
 namespace DataFile {
 
@@ -9,6 +11,22 @@ Collection::~Collection()
                delete *i;
 }
 
+void Collection::add_future(const std::string &name)
+{
+       if(items.count(name))
+               throw key_error(typeid(ItemMap));
+
+       for(TypeList::const_iterator i=types.begin(); i!=types.end(); ++i)
+               if((*i)->match_name(name))
+               {
+                       items.insert(ItemMap::value_type(name, (*i)->create_future()));
+                       return;
+               }
+
+       /* XXX throw something?  If we do, DirectoryCollection needs some way to
+       check if a name matches any item type. */
+}
+
 
 Collection::Loader::Loader(Collection &c):
        coll(c)
@@ -27,5 +45,25 @@ CollectionItemTypeBase::~CollectionItemTypeBase()
        delete tag;
 }
 
+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<string>::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
index 0595aaca7caddb801d094d9ed847362c669c8be7..66c50fe69d2c86e85ce38ac1e2b4bb73fd8672b3 100644 (file)
@@ -137,6 +137,8 @@ protected:
                insert_unique(items, name, ptr);
        }
 
+       void add_future(const std::string &name);
+
 public:
        /// Gets a typed object from the collection.
        template<typename T>
@@ -302,15 +304,20 @@ protected:
        { };
 
        std::string kwd;
+       std::vector<std::string> suffixes;
        TagBase *tag;
 
        CollectionItemTypeBase();
 public:
        virtual ~CollectionItemTypeBase();
 
+       void set_keyword(const std::string &);
+       void add_suffix(const std::string &);
        virtual void add_to_loader(Collection::Loader &) const = 0;
        virtual bool can_create() const = 0;
        virtual void create_item(Collection &, const std::string &) const = 0;
+       bool match_name(const std::string &) const;
+       virtual Variant create_future() const = 0;
 
        template<typename T>
        bool check_type() const
@@ -360,6 +367,7 @@ private:
                virtual ~StoreBase() { }
 
                virtual void store(Collection &, const std::string &, T *) = 0;
+               virtual Variant create_future() const = 0;
 
                virtual void add_to_loader(Collection::Loader &, const std::string &) = 0;
        };
@@ -371,6 +379,9 @@ private:
                virtual void store(Collection &coll, const std::string &name, T *obj)
                { coll.add(name, static_cast<S *>(obj)); }
 
+               virtual Variant create_future() const
+               { return RefPtr<S>(0); }
+
                virtual void add_to_loader(Collection::Loader &loader, const std::string &kwd)
                { Collection::Loader::Add<T, S>::add(loader, kwd); }
        };
@@ -394,7 +405,17 @@ public:
        item's name. */
        CollectionItemType &keyword(const std::string &k)
        {
-               kwd = k;
+               set_keyword(k);
+               return *this;
+       }
+
+       /** Adds a suffix that is used to match names when looking for future
+       objects.  There is no implied separator; a name matches if it ends with the
+       suffix.  If a keyword is defined before any suffixes, then "."+keyword is
+       added as a suffix. */
+       CollectionItemType &suffix(const std::string &s)
+       {
+               add_suffix(s);
                return *this;
        }
 
@@ -438,6 +459,9 @@ public:
                if(obj)
                        store->store(coll, name, obj);
        }
+
+       virtual Variant create_future() const
+       { return store->create_future(); }
 };
 
 
index 25808d6c760dd1c807e3a98372f3c9477a7fa013..4413ca5a66b79cf408661b2fe1f9fed25d430bd6 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/fs/dir.h>
 #include <msp/fs/stat.h>
 #include "directorycollection.h"
 
@@ -22,6 +23,16 @@ void DirectoryCollection::add_directory(const FS::Path &d)
        dirs.push_back(d);
 }
 
+void DirectoryCollection::load_names()
+{
+       for(list<FS::Path>::const_iterator i=dirs.begin(); i!=dirs.end(); ++i)
+       {
+               list<string> names = FS::list_files(*i);
+               for(list<string>::const_iterator j=names.begin(); j!=names.end(); ++j)
+                       add_future(*j);
+       }
+}
+
 bool DirectoryCollection::lookup_file(const string &name, FS::Path &result) const
 {
        for(list<FS::Path>::const_iterator i=dirs.begin(); i!=dirs.end(); ++i)
index e9a946332c767d0831afced78f4f981c593037cc..cbaffd65532d048735edabaef6610533ced96c01 100644 (file)
@@ -25,6 +25,10 @@ protected:
        void set_directory(const FS::Path &);
        void add_directory(const FS::Path &);
 
+       /** Examines the names of files in the designated directories and adds any
+       applicable ones as future objects. */
+       void load_names();
+
        template<typename T>
        CollectionItemType<T> &add_type()
        {