From 9b9c7439b6cb1b711901ad49cd4855e1b0964652 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Thu, 22 Jan 2015 02:49:09 +0100 Subject: Backup --- src/core/resource/ResourceManager.cpp | 252 ++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 src/core/resource/ResourceManager.cpp (limited to 'src/core/resource/ResourceManager.cpp') diff --git a/src/core/resource/ResourceManager.cpp b/src/core/resource/ResourceManager.cpp new file mode 100644 index 0000000..563fc12 --- /dev/null +++ b/src/core/resource/ResourceManager.cpp @@ -0,0 +1,252 @@ +/* + 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 . +*/ + +#include +#include +#include +#include +#include +#include + +#include "Resource.hpp" +#include "ResourceManager.hpp" + +namespace ousia { + +/* Deduction of the ResourceType */ + +namespace RttiTypes { +extern const Rtti Document; +extern const Rtti Domain; +extern const Rtti Node; +extern const Rtti Typesystem; +} + +/** + * Map mapping from relations (the "rel" attribute in includes) to the + * corresponding ResourceType. + */ +static const std::unordered_map RelResourceTypeMap{ + {"document", ResourceType::DOCUMENT}, + {"domain", ResourceType::DOMAIN_DESC}, + {"typesystem", ResourceType::TYPESYSTEM}}; + +/** + * Map mapping from Rtti pointers to the corresponding ResourceType. + */ +static const std::unordered_map RttiResourceTypeMap{ + {&RttiTypes::Document, ResourceType::DOCUMENT}, + {&RttiTypes::Domain, ResourceType::DOMAIN_DESC}, + {&RttiTypes::Typesystem, ResourceType::TYPESYSTEM}}; + +static ResourceType relToResourceType(const std::string &rel, Logger &logger) +{ + std::string s = Utils::toLowercase(rel); + if (!s.empty()) { + auto it = RelResourceTypeMap.find(s); + if (it != RelResourceTypeMap.end()) { + return it->second; + } else { + logger.error(std::string("Unknown relation \"") + rel + + std::string("\"")); + } + } + return ResourceType::UNKNOWN; +} + +static ResourceType supportedTypesToResourceType(const RttiSet &supportedTypes) +{ + if (supportedTypes.size() == 1U) { + auto it = RttiResourceTypeMap.find(supportedTypes[0]); + if (it != RelResourceTypeMap.end()) { + return it->second; + } + } + return ResourceType::UNKNOWN; +} + +static ResourceType deduceResourceType(const std::string &rel, + const RttiSet &supportedTypes, + Logger &logger) +{ + ResourceType res; + + // Try to deduce the ResourceType from the "rel" attribute + res = relToResourceType(rel, logger); + + // If this did not work, try to deduce the ResourceType from the + // supportedTypes supplied by the Parser instance. + if (res == ResourceType::UNKNOWN) { + res = supportedTypesToResourceType(supportedTypes); + } + if (res == ResourceType::UNKNOWN) { + logger.note( + "Ambigous resource type, consider specifying the \"rel\" " + "attribute"); + } + return res; +} + +/* Functions for reducing the set of supported types */ + +/** + * Map mapping from relations (the "rel" attribute in includes) to the + * corresponding RttiType + */ +static const std::unordered_map RelRttiTypeMap{ + {"document", &RttiTypes::DOCUMENT}, + {"domain", &RttiTypes::DOMAIN}, + {"typesystem", &RttiTypes::TYPESYSTEM}}; + +static Rtti *relToRttiType(const std::string &rel) +{ + std::string s = Utils::toLowercase(rel); + if (!s.empty()) { + auto it = RelRttiTypeMap.find(s); + if (it != RelRttiTypeMap.end()) { + return it->second; + } + } + return &ResourceType::Node; +} + +static RttiType shrinkSupportedTypes(const RttiSet &supportedTypes, + const std::string &rel) +{ + RttiSet types; + RttiType *type = relToRttiType(rel); + for (RttiType *supportedType : supportedTypes) { + if (supportedType->isa(type)) { + types.insert(supportedType); + } + } + return types; +} + +/* Class ResourceManager */ + +Rooted ResourceManager::link(ParserContext &ctx, Resource &resource, + const std::string &mimetype, + const RttiSet &supportedTypes) +{ + +} + +Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, + const std::string &mimetype, + const std::string &rel, + const RttiSet &supportedTypes, + const Resource &relativeTo) +{ + // Try to deduce the ResourceType + ResourceType resourceType = + deduceResourceType(rel, supportedTypes, ctx.logger); + + // Lookup the resource for given path and resource type + Resource resource; + if (!ctx.registry.locateResource(resource, path, resourceType, + relativeTo)) { + ctx.logger.error("File \"" + path + "\" not found."); + return nullptr; + } + + // Try to shrink the set of supportedTypes + RttiSet types = shrinkSupportedTypes(supportedTypes, rel); + + // Check whether the resource has already been parsed + Rooted node = nullptr; + auto it = locations.find(res.getLocation()); + if (it != locations.end()) { + node = + } + = link(ctx, resource, mimetype, types); + + // Try to deduce the mimetype + std::string mime = mimetype; + if (mime.empty()) { + // Fetch the file extension + std::string ext = Utils::extractFileExtension(path); + if (ext.empty()) { + ctx.logger.error( + std::string("Specified filename \"") + path + + std::string( + "\" has no extension and no mimetype (\"type\" " + "attribute) was given instead.")); + return nullptr; + } + + // Fetch the mimetype for the extension + mime = ctx.registry.getMimetypeForExtension(ext); + if (mime.empty()) { + ctx.logger.error(std::string("Unknown file extension \"") + ext + + std::string("\"")); + return nullptr; + } + } + + // Fetch a parser for the mimetype + const std::pair parser = + ctx.registry.getParserForMimetype(mime); + + // Make sure a parser was found + if (!parser->first) { + ctx.logger.error(std::string("Cannot parse files of type \"") + mime + + std::string("\"")); + } + + // Make sure the parser returns one of the supported types +} + +Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, + const std::string &mimetype, + const std::string &rel, + const RttiSet &supportedTypes, + SourceId relativeTo) +{ + // Fetch the resource corresponding to the source id, make sure it is valid + const Resource &relativeResource = getResource(relativeTo); + if (!relativeResource.isValid()) { + ctx.logger.fatalError("Internal error: Invalid SourceId supplied."); + return nullptr; + } + + // Continue with the usual include routine + return include(ctx, path, mimetype, rel, supportedTypes, relativeResource); +} + +const Resource &getResource(SourceId sourceId) const +{ + if (sourceId < resources.size()) { + return resources[sourceId]; + } + return NullResource; +} + +SourceContext ResourceManager::buildContext(const SourceLocation &location) +{ + SourceContext res; + + // TODO + + return res; +} +}; +} + +#endif /* _OUSIA_RESOURCE_MANAGER_HPP_ */ + -- cgit v1.2.3 From 748a44fba54acb936249d13f69231c85f07a1069 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Fri, 23 Jan 2015 00:34:18 +0100 Subject: Implemented most functions in ResourceManager --- CMakeLists.txt | 1 + src/core/resource/ResourceManager.cpp | 294 ++++++++++++++++++---------------- src/core/resource/ResourceManager.hpp | 146 +++++++++++++---- 3 files changed, 276 insertions(+), 165 deletions(-) (limited to 'src/core/resource/ResourceManager.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index a56eb7f..ad9c0ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,6 +151,7 @@ ADD_LIBRARY(ousia_core src/core/parser/ParserStack src/core/resource/Resource src/core/resource/ResourceLocator + src/core/resource/ResourceManager src/core/resource/ResourceUtils # src/core/script/ScriptEngine ) diff --git a/src/core/resource/ResourceManager.cpp b/src/core/resource/ResourceManager.cpp index 563fc12..4a42609 100644 --- a/src/core/resource/ResourceManager.cpp +++ b/src/core/resource/ResourceManager.cpp @@ -16,6 +16,9 @@ along with this program. If not, see . */ +#include + +#include #include #include #include @@ -23,128 +26,182 @@ #include #include -#include "Resource.hpp" #include "ResourceManager.hpp" +#include "ResourceUtils.hpp" namespace ousia { -/* Deduction of the ResourceType */ - -namespace RttiTypes { -extern const Rtti Document; -extern const Rtti Domain; -extern const Rtti Node; -extern const Rtti Typesystem; -} - -/** - * Map mapping from relations (the "rel" attribute in includes) to the - * corresponding ResourceType. - */ -static const std::unordered_map RelResourceTypeMap{ - {"document", ResourceType::DOCUMENT}, - {"domain", ResourceType::DOMAIN_DESC}, - {"typesystem", ResourceType::TYPESYSTEM}}; - -/** - * Map mapping from Rtti pointers to the corresponding ResourceType. - */ -static const std::unordered_map RttiResourceTypeMap{ - {&RttiTypes::Document, ResourceType::DOCUMENT}, - {&RttiTypes::Domain, ResourceType::DOMAIN_DESC}, - {&RttiTypes::Typesystem, ResourceType::TYPESYSTEM}}; - -static ResourceType relToResourceType(const std::string &rel, Logger &logger) +/* Static helper functions */ + +static bool typeSetsIntersect(const RttiSet &s1, const RttiSet &s2) { - std::string s = Utils::toLowercase(rel); - if (!s.empty()) { - auto it = RelResourceTypeMap.find(s); - if (it != RelResourceTypeMap.end()) { - return it->second; - } else { - logger.error(std::string("Unknown relation \"") + rel + - std::string("\"")); + for (const Rtti *t1 : s1) { + if (t1->isOneOf(s2)) { + return true; } } - return ResourceType::UNKNOWN; + return false; } -static ResourceType supportedTypesToResourceType(const RttiSet &supportedTypes) +static void logUnsopportedType(Logger &logger, const RttiSet &supportedTypes) { - if (supportedTypes.size() == 1U) { - auto it = RttiResourceTypeMap.find(supportedTypes[0]); - if (it != RelResourceTypeMap.end()) { - return it->second; - } + // Build a list containing the expected type names + std::vector expected; + for (const Rtti *supportedType : supportedTypes) { + expected.push_back(supportedType->name); } - return ResourceType::UNKNOWN; + + // Log the actual error message + ctx.logger.error( + std::string("Expected the file \"") + resource.location + + std::string("\" to define one of the following internal types ") + + Utils::join(expected, ", ", "{", "}")); } -static ResourceType deduceResourceType(const std::string &rel, - const RttiSet &supportedTypes, - Logger &logger) +/* Class ResourceManager */ + +SourceId ResourceManager::allocateSourceId(const Resource &resource) { - ResourceType res; + // Increment the source id and make sure the values don't overflow + SourceId sourceId = nextSourceId++; + if (sourceId == InvalidSourceId) { + nextSourceId = InvalidSourceId; + throw OusiaException{"Internal resource handles depleted!"}; + } + + // Register the node and the resource with this id + locations[resource.getLocation()] = sourceId; + resources[sourceId] = resource; + + return sourceId; +} - // Try to deduce the ResourceType from the "rel" attribute - res = relToResourceType(rel, logger); +void ResourceManager::storeNode(SourceId sourceId, Handle node) +{ + nodes[sourceId] = node->getUid(); +} - // If this did not work, try to deduce the ResourceType from the - // supportedTypes supplied by the Parser instance. - if (res == ResourceType::UNKNOWN) { - res = supportedTypesToResourceType(supportedTypes); +void ResourceManager::purgeResource(SourceId sourceId) +{ + Resource res = getResource(sourceId); + if (res.isValid()) { + locations.erase(res.getLocation()); } - if (res == ResourceType::UNKNOWN) { - logger.note( - "Ambigous resource type, consider specifying the \"rel\" " - "attribute"); + resources.erase(sourceId); + nodes.erase(sourceId); + lineNumberCache.erase(sourceId); +} + +Rooted ResourceManager::parse(ParserContext &ctx, Resource &resource, + const std::string &mimetype, + const RttiSet &supportedTypes) +{ + // Try to deduce the mimetype of no mimetype was given + std::string mime = mimetype; + if (mime.empty()) { + mime = ctx.registry.getMimetypeForFilename(resource.getLocation()); + if (mime.empty()) { + ctx.logger.error(std::string("Filename \"") + path + + std::string( + "\" has an unknown file extension. Explicitly " + "specify a mimetype.")); + return nullptr; + } } - return res; + + // Fetch a parser for the mimetype + const std::pair &parserDescr = + ctx.registry.getParserForMimetype(mime); + Parser *parser = parserDescr.first; + + // Make sure a parser was found + if (!parser) { + ctx.logger.error(std::string("Cannot parse files of type \"") + mime + + std::string("\"")); + return nullptr; + } + + // Make sure the parser returns at least one of the supported types + if (!typeSetsIntersect(parserDescr.second, supportedTypes)) { + logUnsopportedType(ctx.logger, supportedTypes); + return nullptr; + } + + // Allocate a new SourceId handle for this Resource + SourceId sourceId = allocateSourceId(resource); + + // We can now try to parse the given file + Rooted node; + try { + CharReader reader(resource.stream(), sourceId); + node = parser->parse(reader, ctx); + if (node == nullptr) { + throw LoggableException{"Internal error: Parser returned null."}; + } + } catch (LoggableException ex) { + // Remove all data associated with the allocated source id + purgeResource(sourceId); + + // Log the exception and return nullptr + ctx.logger.log(ex); + return nullptr; + } + + // Store the parsed node along with the sourceId + storeNode(sourceId, node); + + // Return the parsed node + return node; } -/* Functions for reducing the set of supported types */ +SourceId ResourceManager::getSourceId(const std::string &location) +{ + auto it = locations.find(location); + if (it != locations.end()) { + return it->second; + } + return InvalidSourceId; +} -/** - * Map mapping from relations (the "rel" attribute in includes) to the - * corresponding RttiType - */ -static const std::unordered_map RelRttiTypeMap{ - {"document", &RttiTypes::DOCUMENT}, - {"domain", &RttiTypes::DOMAIN}, - {"typesystem", &RttiTypes::TYPESYSTEM}}; +SourceId ResourceManager::getSourceId(const Resource &resource) +{ + if (resource.isValid()) { + return getSourceId(resource.getLocation()); + } + return InvalidSourceId; +} -static Rtti *relToRttiType(const std::string &rel) +const Resource &ResourceManager::getResource(SourceId sourceId) const { - std::string s = Utils::toLowercase(rel); - if (!s.empty()) { - auto it = RelRttiTypeMap.find(s); - if (it != RelRttiTypeMap.end()) { - return it->second; - } + auto it = resources.find(sourceId); + if (it != resourced.end()) { + return it->second; } - return &ResourceType::Node; + return NullResource; } -static RttiType shrinkSupportedTypes(const RttiSet &supportedTypes, - const std::string &rel) +Rooted ResourceManager::getNode(Manager &mgr, SourceId sourceId) { - RttiSet types; - RttiType *type = relToRttiType(rel); - for (RttiType *supportedType : supportedTypes) { - if (supportedType->isa(type)) { - types.insert(supportedType); + auto it = nodes.find(sourceId); + if (it != nodes.end()) { + Managed *managed = mgr.getManaged(sourceId); + if (managed != nullptr) { + return dynamic_cast(managed); + } else { + purgeResource(sourceId); } } - return types; + return nullptr; } -/* Class ResourceManager */ +Rooted ResourceManager::getNode(Manager &mgr, const std::string &location) +{ + return getNode(mgr, getSourceId(location)); +} -Rooted ResourceManager::link(ParserContext &ctx, Resource &resource, - const std::string &mimetype, - const RttiSet &supportedTypes) +Rooted ResourceManager::getNode(Manager &mgr, const Resource &resource) { - + return getNode(mgr, getSourceId(resource)); } Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, @@ -155,7 +212,7 @@ Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, { // Try to deduce the ResourceType ResourceType resourceType = - deduceResourceType(rel, supportedTypes, ctx.logger); + ResourceUtils::deduceResourceType(rel, supportedTypes, ctx.logger); // Lookup the resource for given path and resource type Resource resource; @@ -166,50 +223,27 @@ Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, } // Try to shrink the set of supportedTypes - RttiSet types = shrinkSupportedTypes(supportedTypes, rel); + RttiSet types = ResourceUtils::limitRttiTypes(supportedTypes, rel); // Check whether the resource has already been parsed - Rooted node = nullptr; - auto it = locations.find(res.getLocation()); - if (it != locations.end()) { - node = - } - = link(ctx, resource, mimetype, types); + Rooted node = getNode(ctx.manager, resource); + if (node == nullptr) { + // Node has not already been parsed, parse it now + node = parse(ctx, resource, mimetype, supportedTypes); - // Try to deduce the mimetype - std::string mime = mimetype; - if (mime.empty()) { - // Fetch the file extension - std::string ext = Utils::extractFileExtension(path); - if (ext.empty()) { - ctx.logger.error( - std::string("Specified filename \"") + path + - std::string( - "\" has no extension and no mimetype (\"type\" " - "attribute) was given instead.")); - return nullptr; - } - - // Fetch the mimetype for the extension - mime = ctx.registry.getMimetypeForExtension(ext); - if (mime.empty()) { - ctx.logger.error(std::string("Unknown file extension \"") + ext + - std::string("\"")); + // Abort if parsing failed + if (node == nullptr) { return nullptr; } } - // Fetch a parser for the mimetype - const std::pair parser = - ctx.registry.getParserForMimetype(mime); - - // Make sure a parser was found - if (!parser->first) { - ctx.logger.error(std::string("Cannot parse files of type \"") + mime + - std::string("\"")); + // Make sure the node has one of the supported types + if (!node->type().isOneOf(supportedTypes)) { + logUnsopportedType(ctx.logger, supportedTypes); + return nullptr; } - // Make sure the parser returns one of the supported types + return node; } Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, @@ -229,14 +263,6 @@ Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, return include(ctx, path, mimetype, rel, supportedTypes, relativeResource); } -const Resource &getResource(SourceId sourceId) const -{ - if (sourceId < resources.size()) { - return resources[sourceId]; - } - return NullResource; -} - SourceContext ResourceManager::buildContext(const SourceLocation &location) { SourceContext res; @@ -245,7 +271,7 @@ SourceContext ResourceManager::buildContext(const SourceLocation &location) return res; } -}; + } #endif /* _OUSIA_RESOURCE_MANAGER_HPP_ */ diff --git a/src/core/resource/ResourceManager.hpp b/src/core/resource/ResourceManager.hpp index 809fd55..05dcc8e 100644 --- a/src/core/resource/ResourceManager.hpp +++ b/src/core/resource/ResourceManager.hpp @@ -35,12 +35,13 @@ #include #include +#include "Resource.hpp" + namespace ousia { // Forward declarations class Node; class ParserContext; -class Resource; class RttiSet; extern const Resource NullResource; @@ -52,19 +53,19 @@ extern const Resource NullResource; class ResourceManager { private: /** - * Vector used for mapping SourceId instances to the underlying resource. + * Next SourceId to be used. */ - std::vector resources; + SourceId nextSourceId = 0; /** - * Index pointing at the next free entry in the resources list. + * Map between Resource locations and the corresponding SourceId. */ - SourceId nextFreeSourceId = 0; + std::unordered_map locations; /** - * Map between Resource locations and the corresponding SourceId. + * Map used for mapping SourceId instances to the underlying resource. */ - std::unordered_map locations; + std::unordered_map resources; /** * Map between a SourceId and the corresponding (if available) parsed node @@ -79,22 +80,115 @@ private: */ std::unordered_map> lineNumberCache; + /** + * Allocates a new SourceId for the given resource. + * + * @param resource is the Resource that should be associated with the newly + * allocated SourceId. + * @return a new SourceId describing the given resource. + */ + SourceId allocateSourceId(const Resource &resource); - Rooted getCachedNode(SourceId id); + /** + * Registers the parsed node for this node id. + * + * @param sourceId is SourceId instance of the resource. + * @param node is the node that was parsed from that resource. + */ + void storeNode(SourceId sourceId, Handle node); - Rooted getCachedNode(const std::string &location); + /** + * Removes a resource from the internal stores. + * + * @param sourceId is the id of the file that should be removed. + */ + void purgeResource(SourceId sourceId); + /** + * Used internally to parse the given resource. + * + * @param ctx is the context from the Registry and the Logger instance will + * be looked up. + * @param resource is the resource from which the input stream should be + * obtained. + * @param mimetype is the mimetype of the resource that should be parsed + * (may be empty, in which case the mimetype is deduced from the file + * extension) + * @param supportedTypes contains the types of the returned Node the caller + * can deal with. Note that only the types the parser claims to return are + * checked, not the actual result. + * @return the parsed node or nullptr if something goes wrong. + */ + Rooted parse(ParserContext &ctx, Resource &resource, + const std::string &mimetype, + const RttiSet &supportedTypes); + +public: + /** + * Returns the sourceId for the given location string. + * + * @param location is the location string for which the resource id should + * be returned. + * @return the SourceId that can be used to identify the Resource, or + * InvalidSourceId if the specified location is not loaded. + */ SourceId getSourceId(const std::string &location); /** - * Used internally to either parse a resource or retrieve it from the - * internal cache of already parsed resources. + * Returns the sourceId for the given Resource. + * + * @param resource is the Resource for which the sourceId should be + * returned. + * @return the SourceId that can be used to identify the Resource, or + * InvalidSourceId if the specified resource is not loaded or invalid. */ - Rooted link(ParserContext &ctx, Resource &resource, const std::string &mimetype, - const RttiSet &supportedTypes); + SourceId getSourceId(const Resource &resource); + /** + * Returns a Resource instance for the given SourceId. + * + * @param sourceId is the id of the Resource instance that should be + * returned. + * @return the Resource instance corresponding to the given sourceId. If the + * sourceId is invalid, the returned Resource will be invalid (a reference + * at NullResource). + */ + const Resource &getResource(SourceId sourceId) const; + + /** + * Returns the node that is associated with the given SourceId or nullptr if + * the Node no longer exists or the supplied SourceId is invalid. + * + * @param mgr is the Manager instance that should be used to resolve the + * internal weak reference to the Node instance. + * @param sourceId is the id of the resource for which the parsed Node + * instance should be returned. + * @return the Node instance corresponding to the given sourceId. + */ + Rooted getNode(Manager &mgr, SourceId sourceId); + + /** + * Returns the node that is associated with the given location or nullptr if + * the Node no longer exists or the supplied location was never parsed. + * + * @param mgr is the Manager instance that should be used to resolve the + * internal weak reference to the Node instance. + * @param location is the location from which the node was parsed. + * @return the Node instance corresponding to the given location. + */ + Rooted getNode(Manager &mgr, const std::string &location); + + /** + * Returns the node that is associated with the given resource or nullptr if + * the Node no longer exists or the supplied resource was never parsed. + * + * @param mgr is the Manager instance that should be used to resolve the + * internal weak reference to the Node instance. + * @param resource is the resource from which the node was parsed. + * @return the Node instance corresponding to the given resource. + */ + Rooted getNode(Manager &mgr, const Resource &resource); -public: /** * Resolves the reference to the file specified by the given path and -- if * this has not already happened -- parses the file. Logs any problem in @@ -107,10 +201,10 @@ public: * mimetype is given, the path must have an extension that is known by */ Rooted link(ParserContext &ctx, const std::string &path, - const std::string &mimetype = "", - const std::string &rel = "", - const RttiSet &supportedTypes = RttiSet{}, - const Resource &relativeTo = NullResource); + const std::string &mimetype = "", + const std::string &rel = "", + const RttiSet &supportedTypes = RttiSet{}, + const Resource &relativeTo = NullResource); /** * Resolves the reference to the file specified by the given path and -- if @@ -118,19 +212,8 @@ public: * the logger instance of the given ParserContext. */ Rooted link(ParserContext &ctx, const std::string &path, - const std::string &mimetype, const std::string &rel, - const RttiSet &supportedTypes, SourceId relativeTo); - - /** - * Returns a Resource instance for the given SourceId. - * - * @param sourceId is the id of the Resource instance that should be - * returned. - * @return the Resource instance corresponding to the given sourceId. If the - * sourceId is invalid, the returned Resource will be invalid (a reference - * at NullResource). - */ - const Resource &getResource(SourceId sourceId) const; + const std::string &mimetype, const std::string &rel, + const RttiSet &supportedTypes, SourceId relativeTo); /** * Creates and returns a SourceContext structure containing information @@ -145,6 +228,7 @@ public: * invalid SourceContext if the location is invalid. */ SourceContext buildContext(const SourceLocation &location); + }; } -- cgit v1.2.3 From ea55274d4d5a6066f73380352274d568caa2d079 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Fri, 23 Jan 2015 15:31:34 +0100 Subject: Fixed ResourceManager and ResourceUtils --- src/core/resource/ResourceManager.cpp | 41 ++++++++++++++++------------------- src/core/resource/ResourceUtils.cpp | 25 +++++++++++---------- 2 files changed, 32 insertions(+), 34 deletions(-) (limited to 'src/core/resource/ResourceManager.cpp') diff --git a/src/core/resource/ResourceManager.cpp b/src/core/resource/ResourceManager.cpp index 4a42609..f154c9c 100644 --- a/src/core/resource/ResourceManager.cpp +++ b/src/core/resource/ResourceManager.cpp @@ -18,12 +18,14 @@ #include +#include #include #include #include #include #include #include +#include #include #include "ResourceManager.hpp" @@ -33,17 +35,7 @@ namespace ousia { /* Static helper functions */ -static bool typeSetsIntersect(const RttiSet &s1, const RttiSet &s2) -{ - for (const Rtti *t1 : s1) { - if (t1->isOneOf(s2)) { - return true; - } - } - return false; -} - -static void logUnsopportedType(Logger &logger, const RttiSet &supportedTypes) +static void logUnsopportedType(Logger &logger, Resource &resource, const RttiSet &supportedTypes) { // Build a list containing the expected type names std::vector expected; @@ -52,8 +44,8 @@ static void logUnsopportedType(Logger &logger, const RttiSet &supportedTypes) } // Log the actual error message - ctx.logger.error( - std::string("Expected the file \"") + resource.location + + logger.error( + std::string("Expected the file \"") + resource.getLocation() + std::string("\" to define one of the following internal types ") + Utils::join(expected, ", ", "{", "}")); } @@ -101,7 +93,7 @@ Rooted ResourceManager::parse(ParserContext &ctx, Resource &resource, if (mime.empty()) { mime = ctx.registry.getMimetypeForFilename(resource.getLocation()); if (mime.empty()) { - ctx.logger.error(std::string("Filename \"") + path + + ctx.logger.error(std::string("Filename \"") + resource.getLocation() + std::string( "\" has an unknown file extension. Explicitly " "specify a mimetype.")); @@ -122,8 +114,8 @@ Rooted ResourceManager::parse(ParserContext &ctx, Resource &resource, } // Make sure the parser returns at least one of the supported types - if (!typeSetsIntersect(parserDescr.second, supportedTypes)) { - logUnsopportedType(ctx.logger, supportedTypes); + if (!Rtti::setIsOneOf(parserDescr.second, supportedTypes)) { + logUnsopportedType(ctx.logger, resource, supportedTypes); return nullptr; } @@ -133,7 +125,14 @@ Rooted ResourceManager::parse(ParserContext &ctx, Resource &resource, // We can now try to parse the given file Rooted node; try { - CharReader reader(resource.stream(), sourceId); + // Set the current source id in the logger instance + ScopedLogger logger(ctx.logger, SourceLocation{sourceId}); + + // Fetch the input stream and create a char reader + std::unique_ptr is = resource.stream(); + CharReader reader(*is, sourceId); + + // Actually parse the input stream node = parser->parse(reader, ctx); if (node == nullptr) { throw LoggableException{"Internal error: Parser returned null."}; @@ -174,7 +173,7 @@ SourceId ResourceManager::getSourceId(const Resource &resource) const Resource &ResourceManager::getResource(SourceId sourceId) const { auto it = resources.find(sourceId); - if (it != resourced.end()) { + if (it != resources.end()) { return it->second; } return NullResource; @@ -239,7 +238,7 @@ Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, // Make sure the node has one of the supported types if (!node->type().isOneOf(supportedTypes)) { - logUnsopportedType(ctx.logger, supportedTypes); + logUnsopportedType(ctx.logger, resource, supportedTypes); return nullptr; } @@ -260,7 +259,7 @@ Rooted ResourceManager::link(ParserContext &ctx, const std::string &path, } // Continue with the usual include routine - return include(ctx, path, mimetype, rel, supportedTypes, relativeResource); + return link(ctx, path, mimetype, rel, supportedTypes, relativeResource); } SourceContext ResourceManager::buildContext(const SourceLocation &location) @@ -274,5 +273,3 @@ SourceContext ResourceManager::buildContext(const SourceLocation &location) } -#endif /* _OUSIA_RESOURCE_MANAGER_HPP_ */ - diff --git a/src/core/resource/ResourceUtils.cpp b/src/core/resource/ResourceUtils.cpp index 26faaad..7c42716 100644 --- a/src/core/resource/ResourceUtils.cpp +++ b/src/core/resource/ResourceUtils.cpp @@ -16,8 +16,9 @@ along with this program. If not, see . */ -#include #include +#include +#include #include "ResourceUtils.hpp" @@ -42,15 +43,15 @@ static const std::unordered_map RelResourceTypeMap{ /** * Map mapping from relations to the corresponding Rtti descriptor. */ -static const std::unordered_map RelRttiTypeMap{ - {"document", &RttiTypes::DOCUMENT}, - {"domain", &RttiTypes::DOMAIN}, - {"typesystem", &RttiTypes::TYPESYSTEM}}; +static const std::unordered_map RelRttiTypeMap{ + {"document", &RttiTypes::Document}, + {"domain", &RttiTypes::Domain}, + {"typesystem", &RttiTypes::Typesystem}}; /** * Map mapping from Rtti pointers to the corresponding ResourceType. */ -static const std::unordered_map RttiResourceTypeMap{ +static const std::unordered_map RttiResourceTypeMap{ {&RttiTypes::Document, ResourceType::DOCUMENT}, {&RttiTypes::Domain, ResourceType::DOMAIN_DESC}, {&RttiTypes::Typesystem, ResourceType::TYPESYSTEM}}; @@ -80,7 +81,7 @@ ResourceType ResourceUtils::deduceResourceType(const std::string &rel, ResourceType ResourceUtils::deduceResourceType(const std::string &rel, Logger &logger) { - std::string s = Utils::toLowercase(rel); + std::string s = Utils::toLower(rel); if (!s.empty()) { auto it = RelResourceTypeMap.find(s); if (it != RelResourceTypeMap.end()) { @@ -97,8 +98,8 @@ ResourceType ResourceUtils::deduceResourceType(const RttiSet &supportedTypes, Logger &logger) { if (supportedTypes.size() == 1U) { - auto it = RttiResourceTypeMap.find(supportedTypes[0]); - if (it != RelResourceTypeMap.end()) { + auto it = RttiResourceTypeMap.find(*supportedTypes.begin()); + if (it != RttiResourceTypeMap.end()) { return it->second; } } @@ -107,14 +108,14 @@ ResourceType ResourceUtils::deduceResourceType(const RttiSet &supportedTypes, const Rtti *ResourceUtils::deduceRttiType(const std::string &rel) { - std::string s = Utils::toLowercase(rel); + std::string s = Utils::toLower(rel); if (!s.empty()) { auto it = RelRttiTypeMap.find(s); if (it != RelRttiTypeMap.end()) { return it->second; } } - return &ResourceType::Node; + return &RttiTypes::Node; } RttiSet ResourceUtils::limitRttiTypes(const RttiSet &supportedTypes, @@ -128,7 +129,7 @@ RttiSet ResourceUtils::limitRttiTypes(const RttiSet &supportedTypes, { RttiSet res; for (const Rtti *supportedType : supportedTypes) { - if (supportedType.isa(type)) { + if (supportedType->isa(*type)) { res.insert(supportedType); } } -- cgit v1.2.3