FOUND Coverage Report


src/
File: providers/converters.hpp
Date: 2025-11-20 21:57:26
Lines:
54/54
100.0%
Functions:
8/8
100.0%
Branches:
75/75
100.0%

Line Branch Exec Source
1 #ifndef SRC_PROVIDERS_CONVERTERS_HPP_
2 #define SRC_PROVIDERS_CONVERTERS_HPP_
3
4 #include <stb_image/stb_image.h>
5
6 #include <string>
7 #include <memory>
8 #include <fstream>
9 #include <sstream>
10
11 #include "common/logging.hpp"
12
13 #include "common/spatial/attitude-utils.hpp"
14 #include "common/style.hpp"
15 #include "common/decimal.hpp"
16 #include "datafile/datafile.hpp"
17 #include "datafile/serialization.hpp"
18
19 // NOTE: Throwing exceptions is allowed in this file, as these functions
20 // must successfully parse data for any pipeline to function properly.
21 // If they fail, the pipeline should not be run, and an exception should be thrown.
22 // This is preferable than continuing with invalid data and outputting an unintended
23 // result.
24
25 namespace found {
26
27 /**
28 * Converts a string to an unsigned char
29 *
30 * @param str The string to convert
31 *
32 * @return The unsigned char the string
33 * represents
34 *
35 * @pre str represents a number between 0
36 * and 255
37 */
38 3 inline unsigned char strtouc(const std::string &str) {
39 3 return static_cast<unsigned char>(std::strtoul(str.c_str(), nullptr, 10));
40 }
41
42 6 inline size_t strtosize(const std::string &str) {
43 6 return static_cast<size_t>(atoi(str.c_str()));
44 }
45
46 /**
47 * Converts a string to a decimal
48 *
49 * @param str The string to convert
50 *
51 * @return The decimal numeber this string
52 * represents
53 *
54 * @pre The str must actually represent a decimal
55 */
56 114 inline decimal strtodecimal(const std::string &str) {
57 114 return STR_TO_DECIMAL(str);
58 }
59
60 /**
61 * Converts a string to euler angles.
62 *
63 * @param str The string to convert
64 *
65 * @return An EulerAngle corresponding
66 * to the string, if the str is valid
67 *
68 * @pre The string must have 3 decimal
69 * values seperated by commas or spaces
70 */
71 28 inline EulerAngles strtoea(const std::string &str) {
72
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 17 times.
28 char delimiter = str.find(" ") != std::string::npos ? ' ' : ',';
73 28 decimal result[3];
74
75 28 size_t start = 0;
76 28 size_t end = str.find(delimiter);
77 28 size_t index = 0;
78
79
4/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 55 times.
✓ Branch 3 taken 1 times.
83 while (index != 2 && end != std::string::npos) {
80
2/2
✓ Branch 2 taken 55 times.
✓ Branch 5 taken 55 times.
55 result[index++] = strtodecimal(str.substr(start, end - start));
81 55 start = end + 1;
82 55 end = str.find(delimiter, start);
83 }
84
85
2/2
✓ Branch 2 taken 28 times.
✓ Branch 5 taken 28 times.
28 result[index++] = strtodecimal(str.substr(start));
86
87
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 while (index != 3) result[index++] = 0;
88
89 56 return EulerAngles(DegToRad(result[0]), DegToRad(result[1]), DegToRad(result[2]));
90 }
91
92 /**
93 * Converts the string to a bool
94 *
95 * @param str The string to convert
96 *
97 * @return true iff the string represents
98 * a true value
99 */
100 12 inline bool strtobool(const std::string &str) {
101
6/6
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 6 times.
✓ Branch 8 taken 4 times.
12 return str.size() != 0 && str != "0" && str != "false";
102 }
103
104 /**
105 * Converts a string to an image
106 *
107 * @param str The string to convert
108 *
109 * @return The image that the string represents
110 *
111 * @note This function uses stb_image.h to load the image
112 *
113 * @throw std::runtime_error if the image cannot be loaded
114 */
115 23 inline Image strtoimage(const std::string &str) {
116 Image image;
117 23 image.image = stbi_load(str.c_str(), &image.width, &image.height, &image.channels, 0);
118
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 22 times.
23 if (!image.image) {
119
5/5
✓ Branch 3 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 14 taken 1 times.
✓ Branch 17 taken 1 times.
1 throw std::runtime_error("Could not load image " + str + ": " + stbi_failure_reason());
120 }
121 22 return image;
122 }
123
124 /**
125 *
126 */
127 23 inline DataFile strtodf(const std::string &str) {
128
1/1
✓ Branch 2 taken 23 times.
23 std::ifstream stream(str);
129
1/1
✓ Branch 1 taken 21 times.
44 return deserializeDataFile(stream, str);
130 23 }
131
132 /**
133 * Converts a string to a vector of location records
134 *
135 * @param str The string to convert
136 *
137 * @return The vector of location records that the string represents
138 *
139 * @pre str must refer to a file, either the Data File, or a space
140 * delinated file with the following format on each line:
141 * Timestamp(int) PositionX(decimal) PositionY(decimal) PositionZ(decimal)
142 */
143 8 inline LocationRecords strtolr(const std::string &str) {
144
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1 times.
8 if (str.size() >= 6) {
145
4/4
✓ Branch 3 taken 7 times.
✓ Branch 6 taken 7 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 5 times.
7 if (str.substr(str.size() - 6) == ".found") {
146
8/8
✓ Branch 3 taken 2 times.
✓ Branch 10 taken 2 times.
✓ Branch 13 taken 2 times.
✓ Branch 16 taken 2 times.
✓ Branch 20 taken 2 times.
✓ Branch 23 taken 2 times.
✓ Branch 26 taken 2 times.
✓ Branch 29 taken 2 times.
6 LOG_INFO("Getting Position Data from Data File (*.found)");
147
1/1
✓ Branch 2 taken 1 times.
2 DataFile data = strtodf(str);
148
1/1
✓ Branch 4 taken 1 times.
3 return LocationRecords(data.positions.get(), data.positions.get() + data.header.num_positions);
149 1 }
150 }
151
152
8/8
✓ Branch 3 taken 6 times.
✓ Branch 10 taken 6 times.
✓ Branch 13 taken 6 times.
✓ Branch 16 taken 6 times.
✓ Branch 20 taken 6 times.
✓ Branch 23 taken 6 times.
✓ Branch 26 taken 6 times.
✓ Branch 29 taken 6 times.
18 LOG_INFO("Getting Position Data from non-Data File (not *.found)");
153 6 LocationRecords records;
154
1/1
✓ Branch 2 taken 6 times.
6 std::ifstream file(str);
155
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 if (!file.is_open()) {
156
2/2
✓ Branch 3 taken 3 times.
✓ Branch 6 taken 3 times.
3 throw std::runtime_error("Could not open file " + str);
157 }
158
159 3 std::string line;
160
4/4
✓ Branch 1 taken 11 times.
✓ Branch 4 taken 11 times.
✓ Branch 6 taken 9 times.
✓ Branch 7 taken 2 times.
11 while (std::getline(file, line)) {
161
1/1
✓ Branch 2 taken 9 times.
9 std::istringstream iss(line);
162 9 LocationRecord record;
163
7/7
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
✓ Branch 7 taken 9 times.
✓ Branch 10 taken 9 times.
✓ Branch 13 taken 9 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 8 times.
9 if (!(iss >> record.timestamp >> record.position.x >> record.position.y >> record.position.z)) {
164
1/1
✓ Branch 1 taken 1 times.
1 file.close();
165
4/4
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 14 taken 1 times.
1 throw std::runtime_error("Invalid format for file " + str + ": " + line);
166 }
167
1/1
✓ Branch 1 taken 8 times.
8 records.push_back(record);
168 9 }
169
170
1/1
✓ Branch 1 taken 2 times.
2 file.close();
171 2 return records;
172 11 }
173
174 } // namespace found
175
176 #endif // SRC_PROVIDERS_CONVERTERS_HPP_
177