diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-20 00:53:49 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-20 00:53:49 +0100 |
commit | 47311cc8b211a7fef033d744d9eba9f308726ea8 (patch) | |
tree | 348726aef17297729233b93b6d7eef86f25c7a78 /src/core/resource | |
parent | d836d70ea2352dcf277c6fce91ba1ded3f074b44 (diff) |
Refactored stuff surrounding the ResourceLocator class, implemented StaticResourceLocator which can be used for registering static resources (mainly for testing or if certain resources need to be available from the executable)
Diffstat (limited to 'src/core/resource')
-rw-r--r-- | src/core/resource/Resource.cpp | 46 | ||||
-rw-r--r-- | src/core/resource/Resource.hpp | 144 | ||||
-rw-r--r-- | src/core/resource/ResourceLocator.cpp | 103 | ||||
-rw-r--r-- | src/core/resource/ResourceLocator.hpp | 194 |
4 files changed, 422 insertions, 65 deletions
diff --git a/src/core/resource/Resource.cpp b/src/core/resource/Resource.cpp index e69de29..349c82a 100644 --- a/src/core/resource/Resource.cpp +++ b/src/core/resource/Resource.cpp @@ -0,0 +1,46 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "Resource.hpp" +#include "ResourceLocator.hpp" + +namespace ousia { + +/* Class Resource */ + +Resource::Resource() + : Resource(false, NullResourceLocator, ResourceType::UNKNOWN, "") +{ +} + +Resource::Resource(bool valid, const ResourceLocator &locator, + ResourceType type, const std::string &location) + : valid(valid), locator(&locator), type(type), location(location) +{ +} + +std::unique_ptr<std::istream> Resource::stream() const +{ + return locator->stream(location); +} + +/* NullResource instance */ + +const Resource NullResource{}; +} + diff --git a/src/core/resource/Resource.hpp b/src/core/resource/Resource.hpp index 9df851d..1934029 100644 --- a/src/core/resource/Resource.hpp +++ b/src/core/resource/Resource.hpp @@ -22,15 +22,159 @@ * Contains the Resource class, representing an external resource as well as * further types used for describing resources. * + * @author Benjamin Paaßen (bpassen@techfak.uni-bielefeld.de) */ #ifndef _OUSIA_RESOURCE_HPP_ #define _OUSIA_RESOURCE_HPP_ +#include <map> +#include <memory> +#include <string> + namespace ousia { +// Forward declaration +class ResourceLocator; + +/** + * This enum contains all possible types of includable resources in Ousía. + */ +enum class ResourceType { + /** + * Unknown type. + */ + UNKNOWN, + + /** + * The resource contains a domain description. + */ + DOMAIN_DESC, + + /** + * The resource contains a typesystem description. + */ + TYPESYSTEM, + + /** + * The resource contains a simple document. + */ + DOCUMENT, + /** + * The resource contains style attributes. + */ + ATTRIBUTES, + + /** + * The resource is a stylesheet. + */ + STYLESHEET, + + /** + * The resource contains script (note that the actual scripting language is + * not specified by the resource type). + */ + SCRIPT, + + /** + * Generic data, such as e.g. images. + */ + DATA +}; + +/** + * A Location contains the location of a Resource, e.g. a file path + * on a hard drive. Note that the 'found' flag might be set to false + * indicating that a resource was not found. + */ +class Resource { +private: + /** + * Specifies whether the resource points at a valid location or not. + */ + bool valid; + /** + * Reference pointing at the location + */ + ResourceLocator const *locator; + + /** + * Requested type of the resource. + */ + ResourceType type; + + /** + * This is a fully qualified/canonical path to the resource found or + * in an undefined state (possibly empty) if the 'valid' flag is set + * to 'false'. + */ + std::string location; + +public: + /** + * Default constructor of the Resource class, represents an invalid + * resource. + */ + Resource(); + + /** + * Constructor of the Resource class. + * + * @param valid specifies whether the Resource is valid or not. + * @param locator specifies the resource locator that was used to locate the + * resource. + */ + Resource(bool valid, const ResourceLocator &locator, + ResourceType type, const std::string &location); + + /** + * This calls the 'stream' method of the underlying ResourceLocator that + * found this location and returns a stream containing the data of the + * Resource at this location. + * + * @return a stream containing the data of the Resource at this + * location. This has to be a unique_pointer because the current + * C++11 compiler does not yet support move semantics for + * streams. + */ + std::unique_ptr<std::istream> stream() const; + + /** + * Returns whether this resource is valid or not. + * + * @return true if the resource is valid, false otherwise. + */ + bool isValid() const { return valid; } + + /** + * Returns a reference pointing at the locator that was used to locate this + * resource. + * + * @return the locator used for locating this resource. + */ + const ResourceLocator &getLocator() const { return *locator; } + + /** + * Returns the type of the resource that was requested when the resource was + * located. + * + * @return the type of the resource. + */ + ResourceType getType() const { return type; } + + /** + * Returns a canonical location that can be used in a hash map to identify + * a resource. + */ + const std::string &getLocation() const { return location; } +}; + +/** + * Invalid resource instance. + */ +extern const Resource NullResource; } #endif /* _OUSIA_RESOURCE_HPP_ */ diff --git a/src/core/resource/ResourceLocator.cpp b/src/core/resource/ResourceLocator.cpp index e69de29..1b8490d 100644 --- a/src/core/resource/ResourceLocator.cpp +++ b/src/core/resource/ResourceLocator.cpp @@ -0,0 +1,103 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <sstream> + +#include "Resource.hpp" +#include "ResourceLocator.hpp" + +namespace ousia { + +/* Class ResourceLocator */ + +bool ResourceLocator::locate(Resource &resource, const std::string &path, + const ResourceType type, + const Resource &relativeTo) const +{ + if (&relativeTo.getLocator() == this) { + return doLocate(resource, path, type, relativeTo.getLocation()); + } + return doLocate(resource, path, type, ""); +} + +bool ResourceLocator::locate(Resource &resource, const std::string &path, + const ResourceType type, + const std::string &relativeTo) const +{ + return doLocate(resource, path, type, relativeTo); +} + +std::unique_ptr<std::istream> ResourceLocator::stream( + const std::string &location) const +{ + return doStream(location); +} + +/* Class StaticResourceLocator */ + +bool StaticResourceLocator::doLocate( + Resource &resource, const std::string &path, const ResourceType type, + const std::string &relativeTo) const +{ + auto it = resources.find(path); + if (it != resources.end()) { + resource = Resource(true, *this, type, path); + return true; + } + return false; +} + +std::unique_ptr<std::istream> StaticResourceLocator::doStream( + const std::string &location) const +{ + auto it = resources.find(location); + if (it != resources.end()) { + return std::unique_ptr<std::istream>{new std::stringstream{it->second}}; + } + return std::unique_ptr<std::istream>{new std::stringstream{""}}; +} + +void StaticResourceLocator::store(const std::string &path, + const std::string &data) +{ + auto it = resources.find(path); + if (it != resources.end()) { + it->second = data; + } else { + resources.emplace(path, data); + } +} + +/* Class NullResourceLocatorImpl */ + +bool NullResourceLocatorImpl::doLocate(Resource &resource, + const std::string &path, + const ResourceType type, + const std::string &relativeTo) const +{ + return false; +} +std::unique_ptr<std::istream> NullResourceLocatorImpl::doStream( + const std::string &location) const +{ + return std::unique_ptr<std::istream>{new std::stringstream{""}}; +} + +const NullResourceLocatorImpl NullResourceLocator; +} + diff --git a/src/core/resource/ResourceLocator.hpp b/src/core/resource/ResourceLocator.hpp index 39c7b30..c1d0807 100644 --- a/src/core/resource/ResourceLocator.hpp +++ b/src/core/resource/ResourceLocator.hpp @@ -22,8 +22,13 @@ #include <istream> #include <memory> +#include "Resource.hpp" + namespace ousia { +// Forward declaration +class ResourceLocator; + /** * A ResourceLocator is a class able to locate resources in some way, usually * on the hard drive. @@ -33,84 +38,82 @@ namespace ousia { * locations (e.g. online resources, .zip files, etc.). */ class ResourceLocator { -public: +protected: /** - * This enum contains all possible types of includable resources in Ousía. + * The locate function uses this ResourceLocator to search for a given + * Resource name (path parameter). It returns a Location with the + * 'valid' flag set accordingly. + * + * @param resource reference to a Resource the will be set the the found + * location. The content of the variable will be only valid if the return + * value of this function is set to true. + * @param path is the resource name. + * @param relativeTo is an already resolved fully qualified name/canonical + * path that is to be used as base directory for this search. It is + * guaranteed that the path was produced by this locator instance. Otherwise + * this argument is set to an empty string. + * @param type is the type of this resource. + * @return true if a resource could be found, false otherwise. + */ + virtual bool doLocate(Resource &resource, const std::string &path, + const ResourceType type, + const std::string &relativeTo) const = 0; + + /** + * This method returns a stream containing the data of the resource at the + * given location. + * + * @param location is a found location, most likely from a Location. + * + * @return a stream containing the data of the Resource at this + * location. This has to be a unique_pointer because the current + * C++11 compiler does not yet support move semantics for + * streams. */ - enum class Type { - // A Domain description - DOMAIN_DESC, - // An ECMA/JavaScript - SCRIPT, - // A Type System - TYPESYS, - DOCUMENT, - ATTRIBUTES, - // TODO: Aren't documents and attribute descriptors missing? - // TODO: What is the purpose of these two? - GENERIC_MODULE, - GENERIC_INCLUDE - }; + virtual std::unique_ptr<std::istream> doStream( + const std::string &location) const = 0; +public: /** - * A Location contains the location of a Resource, e.g. a file path - * on a hard drive. Note that the 'found' flag might be set to false - * indicating that a resource was not found. + * Virtual destructor of the ResourceLocator interface. */ - struct Location { - const bool found; - const ResourceLocator &locator; - const Type type; - /** - * This is a fully qualified/canonical path to the resource found or - * in an undefined state (possibly empty) if the 'found' flag is set - * to 'false'. - */ - const std::string location; - - Location(const bool found, const ResourceLocator &locator, - const Type type, const std::string location) - : found(found), locator(locator), type(type), location(location) - { - } - - /** - * This calls the 'stream' method of the underlying ResourceLocator that - * found this location and returns a stream containing the data of the - * Resource at this location. - * - * @return a stream containing the data of the Resource at this - * location. This has to be a unique_pointer because the current - * C++11 compiler does not yet support move semantics for - * streams. - */ - std::unique_ptr<std::istream> stream() const - { - return std::move(locator.stream(location)); - } - }; + virtual ~ResourceLocator() {} /** * The locate function uses this ResourceLocator to search for a given - * Resource name (path parameter). It returns a Location with the - * 'found' flag set accordingly. + * Resource name (path parameter). * + * @param resource reference to a Resource the will be set the the found + * location. The content of the variable will be only valid if the return + * value of this function is set to true. * @param path is the resource name. - * @param relativeTo is an already resolved fully qualified name/canonical - * path that is to be used as base directory for this - * search. + * @param relativeTo is an already resolved Resource. * @param type is the type of this resource. + * @return true if a resource could be found, false otherwise. + */ + bool locate(Resource &resource, const std::string &path, + const ResourceType type = ResourceType::UNKNOWN, + const Resource &relativeTo = NullResource) const; + + /** + * The locate function uses this ResourceLocator to search for a given + * Resource name (path parameter). * - * @return A Location containing either the found location of the - * Resource and the found flag set to 'true' or an empty location - * and the found flag set to 'false'. + * @param resource reference to a Resource the will be set the the found + * location. The content of the variable will be only valid if the return + * value of this function is set to true. + * @param path is the resource name. + * @param type is the type of this resource. + * @param relativeTo is the location of an already resolved resource + * relative to which this resource should be located. + * @return true if a resource could be found, false otherwise. */ - virtual Location locate(const std::string &path, - const std::string &relativeTo, - const Type type) const = 0; + bool locate(Resource &resource, const std::string &path, + const ResourceType type, + const std::string &relativeTo) const; /** - * This method returns a strem containing the data of the resource at the + * This method returns a stream containing the data of the resource at the * given location. * * @param location is a found location, most likely from a Location. @@ -120,9 +123,70 @@ public: * C++11 compiler does not yet support move semantics for * streams. */ - virtual std::unique_ptr<std::istream> stream( - const std::string &location) const = 0; + std::unique_ptr<std::istream> stream(const std::string &location) const; +}; + +/** + * The StaticResourceLocator class stores a set of predefined resources in + * memory and allows to return these. + */ +class StaticResourceLocator : public ResourceLocator { +private: + /** + * Map containing the paths and the corresponding stored data. + */ + std::map<std::string, std::string> resources; + +protected: + /** + * Always returns false. + */ + bool doLocate(Resource &resource, const std::string &path, + const ResourceType type, + const std::string &relativeTo) const override; + + /** + * Returns an input stream containing an empty string. + */ + std::unique_ptr<std::istream> doStream( + const std::string &location) const override; + +public: + /** + * Stores static (string) data for the given path. + * + * @param path is the path the resource should be stored with. + * @param data is the data that should be stored for that path. + */ + void store(const std::string &path, const std::string &data); }; + +/** + * Implementation of the NullResourceLocator - contains a default implementation + * of the ResourceLocator class that does nothing. This class is e.g. used in + * the default constructor of the resource class. A instance of the class is + * provided as "NullResourceLocator". + */ +class NullResourceLocatorImpl : public ResourceLocator { +protected: + /** + * Always returns false. + */ + bool doLocate(Resource &resource, const std::string &path, + const ResourceType type, + const std::string &relativeTo) const override; + + /** + * Returns an input stream containing an empty string. + */ + std::unique_ptr<std::istream> doStream( + const std::string &location) const override; +}; + +/** + * The NullResourceLocator is used as a fallback for invalid Resources. + */ +extern const NullResourceLocatorImpl NullResourceLocator; } #endif /* _RESOURCE_LOCATOR_HPP_ */ |