GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/parser/factories/sequence.cc Lines: 18 42 42.9 %
Date: 2024-05-05 11:05:40 Branches: 19 66 28.8 %

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 : public std::unary_function<std::string, bool> {
44
51
  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
25
  if (TIXML_SSCANF(str.c_str(), "%lf", val) == 1) return true;
68
  return false;
69
}
70
71
template <>
72
21
bool cast<float>(const std::string& str, float* val) {
73
21
  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
24
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
48
  StringList values;
102
103
  boost::algorithm::split(values, str, boost::algorithm::is_any_of(" \n\t\r"),
104

24
                          boost::algorithm::token_compress_on);
105

24
  values.erase(std::remove_if(values.begin(), values.end(), StringIsEmpty()),
106
24
               values.end());
107

24
  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
24
  out.resize(values.size());
114
115
  value_type v;
116

116
  for (std::size_t i = 0; i < (std::size_t)out.size(); ++i) {
117
92
    if (!cast<value_type>(values[i], &v)) {
118
      throw std::invalid_argument("Failed to cast string " + values[i]);
119
    }
120
92
    out[i] = v;
121
  }
122
}
123
124
template <typename ValueType>
125
10
void SequenceFactory<ValueType>::addTextChild(const XMLText* text) {
126

20
  std::string t(text->Value());
127
128
10
  readSequence(t, values_, size_);
129
}
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