GCC Code Coverage Report


Directory: ./
File: src/parser/factories/sequence.cc
Date: 2025-06-05 11:04:44
Exec Total Coverage
Lines: 20 45 44.4%
Functions: 9 18 50.0%
Branches: 17 64 26.6%

Line Branch Exec Source
1 // Copyright (c) 2014, LAAS-CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #include "hpp/manipulation/parser/factories/sequence.hh"
30
31 #include <boost/algorithm/string.hpp>
32 #include <hpp/util/debug.hh>
33
34 /* tinyxml 2.5.2 is missing this */
35 #ifndef TIXML_SSCANF
36 #define TIXML_SSCANF sscanf
37 #endif
38
39 namespace hpp {
40 namespace manipulation {
41 namespace parser {
42 namespace {
43 struct StringIsEmpty {
44 69 bool operator()(std::string s) const { return s.empty(); }
45 };
46
47 template <typename ValueType>
48 bool cast(const std::string& str, ValueType* val) {
49 hppDout(error, "Unkown type.");
50 return false;
51 }
52
53 template <>
54 bool cast<int>(const std::string& str, int* val) {
55 if (TIXML_SSCANF(str.c_str(), "%d", val) == 1) return true;
56 return false;
57 }
58
59 template <>
60 bool cast<unsigned int>(const std::string& str, unsigned int* val) {
61 if (TIXML_SSCANF(str.c_str(), "%u", val) == 1) return true;
62 return false;
63 }
64
65 template <>
66 25 bool cast<double>(const std::string& str, double* val) {
67
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
25 if (TIXML_SSCANF(str.c_str(), "%lf", val) == 1) return true;
68 return false;
69 }
70
71 template <>
72 35 bool cast<float>(const std::string& str, float* val) {
73
1/2
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
35 if (TIXML_SSCANF(str.c_str(), "%f", val) == 1) return true;
74 return false;
75 }
76
77 template <>
78 bool cast<bool>(const std::string& str, bool* val) {
79 int iVal;
80 if (cast<int>(str, &iVal)) {
81 *val = (iVal == 0) ? false : true;
82 return true;
83 }
84 if (str.compare("true") == 0) {
85 *val = true;
86 return true;
87 }
88 if (str.compare("false") == 0) {
89 *val = false;
90 return true;
91 }
92 return false;
93 }
94 } // namespace
95
96 template <typename Container>
97 28 void readSequence(const std::string& str, Container& out, int size) {
98 typedef typename Container::value_type value_type;
99
100 typedef std::vector<std::string> StringList;
101 28 StringList values;
102
103
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
28 boost::algorithm::split(values, str, boost::algorithm::is_any_of(" \n\t\r"),
104 boost::algorithm::token_compress_on);
105
2/4
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
28 values.erase(std::remove_if(values.begin(), values.end(), StringIsEmpty()),
106 28 values.end());
107
3/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
28 if (size >= 0 && values.size() != (std::size_t)size) {
108 std::ostringstream oss;
109 oss << "Wrong sequence size, expecting " << size << ", got "
110 << values.size() << " in " << str;
111 throw std::invalid_argument(oss.str().c_str());
112 }
113
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
28 out.resize(values.size());
114
115 value_type v;
116
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 14 times.
148 for (std::size_t i = 0; i < (std::size_t)out.size(); ++i) {
117
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 60 times.
120 if (!cast<value_type>(values[i], &v)) {
118 throw std::invalid_argument("Failed to cast string " + values[i]);
119 }
120
1/2
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
120 out[i] = v;
121 }
122 28 }
123
124 template <typename ValueType>
125 14 void SequenceFactory<ValueType>::addTextChild(const XMLText* text) {
126
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
14 std::string t(text->Value());
127
128
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 readSequence(t, values_, size_);
129 14 }
130
131 template class SequenceFactory<bool>;
132 template class SequenceFactory<int>;
133 template class SequenceFactory<unsigned int>;
134 template class SequenceFactory<double>;
135 template class SequenceFactory<float>;
136
137 template void readSequence<vector_t>(const std::string&, vector_t&, int);
138 template void readSequence<vector3_t>(const std::string&, vector3_t&, int);
139 } // namespace parser
140 } // namespace manipulation
141 } // namespace hpp
142