GCC Code Coverage Report


Directory: ./
File: src/Factory.cpp
Date: 2026-09-03 16:05:57
Exec Total Coverage
Lines: 29 38 76.3%
Branches: 20 56 35.7%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * This file is part of the ecapp library (EtherCAT application devices).
4 *
5 * Copyright (C) 2026 Florian Pose <fp@igh.de>
6 *
7 * The ecapp library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, version 3 of the
10 * License.
11 *
12 * The ecapp library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with the ecapp library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23 #include "ecapp/Factory.h"
24
25 #include "ecapp/Exceptions.h"
26
27 #include <memory>
28 #include <sstream>
29 #include <string>
30
31 using std::hex;
32 using std::string;
33 using std::stringstream;
34 using std::unique_ptr;
35
36 /****************************************************************************/
37
38 namespace EcApp {
39
40 392 Registry &Registry::instance()
41 {
42
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 384 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
392 static Registry registry;
43 392 return registry;
44 }
45
46 /****************************************************************************/
47
48 376 void Registry::add(DeviceDescriptor d)
49 {
50 376 descriptors.push_back(std::move(d));
51 376 }
52
53 /****************************************************************************/
54
55 15 const DeviceDescriptor &Registry::find(const string &name) const
56 {
57
2/2
✓ Branch 3 taken 496 times.
✓ Branch 4 taken 5 times.
501 for (const auto &d : descriptors) {
58
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 486 times.
496 if (d.name == name) {
59 20 return d;
60 }
61 }
62
63
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 stringstream err;
64
3/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
5 err << "No device registered under the name \"" << name << "\".";
65
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
5 throw UnknownDevice(err.str());
66 }
67
68 /****************************************************************************/
69
70 1 const DeviceDescriptor &Registry::find(
71 uint32_t vendorId,
72 uint32_t productCode,
73 uint32_t revision) const
74 {
75 1 const DeviceDescriptor *anyRevisionMatch = nullptr;
76
77
1/2
✓ Branch 3 taken 42 times.
✗ Branch 4 not taken.
42 for (const auto &d : descriptors) {
78
4/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 1 times.
42 if (d.vendorId != vendorId || d.productCode != productCode) {
79 41 continue;
80 }
81
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (revision == AnyRevision || d.revision == AnyRevision) {
82 1 anyRevisionMatch = &d;
83 }
84
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (d.revision == revision) {
85 1 return d;
86 }
87 }
88
89 if (anyRevisionMatch) {
90 return *anyRevisionMatch;
91 }
92
93 stringstream err;
94 err << "No device registered for vendor 0x" << hex << vendorId
95 << ", product code 0x" << productCode << ", revision 0x" << revision
96 << ".";
97 throw UnknownDevice(err.str());
98 }
99
100 /****************************************************************************/
101
102 const std::vector<DeviceDescriptor> &Registry::all() const
103 {
104 return descriptors;
105 }
106
107 /****************************************************************************/
108
109 15 unique_ptr<SubDevice> createSubDevice(
110 const string &name,
111 Master *master,
112 Domain *domainOut,
113 Domain *domainIn,
114 uint16_t alias,
115 uint16_t position,
116 Mode mode,
117 const string &prefix,
118 pdserv *pdServ,
119 pdtask *task)
120 {
121 15 return Registry::instance().find(name).factory(
122 master, domainOut, domainIn, alias, position, mode, prefix,
123 10 pdServ, task);
124 }
125
126 /****************************************************************************/
127
128 1 unique_ptr<SubDevice> createSubDevice(
129 uint32_t vendorId,
130 uint32_t productCode,
131 Master *master,
132 Domain *domainOut,
133 Domain *domainIn,
134 uint16_t alias,
135 uint16_t position,
136 Mode mode,
137 const string &prefix,
138 pdserv *pdServ,
139 pdtask *task,
140 uint32_t revision)
141 {
142 1 return Registry::instance()
143 1 .find(vendorId, productCode, revision)
144 .factory(
145 master, domainOut, domainIn, alias, position, mode,
146 1 prefix, pdServ, task);
147 }
148
149 } // namespace EcApp
150
151 /****************************************************************************/
152