INSTINCT Code Coverage Report


Directory: src/
File: Nodes/DataProvider/Protocol/FileReader.cpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 45 92 48.9%
Functions: 6 11 54.5%
Branches: 31 126 24.6%

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 #include "FileReader.hpp"
10
11 #include "util/Logger.hpp"
12
13 #include "internal/ConfigManager.hpp"
14 #include "internal/FlowManager.hpp"
15
16 #include <sstream>
17 #include "util/StringUtil.hpp"
18
19 #include <imgui.h>
20 #include "internal/gui/widgets/FileDialog.hpp"
21 #include "internal/gui/widgets/HelpMarker.hpp"
22
23 NAV::FileReader::GuiResult NAV::FileReader::guiConfig(const char* vFilters, const std::vector<std::string>& extensions, size_t id, const std::string& nameId)
24 {
25 GuiResult result = PATH_UNCHANGED;
26
27 if (gui::widgets::FileDialogLoad(_path, "Select File", vFilters, extensions, flow::GetInputPath(), id, nameId))
28 {
29 if (!std::filesystem::exists(getFilepath()))
30 {
31 result = PATH_CHANGED_INVALID;
32 }
33 else
34 {
35 result = PATH_CHANGED;
36 }
37 }
38 ImGui::SameLine();
39 gui::widgets::HelpMarker(fmt::format("If a relative path is given, files will be searched inside {}.", flow::GetInputPath()).c_str());
40
41 return result;
42 }
43
44 318 std::filesystem::path NAV::FileReader::getFilepath()
45 {
46 318 std::filesystem::path filepath{ _path };
47
1/2
✓ Branch 1 taken 318 times.
✗ Branch 2 not taken.
319 if (filepath.is_relative())
48 {
49
1/2
✓ Branch 1 taken 319 times.
✗ Branch 2 not taken.
318 filepath = flow::GetInputPath();
50
1/2
✓ Branch 1 taken 319 times.
✗ Branch 2 not taken.
319 filepath /= _path;
51 }
52 319 return filepath;
53 }
54
55 [[nodiscard]] json NAV::FileReader::save() const
56 {
57 LOG_TRACE("called");
58
59 json j;
60
61 j["path"] = _path;
62
63 return j;
64 }
65
66 161 void NAV::FileReader::restore(json const& j)
67 {
68 LOG_TRACE("called");
69
70
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
161 if (j.contains("path"))
71 {
72 161 j.at("path").get_to(_path);
73 }
74 161 }
75
76 161 bool NAV::FileReader::initialize()
77 {
78
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
161 deinitialize();
79
80 LOG_TRACE("called");
81
82
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 161 times.
161 if (_path.empty())
83 {
84 return false;
85 }
86
87
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
161 std::filesystem::path filepath = getFilepath();
88
89
2/4
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 161 times.
161 if (!std::filesystem::exists(filepath))
90 {
91 LOG_ERROR("File does not exist {}", filepath);
92 return false;
93 }
94
2/4
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 160 times.
161 if (std::filesystem::is_directory(filepath))
95 {
96 LOG_ERROR("Path is a directory {}", filepath);
97 return false;
98 }
99
100
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
160 _fileType = determineFileType();
101
102
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 times.
161 if (_fileType == FileType::ASCII || _fileType == FileType::BINARY)
103 {
104 // Does not enable binary read/write, but disables OS dependant treatment of \n, \r
105
2/4
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 160 times.
✗ Branch 6 not taken.
160 _filestream = std::ifstream(filepath, std::ios_base::in | std::ios_base::binary);
106 }
107 else
108 {
109 1 return false;
110 }
111
112
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 160 times.
160 if (!_filestream.good())
113 {
114 LOG_ERROR("Could not open file {}", filepath);
115 return false;
116 }
117 160 _lineCnt = 0;
118
119
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 readHeader();
120
121 160 _lineCntDataStart = _lineCnt;
122
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 _dataStart = _filestream.tellg();
123
124
2/2
✓ Branch 0 taken 153 times.
✓ Branch 1 taken 7 times.
160 if (_fileType == FileType::ASCII)
125 {
126
2/4
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 153 times.
✗ Branch 7 not taken.
306 LOG_DEBUG("ASCII-File successfully initialized");
127 }
128
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 else if (_fileType == FileType::BINARY)
129 {
130
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
14 LOG_DEBUG("Binary-File successfully initialized");
131 }
132
133 160 return true;
134 161 }
135
136 321 void NAV::FileReader::deinitialize()
137 {
138 LOG_TRACE("called");
139
140 321 _headerColumns.clear();
141
142
2/2
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 161 times.
321 if (_filestream.is_open())
143 {
144 160 _filestream.close();
145 }
146
147 321 _filestream.clear();
148 321 }
149
150 NAV::FileReader::FileType NAV::FileReader::determineFileType()
151 {
152 LOG_TRACE("called");
153
154 auto filepath = getFilepath();
155
156 auto filestreamHeader = std::ifstream(filepath);
157 if (_filestream.good())
158 {
159 std::string line;
160 std::getline(filestreamHeader, line);
161 filestreamHeader.close();
162
163 auto n = std::ranges::count(line, ',');
164
165 if (n >= 3)
166 {
167 return FileType::ASCII;
168 }
169
170 return FileType::BINARY;
171 }
172
173 LOG_ERROR("Could not open file {}", filepath.string());
174 return FileType::NONE;
175 }
176
177 2 void NAV::FileReader::readHeader()
178 {
179 LOG_TRACE("called");
180
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (_fileType == FileType::ASCII)
182 {
183 _headerColumns.clear();
184
185 // Read header line
186 std::string line;
187 getline(line);
188 // Remove any starting non text characters
189 line.erase(line.begin(), std::ranges::find_if(line, [](int ch) { return std::isalnum(ch); }));
190 // Convert line into stream
191 std::stringstream lineStream(line);
192 std::string cell;
193 // Split line at comma
194 while (std::getline(lineStream, cell, ','))
195 {
196 // Remove any trailing non text characters
197 cell.erase(std::ranges::find_if(cell, [](int ch) { return std::iscntrl(ch); }), cell.end());
198 _headerColumns.push_back(cell);
199 }
200 }
201 2 }
202
203 320 void NAV::FileReader::resetReader()
204 {
205 LOG_TRACE("called");
206
207 // Return to position
208 320 _filestream.clear();
209 320 _filestream.seekg(_dataStart, std::ios_base::beg);
210 320 _lineCnt = _lineCntDataStart;
211 320 }
212