From 938ed7622656c3494ae8fdb83bc2ad4b1f31d901 Mon Sep 17 00:00:00 2001
From: Adrian Kummerländer
Date: Fri, 25 Apr 2014 17:44:32 +0200
Subject: Improved argument resolution and error handling * execute member
 method internal argument count checks are not needed when using between one
 and two arguments ** xalan automatically generates the appropriate message
 containing the getError message when only offered fixed argument execute
 member overloads * improved FunctionReadDirectory attribute element
 generation * added additional validations to FunctionReadFile and
 FunctionReadXMLFile * I plan to return errors inside a DOM tree alongside the
 function return values in the future

---
 src/function/read_directory.cc | 48 ++++++++++++++++++++++--------------------
 src/function/read_directory.h  |  6 ++++--
 src/function/read_file.cc      | 44 +++++++++++++++++++-------------------
 src/function/read_file.h       |  2 +-
 src/function/read_xml_file.cc  | 40 +++++++++++++++++------------------
 src/function/read_xml_file.h   |  8 +++----
 6 files changed, 76 insertions(+), 72 deletions(-)

(limited to 'src/function')

diff --git a/src/function/read_directory.cc b/src/function/read_directory.cc
index 245f311..9711239 100644
--- a/src/function/read_directory.cc
+++ b/src/function/read_directory.cc
@@ -15,41 +15,43 @@ FunctionReadDirectory::FunctionReadDirectory(const FilesystemContext& context):
 	documents_(std::make_shared<std::stack<DomDocumentGuard>>()) { }
 
 xalan::XObjectPtr FunctionReadDirectory::execute(
-	xalan::XPathExecutionContext&                executionContext,
-	xalan::XalanNode*                            context,
-	const xalan::Function::XObjectArgVectorType& arguments,
-	const xalan::Locator*                        locator
+	xalan::XPathExecutionContext& executionContext,
+	xalan::XalanNode*,
+	const xalan::XObjectPtr argument,
+	const xalan::Locator*
 ) const {
-	if ( arguments.size() != 1 ) {
-		xalan::XPathExecutionContext::GetAndReleaseCachedString guard(
-			executionContext
-		);
-
-		this->generalError(executionContext, context, locator);
-	}
-
 	this->documents_->emplace("content");
 	DomDocumentGuard& domDocument = this->documents_->top();
 
 	xercesc::DOMNode* const rootNode = domDocument->getDocumentElement();
 
 	this->fs_context_.iterate(
-		arguments[0]->str(),
+		argument->str(),
 		[&domDocument, &rootNode](const boost::filesystem::path& p) {
 		xercesc::DOMElement* const itemNode(
 			domDocument->createElement(*XercesStringGuard("item"))
 		);
 
-		if ( boost::filesystem::is_regular_file(p) ) {
-			itemNode->setAttribute(
-				*XercesStringGuard("type"),
-				*XercesStringGuard("file")
-			);
-		} else if ( boost::filesystem::is_directory(p) ) {
-			itemNode->setAttribute(
-				*XercesStringGuard("type"),
-				*XercesStringGuard("directory")
-			);
+		switch ( boost::filesystem::status(p).type() ) {
+			case boost::filesystem::regular_file: {
+				itemNode->setAttribute(
+					*XercesStringGuard("type"),
+					*XercesStringGuard("file")
+				);
+
+				break;
+			};
+			case boost::filesystem::directory_file: {
+				itemNode->setAttribute(
+					*XercesStringGuard("type"),
+					*XercesStringGuard("directory")
+				);
+
+				break;
+			};
+			default: {
+				break;
+			};
 		}
 
 		xercesc::DOMText* const textNode(
diff --git a/src/function/read_directory.h b/src/function/read_directory.h
index 3c55591..782ebed 100644
--- a/src/function/read_directory.h
+++ b/src/function/read_directory.h
@@ -22,7 +22,7 @@ class FunctionReadDirectory : public xalan::Function {
 		virtual xalan::XObjectPtr execute(
 			xalan::XPathExecutionContext&,
 			xalan::XalanNode*,
-			const xalan::Function::XObjectArgVectorType&,
+			const xalan::XObjectPtr,
 			const xalan::Locator*
 		) const;
 
@@ -34,7 +34,9 @@ class FunctionReadDirectory : public xalan::Function {
 	private:
 		const FilesystemContext& fs_context_;
 
-		std::shared_ptr<std::stack<DomDocumentGuard>> documents_;
+		std::shared_ptr<
+			std::stack<DomDocumentGuard>
+		> documents_;
 
 		const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const;
 
diff --git a/src/function/read_file.cc b/src/function/read_file.cc
index 9e32f04..ac6225a 100644
--- a/src/function/read_file.cc
+++ b/src/function/read_file.cc
@@ -10,31 +10,31 @@ FunctionReadFile::FunctionReadFile(const FilesystemContext& context):
 	fs_context_(context) { }
 
 xalan::XObjectPtr FunctionReadFile::execute(
-	xalan::XPathExecutionContext&                executionContext,
-	xalan::XalanNode*                            context,
-	const xalan::Function::XObjectArgVectorType& arguments,
-	const xalan::Locator*                        locator
+	xalan::XPathExecutionContext& executionContext,
+	xalan::XalanNode*,
+	const xalan::XObjectPtr argument,
+	const xalan::Locator*
 ) const {
-	if ( arguments.size() != 1 ) {
-		xalan::XPathExecutionContext::GetAndReleaseCachedString guard(
-			executionContext
-		);
-
-		this->generalError(executionContext, context, locator);
-	}
-
-	boost::filesystem::ifstream file(
-		this->fs_context_.resolve(arguments[0]->str())
+	const boost::filesystem::path filePath(
+		this->fs_context_.resolve(argument->str())
 	);
 
-	const std::string fileContent(
-		(std::istreambuf_iterator<char>(file)),
-		(std::istreambuf_iterator<char>())
-	);
+	if ( boost::filesystem::is_regular_file(filePath) ) {
+		boost::filesystem::ifstream file(filePath);
 
-	return executionContext.getXObjectFactory().createString(
-		xalan::XalanDOMString(fileContent.data())
-	);
+		const std::string fileContent(
+			(std::istreambuf_iterator<char>(file)),
+			(std::istreambuf_iterator<char>())
+		);
+
+		return executionContext.getXObjectFactory().createString(
+			xalan::XalanDOMString(fileContent.data())
+		);
+	} else {
+		return executionContext.getXObjectFactory().createString(
+			xalan::XalanDOMString("io error")
+		);
+	}
 }
 
 FunctionReadFile* FunctionReadFile::clone(
@@ -44,7 +44,7 @@ FunctionReadFile* FunctionReadFile::clone(
 
 const xalan::XalanDOMString& FunctionReadFile::getError(
 	xalan::XalanDOMString& result) const {
-	result.assign("The read-file() function expects one argument.");
+	result.assign("The read-file() function expects one argument of type string.");
 
 	return result;
 }
diff --git a/src/function/read_file.h b/src/function/read_file.h
index b88336a..2d1dedf 100644
--- a/src/function/read_file.h
+++ b/src/function/read_file.h
@@ -20,7 +20,7 @@ class FunctionReadFile : public xalan::Function {
 		virtual xalan::XObjectPtr execute(
 			xalan::XPathExecutionContext&,
 			xalan::XalanNode*,
-			const xalan::Function::XObjectArgVectorType&,
+			const xalan::XObjectPtr,
 			const xalan::Locator*
 		) const;
 
diff --git a/src/function/read_xml_file.cc b/src/function/read_xml_file.cc
index ac42288..d429f34 100644
--- a/src/function/read_xml_file.cc
+++ b/src/function/read_xml_file.cc
@@ -13,28 +13,28 @@ FunctionReadXmlFile::FunctionReadXmlFile(const FunctionReadXmlFile& src):
 	parser_() { }
 
 xalan::XObjectPtr FunctionReadXmlFile::execute(
-	xalan::XPathExecutionContext&                executionContext,
-	xalan::XalanNode*                            context,
-	const xalan::Function::XObjectArgVectorType& arguments,
-	const xalan::Locator*                        locator
+	xalan::XPathExecutionContext& executionContext,
+	xalan::XalanNode*,
+	const xalan::XObjectPtr argument,
+	const xalan::Locator*
 ) const {
-	if ( arguments.size() != 1 ) {
-		xalan::XPathExecutionContext::GetAndReleaseCachedString guard(
-			executionContext
-		);
-
-		this->generalError(executionContext, context, locator);
-	}
-
-	boost::filesystem::ifstream file(
-		this->fs_context_.resolve(arguments[0]->str())
+	const boost::filesystem::path filePath(
+		this->fs_context_.resolve(argument->str())
 	);
 
-	return executionContext.getXObjectFactory().createNodeSet(
-		this->parser_.parseXMLStream(
-			xalan::XSLTInputSource(file)
-		)
-	);
+	if ( boost::filesystem::is_regular_file(filePath) ) {
+		boost::filesystem::ifstream file(filePath);
+
+		return executionContext.getXObjectFactory().createNodeSet(
+			this->parser_.parseXMLStream(
+				xalan::XSLTInputSource(file)
+			)
+		);
+	} else {
+		return executionContext.getXObjectFactory().createString(
+			xalan::XalanDOMString("io error")
+		);
+	}
 }
 
 FunctionReadXmlFile* FunctionReadXmlFile::clone(
@@ -44,7 +44,7 @@ FunctionReadXmlFile* FunctionReadXmlFile::clone(
 
 const xalan::XalanDOMString& FunctionReadXmlFile::getError(
 	xalan::XalanDOMString& result) const {
-	result.assign("The read-xml-file() function expects one argument.");
+	result.assign("The read-xml-file() function expects one argument of type string.");
 
 	return result;
 }
diff --git a/src/function/read_xml_file.h b/src/function/read_xml_file.h
index aa8590a..775ec96 100644
--- a/src/function/read_xml_file.h
+++ b/src/function/read_xml_file.h
@@ -20,10 +20,10 @@ class FunctionReadXmlFile : public xalan::Function {
 		FunctionReadXmlFile(const FunctionReadXmlFile&);
 
 		virtual xalan::XObjectPtr execute(
-			xalan::XPathExecutionContext&                executionContext,
-			xalan::XalanNode*                            context,
-			const xalan::Function::XObjectArgVectorType& arguments,
-			const xalan::Locator*                        locator
+			xalan::XPathExecutionContext&,
+			xalan::XalanNode*,
+			const xalan::XObjectPtr,
+			const xalan::Locator*
 		) const;
 
 		virtual FunctionReadXmlFile* clone(xalan::MemoryManager&) const;
-- 
cgit v1.2.3