GCC Code Coverage Report


Directory: libimgdoc2/
File: libimgdoc2/src/public/ClassFactory.cpp
Date: 2025-02-03 12:41:04
Exec Total Coverage
Lines: 63 88 71.6%
Functions: 10 17 58.8%
Branches: 42 86 48.8%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH
2 //
3 // SPDX-License-Identifier: MIT
4
5 #include "ClassFactory.h"
6
7 #include <charconv>
8 #include <cstdlib>
9 #include "../doc/document.h"
10 #include "../src/db/DbFactory.h"
11 #include "../src/db/database_creator.h"
12 #include "../src/db/database_discovery.h"
13
14 #include <libimgdoc2_config.h>
15
16 using namespace std;
17 using namespace imgdoc2;
18
19 class StandardHostingEnvironment : public IHostingEnvironment
20 {
21 public:
22 void Log(int level, const char* message) override
23 {
24 // TODO(JBL): on Windows, let's use DebugOutputString,
25 // on Linux - I am not sure what to do
26 }
27
28 bool IsLogLevelActive(int level) override
29 {
30 return true;
31 }
32
33 void ReportFatalErrorAndExit(const char* message) override
34 {
35 abort();
36 }
37 };
38
39 class NullHostingEnvironment : public IHostingEnvironment
40 {
41 public:
42 void Log(int level, const char* message) override
43 {
44 }
45
46 202620 bool IsLogLevelActive(int level) override
47 {
48 202620 return false;
49 }
50
51 void ReportFatalErrorAndExit(const char* message) override
52 {
53 abort();
54 }
55 };
56
57 class HostingEnvironmentOnFunctionPointers : public IHostingEnvironment
58 {
59 private:
60 std::intptr_t userparam_;
61 void (*pfnLog_)(std::intptr_t userparam, int level, const char* szMessage);
62 bool (*pfnIsLevelActive_)(std::intptr_t userparam, int level);
63 void (*pfnReportFatalErrorAndExit_)(std::intptr_t userparam, const char* szMessage);
64 public:
65 2 explicit HostingEnvironmentOnFunctionPointers(std::intptr_t userparam,
66 void (*pfnLog)(std::intptr_t userparam, int level, const char* szMessage),
67 bool (*pfnIsLevelActive)(std::intptr_t userparam, int level),
68 void (*pfnReportFatalErrorAndExit)(std::intptr_t userparam, const char* szMessage))
69 4 : userparam_(userparam),
70 2 pfnLog_(pfnLog),
71 2 pfnIsLevelActive_(pfnIsLevelActive),
72 2 pfnReportFatalErrorAndExit_(pfnReportFatalErrorAndExit)
73 2 {}
74
75 18 void Log(int level, const char* message) override
76 {
77
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (this->pfnLog_ != nullptr)
78 {
79 18 this->pfnLog_(this->userparam_, level, message);
80 }
81 18 }
82
83 22 bool IsLogLevelActive(int level) override
84 {
85
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if (this->pfnIsLevelActive_ != nullptr)
86 {
87 22 return this->pfnIsLevelActive_(this->userparam_, level);
88 }
89
90 return false;
91 }
92
93 void ReportFatalErrorAndExit(const char* message) override
94 {
95 if (this->pfnReportFatalErrorAndExit_ != nullptr)
96 {
97 this->pfnReportFatalErrorAndExit_(this->userparam_, message);
98 }
99
100 abort();
101 }
102 };
103
104 //------------------------------------------------------------------------
105
106 6 static std::uint32_t convert_to_uint32(const char* str)
107 {
108 6 std::uint32_t result = 0;
109
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 auto [ptr, ec] = std::from_chars(str, str + strlen(str), result);
110
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
6 if (ec == std::errc::invalid_argument || ec == std::errc::result_out_of_range || *ptr != '\0')
111 {
112 return (numeric_limits<uint32_t>::max)();
113 }
114
115 6 return result;
116 }
117
118 2 /*static*/VersionInfo imgdoc2::ClassFactory::GetVersionInfo()
119 {
120 2 VersionInfo version_info;
121
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.major = convert_to_uint32(LIBIMGDOC2_VERSION_MAJOR);
122
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.minor = convert_to_uint32(LIBIMGDOC2_VERSION_MINOR);
123
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.patch = convert_to_uint32(LIBIMGDOC2_VERSION_PATCH);
124
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.compiler_identification = LIBIMGDOC2_CXX_COMPILER_IDENTIFICATION;
125
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.build_type = LIBIMGDOC2_BUILD_TYPE;
126
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.repository_url = LIBIMGDOC2_REPOSITORYREMOTEURL;
127
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.repository_branch = LIBIMGDOC2_REPOSITORYBRANCH;
128
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 version_info.repository_tag = LIBIMGDOC2_REPOSITORYHASH;
129
130 2 return version_info;
131 }
132
133 248 /*static*/std::shared_ptr<imgdoc2::IDoc> imgdoc2::ClassFactory::CreateNew(imgdoc2::ICreateOptions* create_options, std::shared_ptr<IHostingEnvironment> environment)
134 {
135 // TODO(JBL): here would be the place where we'd allow for "other databases than Sqlite", for the time being,
136 // we just deal with Sqlite here
137
2/4
✓ Branch 2 taken 248 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 248 times.
✗ Branch 7 not taken.
248 auto db_connection = DbFactory::SqliteCreateNewDatabase(create_options->GetFilename().c_str(), environment);
138
139 // check pre-conditions
140 // TODO(JBL)
141
142 // tweak settings
143
3/6
✓ Branch 1 taken 248 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 178 times.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
248 switch (create_options->GetDocumentType()) // NOLINT(clang-diagnostic-switch)
144 {
145 178 case DocumentType::kImage2d:
146 {
147 178 DbCreator db_creator(db_connection);
148
1/2
✓ Branch 1 taken 178 times.
✗ Branch 2 not taken.
178 const auto database_configuration_2d = db_creator.CreateTables2d(create_options);
149
150
1/2
✓ Branch 1 taken 178 times.
✗ Branch 2 not taken.
178 if (database_configuration_2d)
151 {
152
1/2
✓ Branch 1 taken 178 times.
✗ Branch 2 not taken.
178 return make_shared<Document>(db_connection, database_configuration_2d);
153 }
154
155 break;
156
2/4
✓ Branch 1 taken 178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 178 times.
✗ Branch 5 not taken.
356 }
157 70 case DocumentType::kImage3d:
158 {
159 70 DbCreator db_creator(db_connection);
160
1/2
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
70 const auto database_configuration_3d = db_creator.CreateTables3d(create_options);
161
162
1/2
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
70 if (database_configuration_3d)
163 {
164
1/2
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
70 return make_shared<Document>(db_connection, database_configuration_3d);
165 }
166
167 break;
168
2/4
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
140 }
169 case DocumentType::kInvalid:
170 break;
171 }
172
173 return {};
174 248 }
175
176 4 /*static*/std::shared_ptr<imgdoc2::IDoc> imgdoc2::ClassFactory::OpenExisting(imgdoc2::IOpenExistingOptions* open_existing_options, std::shared_ptr<IHostingEnvironment> environment)
177 {
178 // TODO(JBL): here would be the place where we'd allow for "other databases than Sqlite", for the time being,
179 // we just deal with Sqlite here
180
3/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
4 auto db_connection = DbFactory::SqliteOpenExistingDatabase(open_existing_options->GetFilename().c_str(), open_existing_options->GetOpenReadonly(), environment);
181
182 4 DbDiscovery database_discovery{ db_connection };
183
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 database_discovery.DoDiscovery();
184
185
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 const auto database_configuration_2d = database_discovery.GetDatabaseConfiguration2DOrNull();
186
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (database_configuration_2d)
187 {
188
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 return make_shared<Document>(db_connection, database_configuration_2d);
189 }
190
191
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 const auto database_configuration_3d = database_discovery.GetDatabaseConfiguration3DOrNull();
192
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (database_configuration_3d)
193 {
194
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 return make_shared<Document>(db_connection, database_configuration_3d);
195 }
196
197 return {};
198 4 }
199
200 /*static*/std::shared_ptr<IHostingEnvironment> imgdoc2::ClassFactory::CreateStandardHostingEnvironment()
201 {
202 return make_shared<StandardHostingEnvironment>();
203 }
204
205 270 /*static*/std::shared_ptr<IHostingEnvironment> imgdoc2::ClassFactory::CreateNullHostingEnvironment()
206 {
207
1/2
✓ Branch 1 taken 270 times.
✗ Branch 2 not taken.
270 return make_shared<NullHostingEnvironment>();
208 }
209
210 2 /*static*/std::shared_ptr<IHostingEnvironment> imgdoc2::ClassFactory::CreateHostingEnvironmentForFunctionPointers(
211 std::intptr_t userparam,
212 void (*pfnLog)(std::intptr_t userparam, int level, const char* szMessage),
213 bool (*pfnIsLevelActive)(std::intptr_t userparam, int level),
214 void (*pfnReportFatalErrorAndExit)(std::intptr_t userparam, const char* szMessage))
215 {
216
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 return make_shared<HostingEnvironmentOnFunctionPointers>(
217 userparam,
218 pfnLog,
219 pfnIsLevelActive,
220 4 pfnReportFatalErrorAndExit);
221 }
222