diff options
Diffstat (limited to 'include/openvic-dataloader/csv')
-rw-r--r-- | include/openvic-dataloader/csv/LineObject.hpp | 84 | ||||
-rw-r--r-- | include/openvic-dataloader/csv/Parser.hpp | 42 |
2 files changed, 126 insertions, 0 deletions
diff --git a/include/openvic-dataloader/csv/LineObject.hpp b/include/openvic-dataloader/csv/LineObject.hpp new file mode 100644 index 0000000..0494ffb --- /dev/null +++ b/include/openvic-dataloader/csv/LineObject.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include <cstddef> +#include <cstdint> +#include <functional> +#include <initializer_list> +#include <optional> +#include <string> +#include <string_view> +#include <tuple> +#include <vector> + +namespace ovdl::csv { + /// LineObject should be able to recognize the differences between: + /// Input -> Indexes == "" + /// ;;a;b;c;; -> 0,1,5,6+ == "" + /// a;b;c -> 3+ == "" + /// a;;b;c;; -> 1,4,5+ == "" + /// a;b;;c; -> 2,4+ == "" + /// a;b;c;; -> 3,4+ == "" + /// a;b;c; -> 3+ == "" + /// ;a;b;c -> 0,4+ == "" + /// + /// If this is incorrect, please report an issue. + class LineObject final : public std::vector<std::tuple<std::uint32_t, std::string>> { + public: + // Stored position of value + using position_type = std::uint32_t; + // Value + using inner_value_type = std::string; + using container_type = std::vector<std::tuple<position_type, inner_value_type>>; + + constexpr LineObject() = default; + constexpr LineObject(LineObject&) = default; + constexpr LineObject(LineObject&&) = default; + constexpr LineObject(const LineObject&) = default; + + constexpr LineObject& operator=(const LineObject& other) = default; + constexpr LineObject& operator=(LineObject&& other) = default; + + constexpr ~LineObject() = default; + + constexpr LineObject(std::initializer_list<value_type> pos_and_val) : container_type(pos_and_val) { + } + + constexpr LineObject(position_type prefix_end, std::initializer_list<value_type> pos_and_val, position_type suffix_end = 0) + : container_type(pos_and_val), + _prefix_end(prefix_end), + _suffix_end(suffix_end) { + } + + /// Special Functionality + /// Retrieves value, produces "" for empty values + constexpr std::string_view get_value_for(std::size_t position) const { + if (position <= _prefix_end || position >= _suffix_end) return ""; + for (const auto& [pos, val] : *this) { + if (pos == position) return val; + } + return ""; + } + /// Tries to retrieve reference, produces nullopt for empty values + constexpr std::optional<const std::reference_wrapper<const std::string>> try_get_string_at(std::size_t position) const { + if (position <= _prefix_end || position > _suffix_end) return std::nullopt; + for (const auto& [pos, val] : *this) { + if (pos == position) return std::cref(val); + } + return std::nullopt; + } + + constexpr position_type prefix_end() const { return _prefix_end; } + constexpr void set_prefix_end(position_type value) { _prefix_end = value; } + + constexpr position_type suffix_end() const { return _suffix_end; } + constexpr void set_suffix_end(position_type value) { _suffix_end = value; } + + constexpr std::size_t value_count() const { return _suffix_end; } + + private: + // Should be position of first valid value on line + position_type _prefix_end; + // Should be position after last value or position after last seperator + position_type _suffix_end; + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/csv/Parser.hpp b/include/openvic-dataloader/csv/Parser.hpp new file mode 100644 index 0000000..3497864 --- /dev/null +++ b/include/openvic-dataloader/csv/Parser.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include <openvic-dataloader/csv/LineObject.hpp> +#include <openvic-dataloader/detail/BasicParser.hpp> + +namespace ovdl::csv { + class Parser final : public detail::BasicParser { + public: + Parser(); + + static Parser from_buffer(const char* data, std::size_t size); + static Parser from_buffer(const char* start, const char* end); + static Parser from_string(const std::string_view string); + static Parser from_file(const char* path); + static Parser from_file(const std::filesystem::path& path); + + constexpr Parser& load_from_buffer(const char* data, std::size_t size); + constexpr Parser& load_from_buffer(const char* start, const char* end); + constexpr Parser& load_from_string(const std::string_view string); + constexpr Parser& load_from_file(const char* path); + Parser& load_from_file(const std::filesystem::path& path); + + constexpr Parser& load_from_file(const detail::Has_c_str auto& path); + + bool parse_csv(); + + const std::vector<csv::LineObject> get_lines() const; + + Parser(Parser&&); + Parser& operator=(Parser&&); + + ~Parser(); + + private: + class BufferHandler; + std::unique_ptr<BufferHandler> _buffer_handler; + std::vector<csv::LineObject> _lines; + + template<typename... Args> + constexpr void _run_load_func(detail::LoadCallback<BufferHandler, Args...> auto func, Args... args); + }; +}
\ No newline at end of file |