Line | Branch | Exec | Source |
---|---|---|---|
1 | // This file is part of INSTINCT, the INS Toolkit for Integrated | ||
2 | // Navigation Concepts and Training by the Institute of Navigation of | ||
3 | // the University of Stuttgart, Germany. | ||
4 | // | ||
5 | // This Source Code Form is subject to the terms of the Mozilla Public | ||
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
7 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
8 | |||
9 | /// @file FileReader.hpp | ||
10 | /// @brief Abstract File Reader class | ||
11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
12 | /// @date 2020-03-16 | ||
13 | |||
14 | #pragma once | ||
15 | |||
16 | #include <string> | ||
17 | #include <vector> | ||
18 | #include <fstream> | ||
19 | #include <filesystem> | ||
20 | |||
21 | #include "Navigation/Time/InsTime.hpp" | ||
22 | |||
23 | #include <fmt/ostream.h> | ||
24 | #include <nlohmann/json.hpp> | ||
25 | using json = nlohmann::json; ///< json namespace | ||
26 | |||
27 | namespace NAV | ||
28 | { | ||
29 | /// Abstract File Reader class | ||
30 | class FileReader | ||
31 | { | ||
32 | public: | ||
33 | /// File Type Enumeration | ||
34 | enum FileType : uint8_t | ||
35 | { | ||
36 | NONE, ///< Not specified | ||
37 | BINARY, ///< Binary data | ||
38 | ASCII, ///< Ascii text data | ||
39 | }; | ||
40 | |||
41 | /// @brief Destructor | ||
42 | 3456 | virtual ~FileReader() = default; | |
43 | /// @brief Copy constructor | ||
44 | FileReader(const FileReader&) = delete; | ||
45 | /// @brief Move constructor | ||
46 | FileReader(FileReader&&) = delete; | ||
47 | /// @brief Copy assignment operator | ||
48 | FileReader& operator=(const FileReader&) = delete; | ||
49 | /// @brief Move assignment operator | ||
50 | FileReader& operator=(FileReader&&) = delete; | ||
51 | |||
52 | /// Results enum for the gui config | ||
53 | enum GuiResult : uint8_t | ||
54 | { | ||
55 | PATH_UNCHANGED = 0, ///< No changes made | ||
56 | PATH_CHANGED, ///< The path changed and exists | ||
57 | PATH_CHANGED_INVALID, ///< The path changed but does not exist or is invalid | ||
58 | }; | ||
59 | |||
60 | protected: | ||
61 | /// @brief Default constructor | ||
62 |
1/2✓ Branch 3 taken 1729 times.
✗ Branch 4 not taken.
|
1729 | FileReader() = default; |
63 | |||
64 | /// @brief ImGui config | ||
65 | /// @param[in] vFilters Filter to apply for file names | ||
66 | /// @param[in] extensions Extensions to filter | ||
67 | /// @param[in] id Unique id for creating the dialog uid | ||
68 | /// @param[in] nameId Name of the node triggering the window used for logging | ||
69 | /// @return True if changes occurred | ||
70 | GuiResult guiConfig(const char* vFilters, const std::vector<std::string>& extensions, size_t id, const std::string& nameId); | ||
71 | |||
72 | /// @brief Returns the path of the file | ||
73 | std::filesystem::path getFilepath(); | ||
74 | |||
75 | /// @brief Saves the node into a json object | ||
76 | [[nodiscard]] json save() const; | ||
77 | |||
78 | /// @brief Restores the node from a json object | ||
79 | /// @param[in] j Json object with the node state | ||
80 | void restore(const json& j); | ||
81 | |||
82 | /// @brief Initialize the file reader | ||
83 | bool initialize(); | ||
84 | |||
85 | /// @brief Deinitialize the file reader | ||
86 | void deinitialize(); | ||
87 | |||
88 | /// @brief Moves the read cursor to the start | ||
89 | void resetReader(); | ||
90 | |||
91 | /// @brief Virtual Function to determine the File Type | ||
92 | /// @return The File path which was recognized | ||
93 | [[nodiscard]] virtual FileType determineFileType(); | ||
94 | |||
95 | /// @brief Virtual Function to read the Header of a file | ||
96 | /// | ||
97 | /// The base implementation reads a CSV file header | ||
98 | /// @attention If your file does not have a header, this functions needs to be overridden with an empty function | ||
99 | virtual void readHeader(); | ||
100 | |||
101 | /// @brief Reads a line from the filestream | ||
102 | /// @param str String to read the line into | ||
103 | 328437 | auto& getline(std::string& str) | |
104 | { | ||
105 | 328437 | _lineCnt++; | |
106 | 328437 | return std::getline(_filestream, str); | |
107 | } | ||
108 | |||
109 | /// @brief Extracts up to count immediately available characters from the input stream. The extracted characters are stored into the character array pointed to by s. | ||
110 | /// @param[out] s pointer to the character array to store the characters to | ||
111 | /// @param[in] count maximum number of characters to read | ||
112 | /// @return The number of characters actually extracted. | ||
113 | auto readsome(char* s, std::streamsize count) { return _filestream.readsome(s, count); } | ||
114 | |||
115 | /// @brief Extraction without delimiters. | ||
116 | /// @param __s A character array. | ||
117 | /// @param __n Maximum number of characters to store. | ||
118 | /// @return The filestream if the stream state is good(), extracts characters and stores them into __s until one of the following happens: - __n characters are stored - the input sequence reaches end-of-file, in which case the error state is set to failbit|eofbit. | ||
119 | /// @note This function is not overloaded on signed char and unsigned char. | ||
120 | 5340412 | auto& read(char* __s, std::streamsize __n) { return _filestream.read(__s, __n); } | |
121 | |||
122 | /// @brief Extracts and discards characters from the input stream until and including delim. | ||
123 | /// @param count number of characters to extract | ||
124 | /// @param delim delimiting character to stop the extraction at. It is also extracted. | ||
125 | /// @return The filestream | ||
126 | ✗ | auto& ignore(std::streamsize count, int delim) { return _filestream.ignore(count, delim); } | |
127 | |||
128 | /// @brief Changing the current read position. | ||
129 | /// @param pos A file offset object. | ||
130 | /// @param dir The direction in which to seek. | ||
131 | /// @return The filestream if fail() is not true, calls rdbuf()->pubseekoff(__off,__dir). If that function fails, sets failbit. | ||
132 | /// @note This function first clears eofbit. It does not count the number of characters extracted, if any, and therefore does not affect the next call to gcount(). | ||
133 | 12 | auto& seekg(std::streamoff pos, std::ios_base::seekdir dir) { return _filestream.seekg(pos, dir); } | |
134 | |||
135 | /// @brief Getting the current read position. | ||
136 | /// @return A file position object. If fail() is not false, returns pos_type(-1) to indicate failure. Otherwise returns rdbuf()->pubseekoff(0,cur,in). | ||
137 | /// @note This function does not count the number of characters extracted, if any, and therefore does not affect the next call to gcount(). At variance with putback, unget and seekg, eofbit is not cleared first. | ||
138 | 48 | [[nodiscard]] std::streampos tellg() { return _filestream.tellg(); } | |
139 | |||
140 | /// Check whether the end of file is reached | ||
141 | 5636431 | [[nodiscard]] auto eof() const { return _filestream.eof(); } | |
142 | |||
143 | /// @brief Fast error checking. | ||
144 | /// @return True if no error flags are set. A wrapper around rdstate. | ||
145 | 443 | [[nodiscard]] bool good() const { return _filestream.good(); } | |
146 | |||
147 | /// @brief Looking ahead in the stream | ||
148 | /// @return The next character, or eof(). If, after constructing the sentry object, good() is false, returns traits::eof(). Otherwise reads but does not extract the next input character. | ||
149 | 250941 | [[nodiscard]] auto peek() { return _filestream.peek(); } | |
150 | |||
151 | /// Get the current line number | ||
152 | 6 | [[nodiscard]] size_t getCurrentLineNumber() const { return _lineCnt; } | |
153 | |||
154 | /// Path to the file | ||
155 | std::string _path; | ||
156 | /// File Type | ||
157 | FileType _fileType = FileType::NONE; | ||
158 | |||
159 | /// Header Columns of a CSV file | ||
160 | std::vector<std::string> _headerColumns; | ||
161 | |||
162 | private: | ||
163 | /// File stream to read the file | ||
164 | std::ifstream _filestream; | ||
165 | /// Start of the data in the file | ||
166 | std::streampos _dataStart = 0; | ||
167 | /// Line counter | ||
168 | size_t _lineCnt = 0; | ||
169 | /// Line counter data start | ||
170 | size_t _lineCntDataStart = 0; | ||
171 | }; | ||
172 | |||
173 | } // namespace NAV | ||
174 | |||
175 | #ifndef DOXYGEN_IGNORE | ||
176 | |||
177 | template<> | ||
178 | struct fmt::formatter<NAV::FileReader::FileType> : ostream_formatter | ||
179 | {}; | ||
180 | |||
181 | #endif | ||
182 |