Tidy up some xml structures.
This commit is contained in:
parent
875cdc84ff
commit
8771b721d1
31 changed files with 885 additions and 563 deletions
|
@ -5,7 +5,7 @@ target_include_directories(sample_gui PUBLIC
|
||||||
"${PROJECT_SOURCE_DIR}/src/client"
|
"${PROJECT_SOURCE_DIR}/src/client"
|
||||||
)
|
)
|
||||||
target_link_libraries(sample_gui PUBLIC client windows console core
|
target_link_libraries(sample_gui PUBLIC client windows console core
|
||||||
network database geometry audio graphics)
|
network database geometry audio graphics web)
|
||||||
|
|
||||||
# Sample Console
|
# Sample Console
|
||||||
add_executable(sample_console console-main.cpp)
|
add_executable(sample_console console-main.cpp)
|
||||||
|
@ -13,7 +13,7 @@ target_include_directories(sample_console PUBLIC
|
||||||
"${PROJECT_SOURCE_DIR}/src/console"
|
"${PROJECT_SOURCE_DIR}/src/console"
|
||||||
)
|
)
|
||||||
target_link_libraries(sample_console PUBLIC console core network
|
target_link_libraries(sample_console PUBLIC console core network
|
||||||
database geometry audio)
|
database geometry audio web)
|
||||||
|
|
||||||
# Xml practice
|
# Xml practice
|
||||||
add_executable(xml_practice xml-practice.cpp)
|
add_executable(xml_practice xml-practice.cpp)
|
||||||
|
@ -21,12 +21,4 @@ target_include_directories(xml_practice PUBLIC
|
||||||
"${PROJECT_SOURCE_DIR}/src/core"
|
"${PROJECT_SOURCE_DIR}/src/core"
|
||||||
"${PROJECT_SOURCE_DIR}/src/web/xml"
|
"${PROJECT_SOURCE_DIR}/src/web/xml"
|
||||||
)
|
)
|
||||||
target_link_libraries(xml_practice PUBLIC core web)
|
target_link_libraries(xml_practice PUBLIC core web)
|
||||||
|
|
||||||
# Markdown practice
|
|
||||||
add_executable(markdown_practice markdown-practice.cpp)
|
|
||||||
target_include_directories(markdown_practice PUBLIC
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/core"
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/web/markdown"
|
|
||||||
)
|
|
||||||
target_link_libraries(markdown_practice PUBLIC web core)
|
|
|
@ -1,37 +1,18 @@
|
||||||
#include <filesystem>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include "CommandLineArgs.h"
|
#include "CommandLineArgs.h"
|
||||||
#include "MainApplication.h"
|
#include "MainApplication.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
CommandLineArgs command_line_args;
|
auto command_line_args = CommandLineArgs::CreateUnique();
|
||||||
command_line_args.Process(argc, argv);
|
command_line_args->Process(argc, argv);
|
||||||
|
command_line_args->RecordLaunchPath();
|
||||||
|
|
||||||
std::string program_type;
|
// Start the main app
|
||||||
if(command_line_args.GetNumberOfArgs() > 1)
|
auto main_app = MainApplication::Create();
|
||||||
{
|
main_app->Initialize(std::move(command_line_args));
|
||||||
program_type = command_line_args.GetArg(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the main app
|
main_app->Run();
|
||||||
auto main_app = MainApplication::Create();
|
|
||||||
main_app->Initialize(std::filesystem::current_path());
|
|
||||||
|
|
||||||
if(program_type == "server")
|
main_app->ShutDown();
|
||||||
{
|
return 0;
|
||||||
main_app->RunServer();
|
|
||||||
}
|
|
||||||
else if(program_type == "audio")
|
|
||||||
{
|
|
||||||
main_app->PlayAudio();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Unknown program type" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
main_app->ShutDown();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
#include <filesystem>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "GuiApplication.h"
|
#include "GuiApplication.h"
|
||||||
#include "MainApplication.h"
|
#include "MainApplication.h"
|
||||||
|
#include "CommandLineArgs.h"
|
||||||
|
|
||||||
int main()
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
auto command_line_args = CommandLineArgs::CreateUnique();
|
||||||
|
command_line_args->Process(argc, argv);
|
||||||
|
command_line_args->RecordLaunchPath();
|
||||||
|
|
||||||
// Start the main app
|
// Start the main app
|
||||||
auto main_app = MainApplication::Create();
|
auto main_app = MainApplication::Create();
|
||||||
main_app->Initialize(std::filesystem::current_path());
|
main_app->Initialize(std::move(command_line_args));
|
||||||
|
|
||||||
// Start the gui app
|
// Start the gui app
|
||||||
auto gui_app = std::make_shared<GuiApplication>();
|
auto gui_app = std::make_shared<GuiApplication>();
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
#include <filesystem>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <ostream>
|
|
||||||
#include "CommandLineArgs.h"
|
|
||||||
#include "MarkdownParser.h"
|
|
||||||
#include "HtmlDocument.h"
|
|
||||||
#include "HtmlWriter.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
CommandLineArgs command_line_args;
|
|
||||||
command_line_args.Process(argc, argv);
|
|
||||||
|
|
||||||
if(command_line_args.GetNumberOfArgs() < 2)
|
|
||||||
{
|
|
||||||
std::cerr << "Expected a filepath argument" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
MarkdownParser parser;
|
|
||||||
const auto filepath = command_line_args.GetArg(1);
|
|
||||||
|
|
||||||
if(!std::filesystem::exists(filepath))
|
|
||||||
{
|
|
||||||
std::cerr << "Couldn't find file: " << filepath << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream md_file;
|
|
||||||
md_file.open(filepath, std::ifstream::in);
|
|
||||||
while(md_file.good())
|
|
||||||
{
|
|
||||||
std::string line;
|
|
||||||
std::getline(md_file, line);
|
|
||||||
parser.ProcessLine(line);
|
|
||||||
}
|
|
||||||
md_file.close();
|
|
||||||
|
|
||||||
auto html_document = parser.GetHtml();
|
|
||||||
HtmlWriter writer;
|
|
||||||
std::string html_string = writer.ToString(html_document);
|
|
||||||
std::ofstream out("/home/james/test.html");
|
|
||||||
out << html_string;
|
|
||||||
out.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -3,6 +3,8 @@ list(APPEND console_LIB_INCLUDES MainApplication.cpp)
|
||||||
add_library(console SHARED ${console_LIB_INCLUDES})
|
add_library(console SHARED ${console_LIB_INCLUDES})
|
||||||
|
|
||||||
target_include_directories(console PUBLIC
|
target_include_directories(console PUBLIC
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/core/"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/core/file_utilities"
|
||||||
"${PROJECT_SOURCE_DIR}/src/core/loggers"
|
"${PROJECT_SOURCE_DIR}/src/core/loggers"
|
||||||
"${PROJECT_SOURCE_DIR}/src/database"
|
"${PROJECT_SOURCE_DIR}/src/database"
|
||||||
"${PROJECT_SOURCE_DIR}/src/database/database_interfaces"
|
"${PROJECT_SOURCE_DIR}/src/database/database_interfaces"
|
||||||
|
@ -11,4 +13,5 @@ target_include_directories(console PUBLIC
|
||||||
"${PROJECT_SOURCE_DIR}/src/audio"
|
"${PROJECT_SOURCE_DIR}/src/audio"
|
||||||
"${PROJECT_SOURCE_DIR}/src/audio/midi"
|
"${PROJECT_SOURCE_DIR}/src/audio/midi"
|
||||||
"${PROJECT_SOURCE_DIR}/src/audio/audio_interfaces"
|
"${PROJECT_SOURCE_DIR}/src/audio/audio_interfaces"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/web"
|
||||||
)
|
)
|
|
@ -1,9 +1,13 @@
|
||||||
#include "MainApplication.h"
|
#include "MainApplication.h"
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "MidiReader.h"
|
#include "MidiReader.h"
|
||||||
|
#include "File.h"
|
||||||
|
#include "DocumentConverter.h"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
MainApplication::MainApplication()
|
MainApplication::MainApplication()
|
||||||
: mDatabaseManager()
|
: mDatabaseManager(),
|
||||||
|
mCommandLineArgs()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,20 +17,64 @@ MainApplication::~MainApplication()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainApplication::Initialize(const std::filesystem::path& workDir)
|
void MainApplication::Initialize(CommandLineArgsUPtr commandLineArgs)
|
||||||
{
|
{
|
||||||
FileLogger::GetInstance().SetWorkDirectory(workDir.string());
|
mCommandLineArgs = std::move(commandLineArgs);
|
||||||
|
std::string launch_path = mCommandLineArgs->GetLaunchPath().string();
|
||||||
|
|
||||||
|
FileLogger::GetInstance().SetWorkDirectory(launch_path);
|
||||||
FileLogger::GetInstance().Open();
|
FileLogger::GetInstance().Open();
|
||||||
MLOG_INFO("Launched");
|
MLOG_INFO("Launched");
|
||||||
|
|
||||||
mDatabaseManager = DatabaseManager::Create();
|
mDatabaseManager = DatabaseManager::Create();
|
||||||
mDatabaseManager->CreateDatabase(workDir.string() + "/database.db");
|
mDatabaseManager->CreateDatabase(launch_path + "/database.db");
|
||||||
|
|
||||||
mNetworkManager = NetworkManager::Create();
|
mNetworkManager = NetworkManager::Create();
|
||||||
|
|
||||||
mAudioManager = AudioManager::Create();
|
mAudioManager = AudioManager::Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainApplication::Run()
|
||||||
|
{
|
||||||
|
std::string program_type;
|
||||||
|
if(mCommandLineArgs->GetNumberOfArgs() > 1)
|
||||||
|
{
|
||||||
|
program_type = mCommandLineArgs->GetArg(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string input_path;
|
||||||
|
std::string output_path;
|
||||||
|
for(unsigned idx=1; idx<mCommandLineArgs->GetNumberOfArgs(); idx++)
|
||||||
|
{
|
||||||
|
auto arg = mCommandLineArgs->GetArg(idx);
|
||||||
|
if(arg == "-input" && mCommandLineArgs->GetNumberOfArgs() > idx+1)
|
||||||
|
{
|
||||||
|
input_path = mCommandLineArgs->GetArg(idx + 1);
|
||||||
|
}
|
||||||
|
else if(arg == "-output" && mCommandLineArgs->GetNumberOfArgs() > idx+1)
|
||||||
|
{
|
||||||
|
output_path = mCommandLineArgs->GetArg(idx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(program_type == "-server")
|
||||||
|
{
|
||||||
|
RunServer();
|
||||||
|
}
|
||||||
|
else if(program_type == "-audio")
|
||||||
|
{
|
||||||
|
PlayAudio();
|
||||||
|
}
|
||||||
|
else if(program_type == "-convert")
|
||||||
|
{
|
||||||
|
ConvertDocument(input_path, output_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Unknown program type: " + program_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainApplication::RunServer()
|
void MainApplication::RunServer()
|
||||||
{
|
{
|
||||||
mNetworkManager->RunHttpServer();
|
mNetworkManager->RunHttpServer();
|
||||||
|
@ -41,6 +89,15 @@ void MainApplication::PlayAudio()
|
||||||
mAudioManager->GetAudioInterface()->Play(device);
|
mAudioManager->GetAudioInterface()->Play(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainApplication::ConvertDocument(const std::string& inputPath, const std::string& outputPath)
|
||||||
|
{
|
||||||
|
auto input_file = File(std::filesystem::path(inputPath));
|
||||||
|
auto output_file = File(std::filesystem::path(outputPath));
|
||||||
|
MLOG_INFO("Converting: " + inputPath + " to " + outputPath);
|
||||||
|
DocumentConverter converter;
|
||||||
|
converter.Convert(&input_file, &output_file);
|
||||||
|
}
|
||||||
|
|
||||||
void MainApplication::ShutDown()
|
void MainApplication::ShutDown()
|
||||||
{
|
{
|
||||||
mDatabaseManager->OnShutDown();
|
mDatabaseManager->OnShutDown();
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
#include "FileLogger.h"
|
#include "FileLogger.h"
|
||||||
#include "DatabaseManager.h"
|
#include "DatabaseManager.h"
|
||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
|
#include "CommandLineArgs.h"
|
||||||
|
|
||||||
class MainApplication
|
class MainApplication
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
CommandLineArgsUPtr mCommandLineArgs;
|
||||||
DatabaseManagerPtr mDatabaseManager;
|
DatabaseManagerPtr mDatabaseManager;
|
||||||
NetworkManagerPtr mNetworkManager;
|
NetworkManagerPtr mNetworkManager;
|
||||||
AudioManagerPtr mAudioManager;
|
AudioManagerPtr mAudioManager;
|
||||||
|
@ -22,15 +24,20 @@ public:
|
||||||
|
|
||||||
~MainApplication();
|
~MainApplication();
|
||||||
|
|
||||||
void Initialize(const std::filesystem::path& workDir);
|
void Initialize(CommandLineArgsUPtr commandLineArgs);
|
||||||
|
|
||||||
void RunServer();
|
void Run();
|
||||||
|
|
||||||
void PlayAudio();
|
|
||||||
|
|
||||||
void ShutDown();
|
void ShutDown();
|
||||||
|
|
||||||
static std::shared_ptr<MainApplication> Create();
|
static std::shared_ptr<MainApplication> Create();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RunServer();
|
||||||
|
|
||||||
|
void PlayAudio();
|
||||||
|
|
||||||
|
void ConvertDocument(const std::string& inputPath, const std::string& outputPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
using MainApplicationPtr = std::shared_ptr<MainApplication>;
|
using MainApplicationPtr = std::shared_ptr<MainApplication>;
|
||||||
|
|
|
@ -4,6 +4,8 @@ list(APPEND core_LIB_INCLUDES
|
||||||
CommandLineArgs.cpp
|
CommandLineArgs.cpp
|
||||||
loggers/FileLogger.cpp
|
loggers/FileLogger.cpp
|
||||||
file_utilities/BinaryFile.cpp
|
file_utilities/BinaryFile.cpp
|
||||||
|
file_utilities/File.cpp
|
||||||
|
file_utilities/FileFormats.cpp
|
||||||
StringUtils.cpp
|
StringUtils.cpp
|
||||||
http/HttpResponse.cpp)
|
http/HttpResponse.cpp)
|
||||||
|
|
||||||
|
@ -12,4 +14,6 @@ add_library(core SHARED ${core_LIB_INCLUDES})
|
||||||
|
|
||||||
target_include_directories(core PUBLIC
|
target_include_directories(core PUBLIC
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/file_utilities"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/loggers"
|
||||||
)
|
)
|
|
@ -1,29 +1,45 @@
|
||||||
#include "CommandLineArgs.h"
|
#include "CommandLineArgs.h"
|
||||||
|
|
||||||
CommandLineArgs::CommandLineArgs()
|
CommandLineArgs::CommandLineArgs()
|
||||||
: mArugments()
|
: mArugments(),
|
||||||
|
mLaunchPath()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CommandLineArgs> CommandLineArgs::CreateUnique()
|
||||||
|
{
|
||||||
|
return std::make_unique<CommandLineArgs>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path CommandLineArgs::GetLaunchPath()
|
||||||
|
{
|
||||||
|
return mLaunchPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandLineArgs::RecordLaunchPath()
|
||||||
|
{
|
||||||
|
mLaunchPath = std::filesystem::current_path();
|
||||||
|
}
|
||||||
|
|
||||||
void CommandLineArgs::Process(int argc, char *argv[])
|
void CommandLineArgs::Process(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
for(int idx=0; idx<argc; idx++)
|
for(int idx=0; idx<argc; idx++)
|
||||||
{
|
{
|
||||||
mArugments.push_back(std::string(argv[idx]));
|
mArugments.push_back(std::string(argv[idx]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t CommandLineArgs::GetNumberOfArgs() const
|
std::size_t CommandLineArgs::GetNumberOfArgs() const
|
||||||
{
|
{
|
||||||
return mArugments.size();
|
return mArugments.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CommandLineArgs::GetArg(std::size_t index) const
|
std::string CommandLineArgs::GetArg(std::size_t index) const
|
||||||
{
|
{
|
||||||
if(index<mArugments.size())
|
if(index<mArugments.size())
|
||||||
{
|
{
|
||||||
return mArugments[index];
|
return mArugments[index];
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,28 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
class CommandLineArgs
|
class CommandLineArgs
|
||||||
{
|
{
|
||||||
std::vector<std::string> mArugments;
|
std::vector<std::string> mArugments;
|
||||||
|
std::filesystem::path mLaunchPath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CommandLineArgs();
|
CommandLineArgs();
|
||||||
|
|
||||||
void Process(int argc, char *argv[]);
|
static std::unique_ptr<CommandLineArgs> CreateUnique();
|
||||||
|
|
||||||
std::size_t GetNumberOfArgs() const;
|
void RecordLaunchPath();
|
||||||
|
|
||||||
std::string GetArg(std::size_t index) const;
|
std::filesystem::path GetLaunchPath();
|
||||||
|
|
||||||
|
void Process(int argc, char *argv[]);
|
||||||
|
|
||||||
|
std::size_t GetNumberOfArgs() const;
|
||||||
|
|
||||||
|
std::string GetArg(std::size_t index) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using CommandLineArgsUPtr = std::unique_ptr<CommandLineArgs>;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
bool StringUtils::IsAlphaNumeric(char c)
|
bool StringUtils::IsAlphaNumeric(char c)
|
||||||
{
|
{
|
||||||
|
@ -12,3 +13,11 @@ bool StringUtils::IsSpace(char c)
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
return std::isspace(c, loc);
|
return std::isspace(c, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string StringUtils::ToLower(const std::string& s)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
std::transform(s.begin(), s.end(), ret.begin(),
|
||||||
|
[](unsigned char c){ return std::tolower(c); });
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -16,4 +16,5 @@ public:
|
||||||
|
|
||||||
static bool IsAlphaNumeric(char c);
|
static bool IsAlphaNumeric(char c);
|
||||||
static bool IsSpace(char c);
|
static bool IsSpace(char c);
|
||||||
|
static std::string ToLower(const std::string& s);
|
||||||
};
|
};
|
||||||
|
|
68
src/core/file_utilities/File.cpp
Normal file
68
src/core/file_utilities/File.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include "File.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
File::File(std::filesystem::path path)
|
||||||
|
: mFullPath(path),
|
||||||
|
mInHandle(),
|
||||||
|
mOutHandle(),
|
||||||
|
mAccessMode(AccessMode::Read)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string File::GetExtension() const
|
||||||
|
{
|
||||||
|
return mFullPath.extension();
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::SetAccessMode(AccessMode mode)
|
||||||
|
{
|
||||||
|
mAccessMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream* File::GetInHandle() const
|
||||||
|
{
|
||||||
|
return mInHandle.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream* File::GetOutHandle() const
|
||||||
|
{
|
||||||
|
return mOutHandle.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::Open()
|
||||||
|
{
|
||||||
|
if(mAccessMode == AccessMode::Read)
|
||||||
|
{
|
||||||
|
mInHandle = std::make_unique<std::ifstream>();
|
||||||
|
mInHandle->open(mFullPath, std::ifstream::in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mOutHandle = std::make_unique<std::ofstream>();
|
||||||
|
mOutHandle->open(mFullPath, std::ofstream::out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::Close()
|
||||||
|
{
|
||||||
|
if(mOutHandle)
|
||||||
|
{
|
||||||
|
mOutHandle->close();
|
||||||
|
}
|
||||||
|
if(mInHandle)
|
||||||
|
{
|
||||||
|
mInHandle->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileFormat::Format File::InferFormat() const
|
||||||
|
{
|
||||||
|
const auto extension = GetExtension();
|
||||||
|
return FileFormat::InferFormat(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool File::PathExists() const
|
||||||
|
{
|
||||||
|
return std::filesystem::exists(mFullPath);
|
||||||
|
}
|
43
src/core/file_utilities/File.h
Normal file
43
src/core/file_utilities/File.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include "FileFormats.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class AccessMode{
|
||||||
|
Read,
|
||||||
|
Write
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::filesystem::path mFullPath;
|
||||||
|
std::unique_ptr<std::ifstream> mInHandle;
|
||||||
|
std::unique_ptr<std::ofstream> mOutHandle;
|
||||||
|
AccessMode mAccessMode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
File(std::filesystem::path fullPath);
|
||||||
|
|
||||||
|
std::string GetExtension() const;
|
||||||
|
|
||||||
|
FileFormat::Format InferFormat() const;
|
||||||
|
|
||||||
|
std::ifstream* GetInHandle() const;
|
||||||
|
|
||||||
|
std::ofstream* GetOutHandle() const;
|
||||||
|
|
||||||
|
bool PathExists() const;
|
||||||
|
|
||||||
|
void SetAccessMode(AccessMode mode);
|
||||||
|
|
||||||
|
void Open();
|
||||||
|
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
};
|
9
src/core/file_utilities/FileFormats.cpp
Normal file
9
src/core/file_utilities/FileFormats.cpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "FileFormats.h"
|
||||||
|
|
||||||
|
FileFormat::ExtensionMap FileFormat::mExtensions = []
|
||||||
|
{
|
||||||
|
ExtensionMap ret;
|
||||||
|
ret[Format::Markdown] = ".md";
|
||||||
|
ret[Format::Html] = ".html";
|
||||||
|
return ret;
|
||||||
|
}();
|
57
src/core/file_utilities/FileFormats.h
Normal file
57
src/core/file_utilities/FileFormats.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
class FileFormat{
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class Encoding{
|
||||||
|
Ascii,
|
||||||
|
UTF8,
|
||||||
|
Binary
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Format{
|
||||||
|
Html,
|
||||||
|
Xml,
|
||||||
|
Markdown,
|
||||||
|
Pdf,
|
||||||
|
Json,
|
||||||
|
Png,
|
||||||
|
Wav,
|
||||||
|
Midi,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
using ExtensionMap = std::map<Format, std::string>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ExtensionMap mExtensions;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool IsFormat(const std::string& extension, Format format)
|
||||||
|
{
|
||||||
|
return StringUtils::ToLower(extension) == mExtensions[format];
|
||||||
|
}
|
||||||
|
|
||||||
|
static Format InferFormat(const std::string& query)
|
||||||
|
{
|
||||||
|
for(const auto& extension : mExtensions)
|
||||||
|
{
|
||||||
|
if(extension.second == query)
|
||||||
|
{
|
||||||
|
return extension.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Format::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetExtension(Format format)
|
||||||
|
{
|
||||||
|
return mExtensions[format];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -6,14 +6,18 @@ list(APPEND web_LIB_INCLUDES
|
||||||
xml/XmlProlog.cpp
|
xml/XmlProlog.cpp
|
||||||
markdown/MarkdownParser.cpp
|
markdown/MarkdownParser.cpp
|
||||||
html/HtmlWriter.cpp
|
html/HtmlWriter.cpp
|
||||||
html/HtmlDocument.cpp)
|
html/HtmlDocument.cpp
|
||||||
|
DocumentConverter.cpp)
|
||||||
|
|
||||||
# add the executable
|
# add the executable
|
||||||
add_library(web SHARED ${web_LIB_INCLUDES})
|
add_library(web SHARED ${web_LIB_INCLUDES})
|
||||||
|
|
||||||
target_include_directories(web PUBLIC
|
target_include_directories(web PUBLIC
|
||||||
"${PROJECT_SOURCE_DIR}/src/core/"
|
"${PROJECT_SOURCE_DIR}/src/core/"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/core/loggers"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/core/file_utilities"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/xml"
|
"${CMAKE_CURRENT_SOURCE_DIR}/xml"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/html"
|
"${CMAKE_CURRENT_SOURCE_DIR}/html"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/markdown"
|
||||||
)
|
)
|
76
src/web/DocumentConverter.cpp
Normal file
76
src/web/DocumentConverter.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include "DocumentConverter.h"
|
||||||
|
#include "MarkdownParser.h"
|
||||||
|
#include "HtmlWriter.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
DocumentConverter::DocumentConverter()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentConverter::Convert(File* input, File* output)
|
||||||
|
{
|
||||||
|
if(!input || !output)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto input_format = input->InferFormat();
|
||||||
|
switch (input_format)
|
||||||
|
{
|
||||||
|
case FileFormat::Format::Markdown:
|
||||||
|
{
|
||||||
|
ConvertMarkdown(input, output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentConverter::ConvertMarkdown(File* input, File* output)
|
||||||
|
{
|
||||||
|
const auto output_format = output->InferFormat();
|
||||||
|
switch (output_format)
|
||||||
|
{
|
||||||
|
case FileFormat::Format::Html:
|
||||||
|
{
|
||||||
|
MarkdownToHtml(input, output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocumentConverter::MarkdownToHtml(File* input, File* output)
|
||||||
|
{
|
||||||
|
MLOG_INFO("Converting Markdown to Html");
|
||||||
|
input->SetAccessMode(File::AccessMode::Read);
|
||||||
|
input->Open();
|
||||||
|
|
||||||
|
MarkdownParser parser;
|
||||||
|
|
||||||
|
auto handle = input->GetInHandle();
|
||||||
|
while(handle->good())
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::getline(*handle, line);
|
||||||
|
parser.ProcessLine(line);
|
||||||
|
};
|
||||||
|
input->Close();
|
||||||
|
|
||||||
|
auto html_document = parser.GetHtml();
|
||||||
|
HtmlWriter writer;
|
||||||
|
std::string html_string = writer.ToString(html_document);
|
||||||
|
|
||||||
|
output->SetAccessMode(File::AccessMode::Write);
|
||||||
|
output->Open();
|
||||||
|
*(output->GetOutHandle()) << html_string;
|
||||||
|
output->Close();
|
||||||
|
}
|
16
src/web/DocumentConverter.h
Normal file
16
src/web/DocumentConverter.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "File.h"
|
||||||
|
|
||||||
|
class DocumentConverter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DocumentConverter();
|
||||||
|
|
||||||
|
void Convert(File* input, File* output);
|
||||||
|
|
||||||
|
void ConvertMarkdown(File* input, File* output);
|
||||||
|
|
||||||
|
void MarkdownToHtml(File* input, File* output);
|
||||||
|
};
|
|
@ -1,11 +1,12 @@
|
||||||
#include "HtmlElement.h"
|
#include "HtmlElement.h"
|
||||||
|
|
||||||
HtmlElement::HtmlElement()
|
HtmlElement::HtmlElement(const std::string& tagName)
|
||||||
|
: XmlElement(tagName)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<HtmlElement> HtmlElement::Create()
|
static std::unique_ptr<HtmlElement> HtmlElement::CreateUnique(const std::string& tagName)
|
||||||
{
|
{
|
||||||
return std::make_shared<HtmlElement>();
|
return std::make_unique<HtmlElement>(tagName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
class HtmlElement : public XmlElement
|
class HtmlElement : public XmlElement
|
||||||
{
|
{
|
||||||
HtmlElement();
|
HtmlElement(const std::string& tagName);
|
||||||
|
|
||||||
static std::shared_ptr<HtmlElement> Create();
|
static std::unique_ptr<HtmlElement> CreateUnique(const std::string& tagName);
|
||||||
};
|
};
|
||||||
|
|
||||||
using HtmlElementPtr = std::shared_ptr<HtmlElement>;
|
using HtmlElementUPtr = std::unique_ptr<HtmlElement>;
|
||||||
|
|
|
@ -2,28 +2,28 @@
|
||||||
|
|
||||||
|
|
||||||
XmlAttribute::XmlAttribute(const std::string& name)
|
XmlAttribute::XmlAttribute(const std::string& name)
|
||||||
: mName(name),
|
: mName(name),
|
||||||
mValue()
|
mValue()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<XmlAttribute> XmlAttribute::Create(const std::string& name)
|
XmlAttributeUPtr XmlAttribute::Create(const std::string& name)
|
||||||
{
|
{
|
||||||
return std::make_shared<XmlAttribute>(name);
|
return std::make_unique<XmlAttribute>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlAttribute::SetValue(const std::string& value)
|
void XmlAttribute::SetValue(const std::string& value)
|
||||||
{
|
{
|
||||||
mValue = value;
|
mValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XmlAttribute::GetName() const
|
std::string XmlAttribute::GetName() const
|
||||||
{
|
{
|
||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XmlAttribute::GetValue() const
|
std::string XmlAttribute::GetValue() const
|
||||||
{
|
{
|
||||||
return mValue;
|
return mValue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,22 @@
|
||||||
|
|
||||||
class XmlAttribute
|
class XmlAttribute
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
std::string mName;
|
std::string mName;
|
||||||
std::string mValue;
|
std::string mValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
XmlAttribute(const std::string& name);
|
XmlAttribute(const std::string& name);
|
||||||
|
|
||||||
static std::shared_ptr<XmlAttribute> Create(const std::string& name);
|
static std::unique_ptr<XmlAttribute> Create(const std::string& name);
|
||||||
|
|
||||||
void SetValue(const std::string& value);
|
void SetValue(const std::string& value);
|
||||||
|
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
|
|
||||||
std::string GetValue() const;
|
std::string GetValue() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
using XmlAttributePtr = std::shared_ptr<XmlAttribute>;
|
using XmlAttributePtr = std::shared_ptr<XmlAttribute>;
|
||||||
|
using XmlAttributeUPtr = std::unique_ptr<XmlAttribute>;
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
#include "XmlDocument.h"
|
#include "XmlDocument.h"
|
||||||
|
|
||||||
|
|
||||||
XmlDocument::XmlDocument()
|
XmlDocument::XmlDocument()
|
||||||
:mProlog(XmlProlog::Create("xml"))
|
:mProlog(XmlProlog::Create("xml"))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<XmlDocument> XmlDocument::Create()
|
XmlDocumentUPtr XmlDocument::Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<XmlDocument>();
|
return std::make_unique<XmlDocument>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlDocument::SetProlog(XmlPrologPtr prolog)
|
void XmlDocument::SetProlog(XmlPrologUPtr prolog)
|
||||||
{
|
{
|
||||||
mProlog = prolog;
|
mProlog = std::move(prolog);
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlPrologPtr XmlDocument::GetProlog() const
|
XmlProlog* XmlDocument::GetProlog() const
|
||||||
{
|
{
|
||||||
return mProlog;
|
return mProlog.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlDocument::SetRoot(XmlElementPtr root)
|
void XmlDocument::SetRoot(XmlElementUPtr root)
|
||||||
{
|
{
|
||||||
mRoot = root;
|
mRoot = std::move(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlElementPtr XmlDocument::GetRoot() const
|
XmlElement* XmlDocument::GetRoot() const
|
||||||
{
|
{
|
||||||
return mRoot;
|
return mRoot.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,21 +6,20 @@
|
||||||
|
|
||||||
class XmlDocument
|
class XmlDocument
|
||||||
{
|
{
|
||||||
XmlPrologPtr mProlog;
|
XmlPrologUPtr mProlog;
|
||||||
XmlElementPtr mRoot;
|
XmlElementUPtr mRoot;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XmlDocument();
|
XmlDocument();
|
||||||
|
|
||||||
static std::shared_ptr<XmlDocument> Create();
|
static std::unique_ptr<XmlDocument> Create();
|
||||||
|
|
||||||
void SetProlog(XmlPrologPtr prolog);
|
|
||||||
XmlPrologPtr GetProlog() const;
|
|
||||||
|
|
||||||
void SetRoot(XmlElementPtr root);
|
|
||||||
XmlElementPtr GetRoot() const;
|
|
||||||
|
|
||||||
|
XmlProlog* GetProlog() const;
|
||||||
|
XmlElement* GetRoot() const;
|
||||||
|
|
||||||
|
void SetProlog(XmlPrologUPtr prolog);
|
||||||
|
void SetRoot(XmlElementUPtr root);
|
||||||
};
|
};
|
||||||
|
|
||||||
using XmlDocumentPtr = std::shared_ptr<XmlDocument>;
|
using XmlDocumentPtr = std::shared_ptr<XmlDocument>;
|
||||||
|
using XmlDocumentUPtr = std::unique_ptr<XmlDocument>;
|
||||||
|
|
|
@ -2,60 +2,69 @@
|
||||||
|
|
||||||
|
|
||||||
XmlElement::XmlElement(const std::string& tagName)
|
XmlElement::XmlElement(const std::string& tagName)
|
||||||
: mTagName(tagName),
|
: mTagName(tagName),
|
||||||
mChildren()
|
mChildren()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<XmlElement> XmlElement::Create(const std::string& tagName)
|
XmlElementUPtr XmlElement::Create(const std::string& tagName)
|
||||||
{
|
{
|
||||||
return std::make_shared<XmlElement>(tagName);
|
return std::make_unique<XmlElement>(tagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlElement::AddChild(std::shared_ptr<XmlElement> child)
|
void XmlElement::SetTagName(const std::string& tagName)
|
||||||
{
|
{
|
||||||
mChildren.push_back(child);
|
mTagName = tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlElement::AddChild(XmlElementUPtr child)
|
||||||
|
{
|
||||||
|
mChildren.push_back(std::move(child));
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlElement::AddAttribute(XmlAttributeUPtr attribute)
|
||||||
|
{
|
||||||
|
mAttributes.push_back(std::move(attribute));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XmlElement::GetTagName() const
|
std::string XmlElement::GetTagName() const
|
||||||
{
|
{
|
||||||
return mTagName;
|
return mTagName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string XmlElement::GetText() const
|
std::string XmlElement::GetText() const
|
||||||
{
|
{
|
||||||
return mText;
|
return mText;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlElement::SetText(const std::string& text)
|
void XmlElement::SetText(const std::string& text)
|
||||||
{
|
{
|
||||||
mText = text;
|
mText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlElement::AddAttribute(XmlAttributePtr attribute)
|
XmlAttribute* XmlElement::GetAttribute(const std::string& attributeName) const
|
||||||
{
|
{
|
||||||
mAttributes.push_back(attribute);
|
for(const auto& attribute : mAttributes)
|
||||||
|
{
|
||||||
|
if(attribute->GetName() == attributeName)
|
||||||
|
{
|
||||||
|
return attribute.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlAttributePtr XmlElement::GetAttribute(const std::string& attributeName) const
|
XmlAttribute* XmlElement::GetAttribute(std::size_t index) const
|
||||||
{
|
{
|
||||||
for(const auto& attribute : mAttributes)
|
if(index < mAttributes.size())
|
||||||
{
|
{
|
||||||
if(attribute->GetName() == attributeName)
|
return mAttributes[index].get();
|
||||||
{
|
}
|
||||||
return attribute;
|
return nullptr;
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t XmlElement::GetNumAttributes() const
|
std::size_t XmlElement::GetNumAttributes() const
|
||||||
{
|
{
|
||||||
return mAttributes.size();
|
return mAttributes.size();
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<XmlAttributePtr> XmlElement::GetAttributes()
|
|
||||||
{
|
|
||||||
return mAttributes;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,26 +7,29 @@
|
||||||
class XmlElement
|
class XmlElement
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::string mTagName;
|
std::string mTagName;
|
||||||
std::vector<XmlAttributePtr> mAttributes;
|
std::vector<XmlAttributeUPtr> mAttributes;
|
||||||
std::vector<std::shared_ptr<XmlElement> > mChildren;
|
std::vector<std::unique_ptr<XmlElement> > mChildren;
|
||||||
std::string mText;
|
std::string mText;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XmlElement(const std::string& tagName);
|
XmlElement(const std::string& tagName);
|
||||||
virtual ~XmlElement() = default;
|
virtual ~XmlElement() = default;
|
||||||
|
|
||||||
static std::shared_ptr<XmlElement> Create(const std::string& tagName);
|
static std::unique_ptr<XmlElement> Create(const std::string& tagName);
|
||||||
|
|
||||||
void AddChild(std::shared_ptr<XmlElement> child);
|
void AddAttribute(XmlAttributeUPtr attribute);
|
||||||
std::string GetTagName() const;
|
void AddChild(std::unique_ptr<XmlElement> child);
|
||||||
std::string GetText() const;
|
|
||||||
void SetText(const std::string& text);
|
|
||||||
|
|
||||||
void AddAttribute(XmlAttributePtr attribute);
|
std::string GetTagName() const;
|
||||||
XmlAttributePtr GetAttribute(const std::string& attribute) const;
|
std::string GetText() const;
|
||||||
std::size_t GetNumAttributes() const;
|
XmlAttribute* GetAttribute(const std::string& attribute) const;
|
||||||
std::vector<XmlAttributePtr> GetAttributes();
|
XmlAttribute* GetAttribute(std::size_t index) const;
|
||||||
|
std::size_t GetNumAttributes() const;
|
||||||
|
|
||||||
|
void SetText(const std::string& text);
|
||||||
|
void SetTagName(const std::string& tagName);
|
||||||
};
|
};
|
||||||
|
|
||||||
using XmlElementPtr = std::shared_ptr<XmlElement>;
|
using XmlElementPtr = std::shared_ptr<XmlElement>;
|
||||||
|
using XmlElementUPtr = std::unique_ptr<XmlElement>;
|
||||||
|
|
|
@ -6,375 +6,376 @@ using LS = XmlParser::LineState;
|
||||||
using DS = XmlParser::DocumentState;
|
using DS = XmlParser::DocumentState;
|
||||||
|
|
||||||
XmlParser::XmlParser()
|
XmlParser::XmlParser()
|
||||||
: mDocument(XmlDocument::Create()),
|
: mDocument(XmlDocument::Create()),
|
||||||
mDocumentState(XmlParser::DocumentState::Await_Prolog),
|
mDocumentState(XmlParser::DocumentState::Await_Prolog),
|
||||||
mLineState(XmlParser::LineState::Await_Tag_Open)
|
mLineState(XmlParser::LineState::Await_Tag_Open),
|
||||||
|
mParentElement(nullptr),
|
||||||
|
mWorkingElement(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::ProcessLine(const std::string& input)
|
void XmlParser::ProcessLine(const std::string& input)
|
||||||
{
|
{
|
||||||
for(std::size_t idx; idx<input.size(); idx++)
|
for(std::size_t idx; idx<input.size(); idx++)
|
||||||
{
|
{
|
||||||
switch (input[idx])
|
switch (input[idx])
|
||||||
{
|
{
|
||||||
case StringUtils::LEFT_BRACKET:
|
case StringUtils::LEFT_BRACKET:
|
||||||
OnLeftBracket();
|
OnLeftBracket();
|
||||||
break;
|
break;
|
||||||
case StringUtils::RIGHT_BRACKET:
|
case StringUtils::RIGHT_BRACKET:
|
||||||
OnRightBracket();
|
OnRightBracket();
|
||||||
break;
|
break;
|
||||||
case StringUtils::QUESTION_MARK:
|
case StringUtils::QUESTION_MARK:
|
||||||
OnQuestionMark();
|
OnQuestionMark();
|
||||||
break;
|
break;
|
||||||
case StringUtils::FORWARD_SLASH:
|
case StringUtils::FORWARD_SLASH:
|
||||||
OnForwardSlash();
|
OnForwardSlash();
|
||||||
break;
|
break;
|
||||||
case StringUtils::EQUALS:
|
case StringUtils::EQUALS:
|
||||||
OnEquals();
|
OnEquals();
|
||||||
break;
|
break;
|
||||||
case StringUtils::DOUBLE_QUOTE:
|
case StringUtils::DOUBLE_QUOTE:
|
||||||
OnDoubleQuote();
|
OnDoubleQuote();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
OnChar(input[idx]);
|
OnChar(input[idx]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnChar(char c)
|
void XmlParser::OnChar(char c)
|
||||||
{
|
{
|
||||||
if(StringUtils::IsAlphaNumeric(c))
|
if(StringUtils::IsAlphaNumeric(c))
|
||||||
{
|
{
|
||||||
OnAlphaNumeric(c);
|
OnAlphaNumeric(c);
|
||||||
}
|
}
|
||||||
else if(StringUtils::IsSpace(c))
|
else if(StringUtils::IsSpace(c))
|
||||||
{
|
{
|
||||||
OnSpace(c);
|
OnSpace(c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnNonAlphaNumeric(c);
|
OnNonAlphaNumeric(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnAlphaNumeric(char c)
|
void XmlParser::OnAlphaNumeric(char c)
|
||||||
{
|
{
|
||||||
switch(mLineState)
|
switch(mLineState)
|
||||||
{
|
{
|
||||||
case LS::Await_Tag_Open:
|
case LS::Await_Tag_Open:
|
||||||
OnTextStart(c);
|
OnTextStart(c);
|
||||||
break;
|
break;
|
||||||
case LS::Await_Tag_Follower:
|
case LS::Await_Tag_Follower:
|
||||||
case LS::Await_Tag_Name:
|
case LS::Await_Tag_Name:
|
||||||
{
|
{
|
||||||
OnTagNameStart(c);
|
OnTagNameStart(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Tag_Name_End:
|
case LS::Await_Tag_Name_End:
|
||||||
{
|
{
|
||||||
mWorkingTagName.push_back(c);
|
mWorkingTagName.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Attribute_Name:
|
case LS::Await_Attribute_Name:
|
||||||
{
|
{
|
||||||
OnAttributeNameStart(c);
|
OnAttributeNameStart(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Attribute_Name_End:
|
case LS::Await_Attribute_Name_End:
|
||||||
{
|
{
|
||||||
mWorkingAttributeName.push_back(c);
|
mWorkingAttributeName.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Attribute_Value:
|
case LS::Await_Attribute_Value:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Attribute_Value_End:
|
case LS::Await_Attribute_Value_End:
|
||||||
{
|
{
|
||||||
mWorkingAttributeValue.push_back(c);
|
mWorkingAttributeValue.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Text_End:
|
case LS::Await_Text_End:
|
||||||
{
|
{
|
||||||
mWorkingText.push_back(c);
|
mWorkingText.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnNonAlphaNumeric(char c)
|
void XmlParser::OnNonAlphaNumeric(char c)
|
||||||
{
|
{
|
||||||
switch(mLineState)
|
switch(mLineState)
|
||||||
{
|
{
|
||||||
case LS::Await_Tag_Name_End:
|
case LS::Await_Tag_Name_End:
|
||||||
{
|
{
|
||||||
mWorkingTagName.push_back(c);
|
mWorkingTagName.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Attribute_Name_End:
|
case LS::Await_Attribute_Name_End:
|
||||||
{
|
{
|
||||||
mWorkingAttributeName.push_back(c);
|
mWorkingAttributeName.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Attribute_Value_End:
|
case LS::Await_Attribute_Value_End:
|
||||||
{
|
{
|
||||||
mWorkingAttributeValue.push_back(c);
|
mWorkingAttributeValue.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Text_End:
|
case LS::Await_Text_End:
|
||||||
{
|
{
|
||||||
mWorkingText.push_back(c);
|
mWorkingText.push_back(c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnSpace(char c)
|
void XmlParser::OnSpace(char c)
|
||||||
{
|
{
|
||||||
switch(mLineState)
|
switch(mLineState)
|
||||||
{
|
{
|
||||||
case LS::Await_Tag_Name_End:
|
case LS::Await_Tag_Name_End:
|
||||||
OnTagNameEnd();
|
OnTagNameEnd();
|
||||||
break;
|
break;
|
||||||
case LS::Await_Attribute_Name_End:
|
case LS::Await_Attribute_Name_End:
|
||||||
OnAttributeNameEnd();
|
OnAttributeNameEnd();
|
||||||
break;
|
break;
|
||||||
case LS::Await_Text_End:
|
case LS::Await_Text_End:
|
||||||
mWorkingText.push_back(c);
|
mWorkingText.push_back(c);
|
||||||
break;
|
break;
|
||||||
case LS::Await_Attribute_Value_End:
|
case LS::Await_Attribute_Value_End:
|
||||||
mWorkingAttributeValue.push_back(c);
|
mWorkingAttributeValue.push_back(c);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnLeftBracket()
|
void XmlParser::OnLeftBracket()
|
||||||
{
|
{
|
||||||
switch(mLineState)
|
switch(mLineState)
|
||||||
{
|
{
|
||||||
case LS::Await_Tag_Open:
|
case LS::Await_Tag_Open:
|
||||||
{
|
{
|
||||||
OnTagOpen();
|
OnTagOpen();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LS::Await_Text_End:
|
case LS::Await_Text_End:
|
||||||
{
|
{
|
||||||
OnTextEnd();
|
OnTextEnd();
|
||||||
OnTagOpen();
|
OnTagOpen();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
OnNonAlphaNumeric(StringUtils::LEFT_BRACKET);
|
OnNonAlphaNumeric(StringUtils::LEFT_BRACKET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnRightBracket()
|
void XmlParser::OnRightBracket()
|
||||||
{
|
{
|
||||||
switch(mLineState)
|
switch(mLineState)
|
||||||
{
|
{
|
||||||
case LS::Await_Tag_Name_End:
|
case LS::Await_Tag_Name_End:
|
||||||
case LS::Await_Attribute_Name:
|
case LS::Await_Attribute_Name:
|
||||||
case LS::Await_Attribute_Name_End:
|
case LS::Await_Attribute_Name_End:
|
||||||
case LS::Await_Attribute_Value:
|
case LS::Await_Attribute_Value:
|
||||||
{
|
{
|
||||||
OnTagClose();
|
OnTagClose();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
OnNonAlphaNumeric(StringUtils::RIGHT_BRACKET);
|
OnNonAlphaNumeric(StringUtils::RIGHT_BRACKET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnQuestionMark()
|
void XmlParser::OnQuestionMark()
|
||||||
{
|
{
|
||||||
if(mLineState == LS::Await_Tag_Follower)
|
if(mLineState == LS::Await_Tag_Follower)
|
||||||
{
|
{
|
||||||
if(mDocumentState == DS::Await_Prolog)
|
if(mDocumentState == DS::Await_Prolog)
|
||||||
{
|
{
|
||||||
OnStartProlog();
|
OnStartProlog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(mDocumentState != DS::Build_Prolog)
|
else if(mDocumentState != DS::Build_Prolog)
|
||||||
{
|
{
|
||||||
OnNonAlphaNumeric(StringUtils::QUESTION_MARK);
|
OnNonAlphaNumeric(StringUtils::QUESTION_MARK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnForwardSlash()
|
void XmlParser::OnForwardSlash()
|
||||||
{
|
{
|
||||||
if(mLineState == LS::Await_Tag_Follower)
|
if(mLineState == LS::Await_Tag_Follower)
|
||||||
{
|
{
|
||||||
if(mDocumentState == DS::Await_Element || mDocumentState == DS::Build_Element)
|
if(mDocumentState == DS::Await_Element || mDocumentState == DS::Build_Element)
|
||||||
{
|
{
|
||||||
mDocumentState = DS::Close_Element;
|
mDocumentState = DS::Close_Element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnEquals()
|
void XmlParser::OnEquals()
|
||||||
{
|
{
|
||||||
if(mLineState == LS::Await_Attribute_Name_End)
|
if(mLineState == LS::Await_Attribute_Name_End)
|
||||||
{
|
{
|
||||||
OnAttributeNameEnd();
|
OnAttributeNameEnd();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnNonAlphaNumeric(StringUtils::EQUALS);
|
OnNonAlphaNumeric(StringUtils::EQUALS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnDoubleQuote()
|
void XmlParser::OnDoubleQuote()
|
||||||
{
|
{
|
||||||
if(mLineState == LS::Await_Attribute_Value)
|
if(mLineState == LS::Await_Attribute_Value)
|
||||||
{
|
{
|
||||||
OnAttributeValueStart();
|
OnAttributeValueStart();
|
||||||
}
|
}
|
||||||
else if(mLineState == LS::Await_Attribute_Value_End)
|
else if(mLineState == LS::Await_Attribute_Value_End)
|
||||||
{
|
{
|
||||||
OnAttributeValueEnd();
|
OnAttributeValueEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnTagOpen()
|
void XmlParser::OnTagOpen()
|
||||||
{
|
{
|
||||||
mLineState = LS::Await_Tag_Follower;
|
mLineState = LS::Await_Tag_Follower;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnTagClose()
|
void XmlParser::OnTagClose()
|
||||||
{
|
{
|
||||||
if(mDocumentState == DS::Build_Prolog)
|
if(mDocumentState == DS::Build_Prolog)
|
||||||
{
|
{
|
||||||
onFinishProlog();
|
onFinishProlog();
|
||||||
}
|
}
|
||||||
else if(mDocumentState == DS::Build_Element)
|
else if(mDocumentState == DS::Build_Element)
|
||||||
{
|
{
|
||||||
if(mLineState == LS::Await_Tag_Name_End)
|
if(mLineState == LS::Await_Tag_Name_End)
|
||||||
{
|
{
|
||||||
OnTagNameEnd();
|
OnTagNameEnd();
|
||||||
}
|
}
|
||||||
onElementTagEnd();
|
onElementTagEnd();
|
||||||
}
|
}
|
||||||
else if(mDocumentState == DS::Close_Element)
|
else if(mDocumentState == DS::Close_Element)
|
||||||
{
|
{
|
||||||
if(mWorkingElement->GetTagName() == mWorkingTagName)
|
if(mWorkingElement->GetTagName() == mWorkingTagName)
|
||||||
{
|
{
|
||||||
mDocumentState = DS::Await_Element;
|
mDocumentState = DS::Await_Element;
|
||||||
mLineState = LS::Await_Tag_Open;
|
mLineState = LS::Await_Tag_Open;
|
||||||
if(mParentElement)
|
if(mParentElement)
|
||||||
{
|
{
|
||||||
mWorkingElement = mParentElement;
|
mWorkingElement = mParentElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnTextStart(char c)
|
void XmlParser::OnTextStart(char c)
|
||||||
{
|
{
|
||||||
mWorkingText = c;
|
mWorkingText = c;
|
||||||
mLineState = LS::Await_Text_End;
|
mLineState = LS::Await_Text_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnTextEnd()
|
void XmlParser::OnTextEnd()
|
||||||
{
|
{
|
||||||
mWorkingElement->SetText(mWorkingText);
|
mWorkingElement->SetText(mWorkingText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::onElementTagEnd()
|
void XmlParser::onElementTagEnd()
|
||||||
{
|
{
|
||||||
mDocumentState = DS::Await_Element;
|
mDocumentState = DS::Await_Element;
|
||||||
mLineState = LS::Await_Tag_Open;
|
mLineState = LS::Await_Tag_Open;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnTagNameStart(char c)
|
void XmlParser::OnTagNameStart(char c)
|
||||||
{
|
{
|
||||||
mWorkingTagName = c;
|
mWorkingTagName = c;
|
||||||
mLineState = LS::Await_Tag_Name_End;
|
mLineState = LS::Await_Tag_Name_End;
|
||||||
if(mDocumentState != DS::Build_Prolog && mDocumentState != DS::Close_Element)
|
if(mDocumentState != DS::Build_Prolog && mDocumentState != DS::Close_Element)
|
||||||
{
|
{
|
||||||
mDocumentState = DS::Build_Element;
|
mDocumentState = DS::Build_Element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnTagNameEnd()
|
void XmlParser::OnTagNameEnd()
|
||||||
{
|
{
|
||||||
if(mDocumentState == DS::Build_Prolog)
|
if(mDocumentState == DS::Build_Prolog)
|
||||||
{
|
{
|
||||||
mWorkingProlog = XmlProlog::Create(mWorkingTagName);
|
mDocument->GetProlog()->SetTagName(mWorkingTagName);
|
||||||
mLineState = LS::Await_Attribute_Name;
|
mLineState = LS::Await_Attribute_Name;
|
||||||
}
|
}
|
||||||
else if(mDocumentState == DS::Build_Element)
|
else if(mDocumentState == DS::Build_Element)
|
||||||
{
|
{
|
||||||
auto new_element = XmlElement::Create(mWorkingTagName);
|
auto new_element = XmlElement::Create(mWorkingTagName);
|
||||||
mParentElement = mWorkingElement;
|
|
||||||
mWorkingElement = new_element;
|
|
||||||
|
|
||||||
if(!mDocument->GetRoot())
|
mParentElement = mWorkingElement;
|
||||||
{
|
mWorkingElement = new_element.get();
|
||||||
mDocument->SetRoot(mWorkingElement);
|
|
||||||
}
|
if(!mDocument->GetRoot())
|
||||||
mLineState = LS::Await_Attribute_Name;
|
{
|
||||||
}
|
mDocument->SetRoot(std::move(new_element));
|
||||||
|
}
|
||||||
|
mLineState = LS::Await_Attribute_Name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnAttributeNameStart(char c)
|
void XmlParser::OnAttributeNameStart(char c)
|
||||||
{
|
{
|
||||||
mWorkingAttributeName = c;
|
mWorkingAttributeName = c;
|
||||||
mLineState = LS::Await_Attribute_Name_End;
|
mLineState = LS::Await_Attribute_Name_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnAttributeNameEnd()
|
void XmlParser::OnAttributeNameEnd()
|
||||||
{
|
{
|
||||||
mWorkingAttribute = XmlAttribute::Create(mWorkingAttributeName);
|
auto attribute = XmlAttribute::Create(mWorkingAttributeName);
|
||||||
if(mDocumentState == DS::Build_Prolog)
|
if(mDocumentState == DS::Build_Prolog)
|
||||||
{
|
{
|
||||||
mWorkingProlog->AddAttribute(mWorkingAttribute);
|
mDocument->GetProlog()->AddAttribute(std::move(attribute));
|
||||||
}
|
}
|
||||||
else if(mDocumentState == DS::Build_Element)
|
else if(mDocumentState == DS::Build_Element)
|
||||||
{
|
{
|
||||||
mWorkingElement->AddAttribute(mWorkingAttribute);
|
mWorkingElement->AddAttribute(std::move(attribute));
|
||||||
}
|
}
|
||||||
mLineState = LS::Await_Attribute_Value;
|
mLineState = LS::Await_Attribute_Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnAttributeValueStart()
|
void XmlParser::OnAttributeValueStart()
|
||||||
{
|
{
|
||||||
mWorkingAttributeValue = "";
|
mWorkingAttributeValue = "";
|
||||||
mLineState = LS::Await_Attribute_Value_End;
|
mLineState = LS::Await_Attribute_Value_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnAttributeValueEnd()
|
void XmlParser::OnAttributeValueEnd()
|
||||||
{
|
{
|
||||||
mWorkingAttribute->SetValue(mWorkingAttributeValue);
|
mWorkingElement->GetAttribute(mWorkingAttributeName)->SetValue(mWorkingAttributeValue);
|
||||||
mLineState = LS::Await_Attribute_Name;
|
mLineState = LS::Await_Attribute_Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::OnStartProlog()
|
void XmlParser::OnStartProlog()
|
||||||
{
|
{
|
||||||
mDocumentState = DS::Build_Prolog;
|
mDocumentState = DS::Build_Prolog;
|
||||||
mLineState = LS::Await_Tag_Name_End;
|
mLineState = LS::Await_Tag_Name_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlParser::onFinishProlog()
|
void XmlParser::onFinishProlog()
|
||||||
{
|
{
|
||||||
mWorkingProlog->Update();
|
mDocument->GetProlog()->Update();
|
||||||
mDocument->SetProlog(mWorkingProlog);
|
mDocumentState = DS::Await_Element;
|
||||||
mWorkingProlog = nullptr;
|
mLineState = LS::Await_Tag_Open;
|
||||||
mDocumentState = DS::Await_Element;
|
|
||||||
mLineState = LS::Await_Tag_Open;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlDocumentPtr XmlParser::GetDocument() const
|
XmlDocumentPtr XmlParser::GetDocument() const
|
||||||
{
|
{
|
||||||
return mDocument;
|
return mDocument;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,97 +6,95 @@
|
||||||
class XmlParser
|
class XmlParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class DocumentState
|
enum class DocumentState
|
||||||
{
|
{
|
||||||
Await_Prolog,
|
Await_Prolog,
|
||||||
Build_Prolog,
|
Build_Prolog,
|
||||||
Await_Element,
|
Await_Element,
|
||||||
Build_Element,
|
Build_Element,
|
||||||
Close_Element
|
Close_Element
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class LineState
|
enum class LineState
|
||||||
{
|
{
|
||||||
Await_Tag_Open,
|
Await_Tag_Open,
|
||||||
Await_Tag_Follower,
|
Await_Tag_Follower,
|
||||||
Await_Tag_Name,
|
Await_Tag_Name,
|
||||||
Await_Tag_Name_End,
|
Await_Tag_Name_End,
|
||||||
Await_Attribute_Name,
|
Await_Attribute_Name,
|
||||||
Await_Attribute_Name_End,
|
Await_Attribute_Name_End,
|
||||||
Await_Attribute_Value,
|
Await_Attribute_Value,
|
||||||
Await_Attribute_Value_End,
|
Await_Attribute_Value_End,
|
||||||
Await_Text_End
|
Await_Text_End
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DocumentState mDocumentState;
|
DocumentState mDocumentState;
|
||||||
LineState mLineState;
|
LineState mLineState;
|
||||||
XmlDocumentPtr mDocument;
|
XmlDocumentPtr mDocument;
|
||||||
XmlPrologPtr mWorkingProlog;
|
XmlElement* mParentElement;
|
||||||
XmlElementPtr mParentElement;
|
XmlElement* mWorkingElement;
|
||||||
XmlElementPtr mWorkingElement;
|
std::string mWorkingAttributeName;
|
||||||
XmlAttributePtr mWorkingAttribute;
|
std::string mWorkingTagName;
|
||||||
std::string mWorkingAttributeName;
|
std::string mWorkingAttributeValue;
|
||||||
std::string mWorkingTagName;
|
std::string mWorkingText;
|
||||||
std::string mWorkingAttributeValue;
|
|
||||||
std::string mWorkingText;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
XmlParser();
|
XmlParser();
|
||||||
|
|
||||||
void ProcessLine(const std::string& input);
|
void ProcessLine(const std::string& input);
|
||||||
|
|
||||||
XmlDocumentPtr GetDocument() const;
|
XmlDocumentPtr GetDocument() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void OnLeftBracket();
|
void OnLeftBracket();
|
||||||
|
|
||||||
void OnRightBracket();
|
void OnRightBracket();
|
||||||
|
|
||||||
void OnQuestionMark();
|
void OnQuestionMark();
|
||||||
|
|
||||||
void OnForwardSlash();
|
void OnForwardSlash();
|
||||||
|
|
||||||
void OnChar(char c);
|
void OnChar(char c);
|
||||||
|
|
||||||
void OnSpace(char c);
|
void OnSpace(char c);
|
||||||
|
|
||||||
void OnAlphaNumeric(char c);
|
void OnAlphaNumeric(char c);
|
||||||
|
|
||||||
void OnNonAlphaNumeric(char c);
|
void OnNonAlphaNumeric(char c);
|
||||||
|
|
||||||
void OnEquals();
|
void OnEquals();
|
||||||
|
|
||||||
void OnDoubleQuote();
|
void OnDoubleQuote();
|
||||||
|
|
||||||
void OnTagOpen();
|
void OnTagOpen();
|
||||||
|
|
||||||
void OnTagNameStart(char c);
|
void OnTagNameStart(char c);
|
||||||
|
|
||||||
void OnTagNameEnd();
|
void OnTagNameEnd();
|
||||||
|
|
||||||
void OnTagClose();
|
void OnTagClose();
|
||||||
|
|
||||||
void OnTextStart(char c);
|
void OnTextStart(char c);
|
||||||
|
|
||||||
void OnTextEnd();
|
void OnTextEnd();
|
||||||
|
|
||||||
void OnAttributeNameStart(char c);
|
void OnAttributeNameStart(char c);
|
||||||
|
|
||||||
void OnAttributeNameEnd();
|
void OnAttributeNameEnd();
|
||||||
|
|
||||||
void OnAttributeValueStart();
|
void OnAttributeValueStart();
|
||||||
|
|
||||||
void OnAttributeValueEnd();
|
void OnAttributeValueEnd();
|
||||||
|
|
||||||
void OnPrologId();
|
void OnPrologId();
|
||||||
|
|
||||||
void OnStartProlog();
|
void OnStartProlog();
|
||||||
|
|
||||||
void onFinishProlog();
|
void onFinishProlog();
|
||||||
|
|
||||||
void onElementTagEnd();
|
void onElementTagEnd();
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,53 +2,53 @@
|
||||||
|
|
||||||
|
|
||||||
XmlProlog::XmlProlog(const std::string& tagName)
|
XmlProlog::XmlProlog(const std::string& tagName)
|
||||||
: XmlElement(tagName),
|
: XmlElement(tagName),
|
||||||
mVersion(XmlProlog::Version::V1_0),
|
mVersion(XmlProlog::Version::V1_0),
|
||||||
mEncoding(XmlProlog::Encoding::UTF8)
|
mEncoding(XmlProlog::Encoding::UTF8)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<XmlProlog> XmlProlog::Create(const std::string& tagName)
|
XmlPrologUPtr XmlProlog::Create(const std::string& tagName)
|
||||||
{
|
{
|
||||||
return std::make_shared<XmlProlog>(tagName);
|
return std::make_unique<XmlProlog>(tagName);
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlProlog::Encoding XmlProlog::GetEncoding() const
|
XmlProlog::Encoding XmlProlog::GetEncoding() const
|
||||||
{
|
{
|
||||||
return mEncoding;
|
return mEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlProlog::Version XmlProlog::GetVersion() const
|
XmlProlog::Version XmlProlog::GetVersion() const
|
||||||
{
|
{
|
||||||
return mVersion;
|
return mVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlProlog::SetEncoding(const std::string& encoding)
|
void XmlProlog::SetEncoding(const std::string& encoding)
|
||||||
{
|
{
|
||||||
if(encoding == "UTF-8")
|
if(encoding == "UTF-8")
|
||||||
{
|
{
|
||||||
mEncoding == XmlProlog::Encoding::UTF8;
|
mEncoding == XmlProlog::Encoding::UTF8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlProlog::SetVersion(const std::string& version)
|
void XmlProlog::SetVersion(const std::string& version)
|
||||||
{
|
{
|
||||||
if(version == "1.0")
|
if(version == "1.0")
|
||||||
{
|
{
|
||||||
mVersion == XmlProlog::Version::V1_0;
|
mVersion == XmlProlog::Version::V1_0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlProlog::Update()
|
void XmlProlog::Update()
|
||||||
{
|
{
|
||||||
if(const auto version = GetAttribute("version"))
|
if(const auto version = GetAttribute("version"))
|
||||||
{
|
{
|
||||||
SetVersion(version->GetValue());
|
SetVersion(version->GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(const auto encoding = GetAttribute("encoding"))
|
if(const auto encoding = GetAttribute("encoding"))
|
||||||
{
|
{
|
||||||
SetEncoding(encoding->GetValue());
|
SetEncoding(encoding->GetValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,30 +7,31 @@ class XmlProlog : public XmlElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum class Version{
|
enum class Version{
|
||||||
V1_0
|
V1_0
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Encoding{
|
enum class Encoding{
|
||||||
UTF8
|
UTF8
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Version mVersion;
|
Version mVersion;
|
||||||
Encoding mEncoding;
|
Encoding mEncoding;
|
||||||
std::string mTagName;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XmlProlog(const std::string& tagName);
|
XmlProlog(const std::string& tagName);
|
||||||
|
|
||||||
static std::shared_ptr<XmlProlog> Create(const std::string& tagName);
|
static std::unique_ptr<XmlProlog> Create(const std::string& tagName);
|
||||||
void Update();
|
|
||||||
Encoding GetEncoding() const;
|
|
||||||
Version GetVersion() const;
|
|
||||||
|
|
||||||
void SetEncoding(const std::string& encoding);
|
Encoding GetEncoding() const;
|
||||||
void SetVersion(const std::string& version);
|
Version GetVersion() const;
|
||||||
|
|
||||||
|
void SetEncoding(const std::string& encoding);
|
||||||
|
void SetVersion(const std::string& version);
|
||||||
|
void Update();
|
||||||
};
|
};
|
||||||
|
|
||||||
using XmlPrologPtr = std::shared_ptr<XmlProlog>;
|
using XmlPrologPtr = std::shared_ptr<XmlProlog>;
|
||||||
|
using XmlPrologUPtr = std::unique_ptr<XmlProlog>;
|
||||||
|
|
Loading…
Reference in a new issue