First
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
#pragma once
|
||||
|
||||
#include "tl/detail/prologue.h"
|
||||
#include <tl/vector.h>
|
||||
#include <tl/fixed_vector.h>
|
||||
#include "tl/string.h"
|
||||
#include "tl/detail/path_system_utils.h"
|
||||
#include "tl/toolchain.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TL_DECLARE_STRING_LITERAL(struct_name, cstr_value)\
|
||||
struct struct_name\
|
||||
{\
|
||||
static const char* value() noexcept\
|
||||
{\
|
||||
return cstr_value;\
|
||||
}\
|
||||
};
|
||||
|
||||
#define TL_DECLARE_STRING_VECTOR(struct_name, ...)\
|
||||
struct struct_name\
|
||||
{\
|
||||
static const tl::vector<const char*>& vector() noexcept\
|
||||
{\
|
||||
static tl::vector<const char*> s_vector {__VA_ARGS__};\
|
||||
return s_vector;\
|
||||
}\
|
||||
};
|
||||
|
||||
#define TL_DECLARE_TLSTRING_VECTOR(struct_name, ...)\
|
||||
struct struct_name\
|
||||
{\
|
||||
static const tl::vector<tl::string>& vector() noexcept\
|
||||
{\
|
||||
static tl::vector<tl::string> s_vector {__VA_ARGS__};\
|
||||
return s_vector;\
|
||||
}\
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace tl
|
||||
{
|
||||
namespace path_system
|
||||
{
|
||||
TL_DECLARE_STRING_LITERAL(back_t, "..");
|
||||
TL_DECLARE_STRING_LITERAL(current_t, ".");
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
struct path_systems
|
||||
{
|
||||
template<typename T>
|
||||
static T format_absolute(int type_id, const tl::vector<string>& members) noexcept;
|
||||
static void parse_absolute(tl::vector<string>& o_elements, int type_id, const char* path, size_t size) noexcept;
|
||||
static void parse_relative(tl::vector<string>& o_elements, const char* path, size_t size) noexcept;
|
||||
static int deduce_system_type(const char* path, size_t size) noexcept;
|
||||
static bool validate_abs_path(int type_id, const tl::vector<string>& members) noexcept;
|
||||
static const tl::vector<tl::vector<const char*> >& get_all_parse_separators() noexcept;
|
||||
|
||||
template <typename TypeToCheck>
|
||||
static bool is(int type_id) noexcept;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename custom_implementation, typename parse_separators, typename format_separator>
|
||||
struct custom_path_system : public custom_implementation, public detail::path_system::base_path_system<parse_separators, format_separator>
|
||||
{
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename root_tag, typename parse_separators, typename format_separator>
|
||||
struct simple_path_system : public detail::path_system::base_path_system<parse_separators, format_separator>
|
||||
{
|
||||
template<typename T>
|
||||
static T format_absolute(const tl::vector<string>& members) noexcept;
|
||||
static void parse_absolute(tl::vector<string>& o_elements, const char* path, size_t size) noexcept;
|
||||
static bool validate_abs_path(const tl::vector<string>& members) noexcept;
|
||||
static bool match(const char* path, size_t size) noexcept;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace tl
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
template<typename T>
|
||||
T path_systems<Systems...>::format_absolute(int type_id, const tl::vector<string>& members) noexcept
|
||||
{
|
||||
TL_PLAIN_ASSERT(type_id >= 0, "Error: trying to format an unknown path system type.");
|
||||
return detail::path_system::path_system_getter<0, Systems...>::template format_absolute<T>(type_id, members);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
void path_systems<Systems...>::parse_absolute(tl::vector<string>& o_elements, int type_id, const char* path, size_t size) noexcept
|
||||
{
|
||||
TL_PLAIN_ASSERT(type_id >= 0, "Error: trying to parse an unknown path system type.");
|
||||
detail::path_system::path_system_getter<0, Systems...>::parse_absolute(o_elements, type_id, path, size);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
int path_systems<Systems...>::deduce_system_type(const char* path, size_t size) noexcept
|
||||
{
|
||||
return detail::path_system::path_system_getter<0, Systems...>::deduce_system_type(path, size);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
bool path_systems<Systems...>::validate_abs_path(int type_id, const tl::vector<string>& members) noexcept
|
||||
{
|
||||
TL_PLAIN_ASSERT(type_id >= 0, "Error: trying to validate an unknown path system type.");
|
||||
return detail::path_system::path_system_getter<0, Systems...>::validate_abs_path(type_id, members);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
const tl::vector<tl::vector<const char*> >& path_systems<Systems...>::get_all_parse_separators() noexcept
|
||||
{
|
||||
static tl::vector<tl::vector<const char*>> s_all_separators_cache = detail::path_system::path_systems_getter<Systems...>::get_all_parse_separators();
|
||||
return s_all_separators_cache;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
void path_systems<Systems...>::parse_relative(tl::vector<string>& o_elements, const char* path, size_t size) noexcept
|
||||
{
|
||||
const tl::vector<tl::vector<const char*> >& all_separators = get_all_parse_separators();
|
||||
const size_t path_system_count = all_separators.size();
|
||||
|
||||
eastl::fixed_vector<string, 512> elements;
|
||||
|
||||
int systemIndex = -1;
|
||||
|
||||
// parse the path
|
||||
const char* start = path;
|
||||
const char* const end = start + size;
|
||||
while (start < end)
|
||||
{
|
||||
bool matchedSeparator = false;
|
||||
|
||||
const char* sepStart = start;
|
||||
const char* sepEnd = nullptr;
|
||||
|
||||
// system hasn't been deduced yet
|
||||
if (systemIndex == -1)
|
||||
{
|
||||
for (size_t s = 0; s < path_system_count; ++s)
|
||||
{
|
||||
const tl::vector<const char*>& separators = all_separators[s];
|
||||
const char* const* separators_begin = separators.data();
|
||||
const char* const* separators_end = separators_begin + separators.size();
|
||||
|
||||
matchedSeparator = detail::path_system::find_next_separator(separators_begin, separators_end, sepStart, end, sepEnd);
|
||||
if (matchedSeparator)
|
||||
{
|
||||
systemIndex = (int)s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// path system already deduced
|
||||
else
|
||||
{
|
||||
const tl::vector<const char*>& separators = all_separators[systemIndex];
|
||||
const char* const* separators_begin = separators.data();
|
||||
const char* const* separators_end = separators_begin + separators.size();
|
||||
|
||||
matchedSeparator = detail::path_system::find_next_separator(separators_begin, separators_end, sepStart, end, sepEnd);
|
||||
}
|
||||
|
||||
// if has matched separator
|
||||
if (matchedSeparator)
|
||||
{
|
||||
if (sepStart > start)
|
||||
elements.emplace_back(start, sepStart);
|
||||
|
||||
start = sepEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
//get the remainder of the string
|
||||
if (*start != 0)
|
||||
elements.emplace_back(start);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//now reserve the space and move into final place
|
||||
o_elements.reserve(o_elements.size() + elements.size());
|
||||
for (string& element : elements)
|
||||
o_elements.emplace_back(std::move(element));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename... Systems>
|
||||
template <typename TypeToCheck>
|
||||
bool path_systems<Systems...>::is(int type_id) noexcept
|
||||
{
|
||||
return detail::path_system::path_system_type_checker<0, TypeToCheck, Systems...>::is(type_id);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename root_tag, typename parse_separators, typename format_separator>
|
||||
template<typename T>
|
||||
T simple_path_system<root_tag, parse_separators, format_separator>::format_absolute(const tl::vector<string>& members) noexcept
|
||||
{
|
||||
if constexpr (is_same_v<T, string>)
|
||||
{
|
||||
eastl::string buffer;
|
||||
buffer.reserve(8192);
|
||||
detail::path_system::simple_format_abs_path(buffer, members, root_tag::value(), format_separator::value());
|
||||
return string(buffer.data(), buffer.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
T str;
|
||||
detail::path_system::simple_format_abs_path(str, members, root_tag::value(), format_separator::value());
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename root_tag, typename parse_separators, typename format_separator>
|
||||
void simple_path_system<root_tag, parse_separators, format_separator>::parse_absolute(tl::vector<string>& o_elements, const char* path, size_t size) noexcept
|
||||
{
|
||||
detail::path_system::simple_parse_path(o_elements, path, size, root_tag::value(), parse_separators::vector());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename root_tag, typename parse_separators, typename format_separator>
|
||||
bool simple_path_system<root_tag, parse_separators, format_separator>::match(const char* path, size_t size) noexcept
|
||||
{
|
||||
return detail::path_system::simple_match_prefix(path, size, root_tag::value());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename root_tag, typename parse_separators, typename format_separator>
|
||||
bool simple_path_system<root_tag, parse_separators, format_separator>::validate_abs_path(const tl::vector<string>& /*members*/) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user