mirror of
				https://github.com/Laupetin/OpenAssetTools.git
				synced 2025-10-30 18:17:15 +00:00 
			
		
		
		
	Add ParserMultiInputStream
This commit is contained in:
		| @@ -65,7 +65,7 @@ bool IncludingStreamProxy::MatchIncludeDirective(const ParserLine& line, unsigne | ||||
|     unsigned filenameStart, filenameEnd; | ||||
|  | ||||
|     if (!ExtractIncludeFilename(line, directivePosition, filenameStart, filenameEnd)) | ||||
|         throw ParsingException(TokenPos(line.m_filename, line.m_line_number, directivePosition), INCLUDE_QUOTES_ERROR); | ||||
|         throw ParsingException(TokenPos(line.m_filename, line.m_line_number, static_cast<int>(directivePosition)), INCLUDE_QUOTES_ERROR); | ||||
|  | ||||
|     if (filenameEnd <= filenameStart) | ||||
|         throw ParsingException(CreatePos(line, directivePosition), "No filename specified"); | ||||
|   | ||||
							
								
								
									
										104
									
								
								src/Parser/Parsing/Impl/ParserMultiInputStream.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/Parser/Parsing/Impl/ParserMultiInputStream.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| #include "ParserMultiInputStream.h" | ||||
|  | ||||
| #include <sstream> | ||||
|  | ||||
| ParserMultiInputStream::FileInfo::FileInfo(std::unique_ptr<std::istream> stream, std::string filePath) | ||||
|     : m_owned_stream(std::move(stream)), | ||||
|       m_stream(*m_owned_stream), | ||||
|       m_file_path(std::move(filePath)), | ||||
|       m_line_number(1) | ||||
| { | ||||
| } | ||||
|  | ||||
| ParserMultiInputStream::FileInfo::FileInfo(std::istream& stream, std::string filePath) | ||||
|     : m_stream(stream), | ||||
|       m_file_path(std::move(filePath)), | ||||
|       m_line_number(1) | ||||
| { | ||||
| } | ||||
|  | ||||
| ParserMultiInputStream::ParserMultiInputStream(std::unique_ptr<std::istream> stream, std::string fileName, include_callback_t includeCallback) | ||||
|     : m_include_callback(std::move(includeCallback)) | ||||
| { | ||||
|     m_files.emplace(std::move(stream), std::move(fileName)); | ||||
| } | ||||
|  | ||||
| ParserMultiInputStream::ParserMultiInputStream(std::istream& stream, std::string fileName, include_callback_t includeCallback) | ||||
|     : m_include_callback(std::move(includeCallback)) | ||||
| { | ||||
|     m_files.emplace(stream, std::move(fileName)); | ||||
| } | ||||
|  | ||||
| ParserLine ParserMultiInputStream::NextLine() | ||||
| { | ||||
|     std::ostringstream str; | ||||
|     auto hasLength = false; | ||||
|  | ||||
|     if (m_files.empty()) | ||||
|         return ParserLine(); | ||||
|  | ||||
|     while (!m_files.empty()) | ||||
|     { | ||||
|         auto& fileInfo = m_files.top(); | ||||
|  | ||||
|         auto c = fileInfo.m_stream.get(); | ||||
|         while (c != EOF) | ||||
|         { | ||||
|             switch (c) | ||||
|             { | ||||
|             case '\r': | ||||
|                 c = fileInfo.m_stream.get(); | ||||
|                 if (c == '\n') | ||||
|                     return ParserLine(fileInfo.m_file_path, fileInfo.m_line_number++, str.str()); | ||||
|                 str << '\r'; | ||||
|                 hasLength = true; | ||||
|                 continue; | ||||
|  | ||||
|             case '\n': | ||||
|                 return ParserLine(fileInfo.m_file_path, fileInfo.m_line_number++, str.str()); | ||||
|  | ||||
|             default: | ||||
|                 str << static_cast<char>(c); | ||||
|                 hasLength = true; | ||||
|                 break; | ||||
|             } | ||||
|  | ||||
|             c = fileInfo.m_stream.get(); | ||||
|         } | ||||
|  | ||||
|         if (hasLength) | ||||
|             return ParserLine(fileInfo.m_file_path, fileInfo.m_line_number, str.str()); | ||||
|         m_files.pop(); | ||||
|     } | ||||
|  | ||||
|     return ParserLine(); | ||||
| } | ||||
|  | ||||
| bool ParserMultiInputStream::IncludeFile(const std::string& filename) | ||||
| { | ||||
|     if (!m_include_callback) | ||||
|         return false; | ||||
|  | ||||
|     auto newFile = m_include_callback(filename); | ||||
|     if (!newFile) | ||||
|         return false; | ||||
|  | ||||
|     m_files.emplace(std::move(newFile), filename); | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void ParserMultiInputStream::PopCurrentFile() | ||||
| { | ||||
|     if (!m_files.empty()) | ||||
|         m_files.pop(); | ||||
| } | ||||
|  | ||||
| bool ParserMultiInputStream::IsOpen() const | ||||
| { | ||||
|     return !m_files.empty(); | ||||
| } | ||||
|  | ||||
| bool ParserMultiInputStream::Eof() const | ||||
| { | ||||
|     return m_files.empty(); | ||||
| } | ||||
							
								
								
									
										40
									
								
								src/Parser/Parsing/Impl/ParserMultiInputStream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Parser/Parsing/Impl/ParserMultiInputStream.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <istream> | ||||
| #include <stack> | ||||
| #include <memory> | ||||
| #include <functional> | ||||
|  | ||||
| #include "Parsing/IParserLineStream.h" | ||||
|  | ||||
| class ParserMultiInputStream final : public IParserLineStream | ||||
| { | ||||
| public: | ||||
|     using include_callback_t = std::function<std::unique_ptr<std::istream>(const std::string& filename)>; | ||||
|  | ||||
| private: | ||||
|     class FileInfo | ||||
|     { | ||||
|     public: | ||||
|         std::unique_ptr<std::istream> m_owned_stream; | ||||
|         std::istream& m_stream; | ||||
|         std::string m_file_path; | ||||
|         int m_line_number; | ||||
|  | ||||
|         FileInfo(std::unique_ptr<std::istream> stream, std::string filePath); | ||||
|         FileInfo(std::istream& stream, std::string filePath); | ||||
|     }; | ||||
|  | ||||
|     const include_callback_t m_include_callback; | ||||
|     std::stack<FileInfo> m_files; | ||||
|  | ||||
| public: | ||||
|     ParserMultiInputStream(std::unique_ptr<std::istream> stream, std::string fileName, include_callback_t includeCallback); | ||||
|     ParserMultiInputStream(std::istream& stream, std::string fileName, include_callback_t includeCallback); | ||||
|  | ||||
|     ParserLine NextLine() override; | ||||
|     bool IncludeFile(const std::string& filename) override; | ||||
|     void PopCurrentFile() override; | ||||
|     _NODISCARD bool IsOpen() const override; | ||||
|     _NODISCARD bool Eof() const override; | ||||
| }; | ||||
| @@ -1,15 +1,15 @@ | ||||
| #include "ParserInputStream.h" | ||||
| #include "ParserSingleInputStream.h" | ||||
| 
 | ||||
| #include <sstream> | ||||
| 
 | ||||
| ParserInputStream::ParserInputStream(std::istream& stream, std::string fileName) | ||||
| ParserSingleInputStream::ParserSingleInputStream(std::istream& stream, std::string fileName) | ||||
|     : m_stream(stream), | ||||
|       m_file_name(std::move(fileName)), | ||||
|       m_line_number(1) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| ParserLine ParserInputStream::NextLine() | ||||
| ParserLine ParserSingleInputStream::NextLine() | ||||
| { | ||||
|     std::ostringstream str; | ||||
|     auto hasLength = false; | ||||
| @@ -45,21 +45,21 @@ ParserLine ParserInputStream::NextLine() | ||||
|     return ParserLine(); | ||||
| } | ||||
| 
 | ||||
| bool ParserInputStream::IncludeFile(const std::string& filename) | ||||
| bool ParserSingleInputStream::IncludeFile(const std::string& filename) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void ParserInputStream::PopCurrentFile() | ||||
| void ParserSingleInputStream::PopCurrentFile() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| bool ParserInputStream::IsOpen() const | ||||
| bool ParserSingleInputStream::IsOpen() const | ||||
| { | ||||
|     return !m_stream.eof(); | ||||
| } | ||||
| 
 | ||||
| bool ParserInputStream::Eof() const | ||||
| bool ParserSingleInputStream::Eof() const | ||||
| { | ||||
|     return !m_stream.eof(); | ||||
| } | ||||
| @@ -4,14 +4,14 @@ | ||||
| 
 | ||||
| #include "Parsing/IParserLineStream.h" | ||||
| 
 | ||||
| class ParserInputStream final : public IParserLineStream | ||||
| class ParserSingleInputStream final : public IParserLineStream | ||||
| { | ||||
|     std::istream& m_stream; | ||||
|     std::string m_file_name; | ||||
|     int m_line_number; | ||||
| 
 | ||||
| public: | ||||
|     ParserInputStream(std::istream& stream, std::string fileName); | ||||
|     ParserSingleInputStream(std::istream& stream, std::string fileName); | ||||
| 
 | ||||
|     ParserLine NextLine() override; | ||||
|     bool IncludeFile(const std::string& filename) override; | ||||
		Reference in New Issue
	
	Block a user