From f6069914af0d47bfea343b0babb734c9fd6d432d Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Mon, 16 Feb 2015 18:56:48 +0100 Subject: Added "autocomplete" function to ResourceLocator and Registry --- src/core/Registry.cpp | 25 +++++++++++++++ src/core/Registry.hpp | 18 +++++++++++ src/core/resource/ResourceLocator.cpp | 39 +++++++++++++++++++++++ src/core/resource/ResourceLocator.hpp | 58 +++++++++++++++++++++++++++++++++-- 4 files changed, 137 insertions(+), 3 deletions(-) diff --git a/src/core/Registry.cpp b/src/core/Registry.cpp index 2bb6a98..e950cdc 100644 --- a/src/core/Registry.cpp +++ b/src/core/Registry.cpp @@ -131,5 +131,30 @@ bool Registry::locateResource(Resource &resource, const std::string &path, return false; } + +std::vector Registry::autocompleteResource( + const std::string &path, ResourceType type, + const Resource &relativeTo) const +{ + std::vector res; + + // Try the locator of the given "relativeTo" resource first + if (relativeTo.isValid()) { + res = relativeTo.getLocator().autocomplete(path, type, relativeTo); + if (!res.empty()) { + return res; + } + } + + // Iterate over all registered locators and try to autocomplete the given + // path + for (auto &locator : locators) { + res = locator->autocomplete(path, type, relativeTo); + if (!res.empty()) { + return res; + } + } + return res; +} } diff --git a/src/core/Registry.hpp b/src/core/Registry.hpp index 4b4cb65..b4ce1a9 100644 --- a/src/core/Registry.hpp +++ b/src/core/Registry.hpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -153,6 +154,23 @@ public: bool locateResource(Resource &resource, const std::string &path, ResourceType type = ResourceType::UNKNOWN, const Resource &relativeTo = NullResource) const; + + /** + * Performs autocompletion of resources with missing file extension and + * returns a list of possible files existing within the filesystem. + * + * @param path is the path for which the autocompletion shuold be performed. + * @param type is the ResourceType which is used to select the search paths. + * @param relativeTo is another resource relatie to which the resource may + * be looked up. + * @return a list of possible files to which the given path may be extended. + * If the file pointed to by "path" exists, it will be the only result in + * the list. Otherwise files which have the given path as a prefix but a + * different file extension are returned. + */ + std::vector autocompleteResource( + const std::string &path, ResourceType type = ResourceType::UNKNOWN, + const Resource &relativeTo = NullResource) const; }; } diff --git a/src/core/resource/ResourceLocator.cpp b/src/core/resource/ResourceLocator.cpp index b19542e..da38cbd 100644 --- a/src/core/resource/ResourceLocator.cpp +++ b/src/core/resource/ResourceLocator.cpp @@ -25,6 +25,37 @@ namespace ousia { /* Class ResourceLocator */ +std::vector ResourceLocator::autocomplete( + const std::string &path, const ResourceType type, + const Resource &relativeTo) const +{ + // If the locator of the given relative resource is this locator instance, + // use the location specified in the resource, otherwise just use no + // "relativeTo" path. + if (&relativeTo.getLocator() == this) { + return autocomplete(path, type, relativeTo.getLocation()); + } + return autocomplete(path, type, ""); +} + +std::vector ResourceLocator::autocomplete( + const std::string &path, const ResourceType type, + const std::string &relativeTo) const +{ + // Try to locate the resource for the specified type, if not found, use + // the "UNKNOWN" type. + std::vector res = doAutocomplete(path, type, relativeTo); + if (!res.empty()) { + return res; + } + + // Use the "UNKNOWN" type + if (type != ResourceType::UNKNOWN) { + return doAutocomplete(path, ResourceType::UNKNOWN, relativeTo); + } + return std::vector{}; +} + bool ResourceLocator::locate(Resource &resource, const std::string &path, const ResourceType type, const Resource &relativeTo) const @@ -59,6 +90,14 @@ std::unique_ptr ResourceLocator::stream( return doStream(location); } +std::vector ResourceLocator::doAutocomplete( + const std::string &path, const ResourceType type, + const std::string &relativeTo) const +{ + // Default implementation + return std::vector{}; +} + /* Class StaticResourceLocator */ bool StaticResourceLocator::doLocate(Resource &resource, diff --git a/src/core/resource/ResourceLocator.hpp b/src/core/resource/ResourceLocator.hpp index c1d0807..d6a2ffc 100644 --- a/src/core/resource/ResourceLocator.hpp +++ b/src/core/resource/ResourceLocator.hpp @@ -21,6 +21,7 @@ #include #include +#include #include "Resource.hpp" @@ -59,6 +60,23 @@ protected: const ResourceType type, const std::string &relativeTo) const = 0; + /** + * Tries to autocomplete the given filename by searching for files with this + * basename but different extensions. Returns a list of possible extended + * paths. May return an empty list if this function is not supported. + * + * @param path is the given filename for which versions with extension + * should be searched. + * @param type is the resource type, determining the search paths in which + * the resource is looked up. + * @param relativeTo is an already resolved Resource relative to which the + * file should be searched. + * @return a list of matching, autocompleted file paths. + */ + virtual std::vector doAutocomplete( + const std::string &path, const ResourceType type, + const std::string &relativeTo) const; + /** * This method returns a stream containing the data of the resource at the * given location. @@ -79,6 +97,41 @@ public: */ virtual ~ResourceLocator() {} + /** + * Tries to autocomplete the given filename by searching for files with this + * basename but different extensions. Returns a list of possible extended + * paths. May return an empty list if this function is not supported. + * + * @param path is the given filename for which versions with extension + * should be searched. + * @param type is the resource type, determining the search paths in which + * the resource is looked up. + * @param relativeTo is an already resolved Resource relative to which the + * file should be searched. + * @return a list of matching, autocompleted file paths. + */ + std::vector autocomplete( + const std::string &path, + const ResourceType type = ResourceType::UNKNOWN, + const Resource &relativeTo = NullResource) const; + + /** + * Tries to autocomplete the given filename by searching for files with this + * basename but different extensions. Returns a list of possible extended + * paths. May return an empty list if this function is not supported. + * + * @param path is the given filename for which versions with extension + * should be searched. + * @param type is the resource type, determining the search paths in which + * the resource is looked up. + * @param relativeTo is the location of an already resolved resource + * relative to which this resource should be located. + * @return a list of matching, autocompleted file paths. + */ + std::vector autocomplete(const std::string &path, + const ResourceType type, + const std::string &relativeTo) const; + /** * The locate function uses this ResourceLocator to search for a given * Resource name (path parameter). @@ -109,8 +162,7 @@ public: * @return true if a resource could be found, false otherwise. */ bool locate(Resource &resource, const std::string &path, - const ResourceType type, - const std::string &relativeTo) const; + const ResourceType type, const std::string &relativeTo) const; /** * This method returns a stream containing the data of the resource at the @@ -123,7 +175,7 @@ public: * C++11 compiler does not yet support move semantics for * streams. */ - std::unique_ptr stream(const std::string &location) const; + std::unique_ptr stream(const std::string &location) const; }; /** -- cgit v1.2.3