1 // Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6 #include <cstring>
7
8 #include "../include/configuration_option_impl.hpp"
9 #include "../../message/include/deserializer.hpp"
10 #include "../../message/include/serializer.hpp"
11
12 namespace vsomeip_v3 {
13 namespace sd {
14
configuration_option_impl()15 configuration_option_impl::configuration_option_impl() {
16 length_ = 2; // always contains "Reserved" and the trailing '\0'
17 type_ = option_type_e::CONFIGURATION;
18 }
19
~configuration_option_impl()20 configuration_option_impl::~configuration_option_impl() {
21 }
22
23 bool
operator ==(const option_impl & _other) const24 configuration_option_impl::operator ==(const option_impl &_other) const {
25 bool is_equal(option_impl::operator ==(_other));
26
27 if (is_equal) {
28 const configuration_option_impl &its_other
29 = dynamic_cast<const configuration_option_impl &>(_other);
30 is_equal = (configuration_ == its_other.configuration_);
31 }
32
33 return is_equal;
34 }
35
add_item(const std::string & _key,const std::string & _value)36 void configuration_option_impl::add_item(const std::string &_key,
37 const std::string &_value) {
38 configuration_[_key] = _value;
39 length_ = uint16_t(length_ + _key.length() + _value.length() + 2u); // +2 for the '=' and length
40 }
41
remove_item(const std::string & _key)42 void configuration_option_impl::remove_item(const std::string &_key) {
43 auto it = configuration_.find(_key);
44 if (it != configuration_.end()) {
45 length_ = uint16_t(length_ - (it->first.length() + it->second.length() + 2u));
46 configuration_.erase(it);
47 }
48 }
49
get_keys() const50 std::vector<std::string> configuration_option_impl::get_keys() const {
51 std::vector < std::string > l_keys;
52 for (const auto& elem : configuration_)
53 l_keys.push_back(elem.first);
54 return l_keys;
55 }
56
get_values() const57 std::vector<std::string> configuration_option_impl::get_values() const {
58 std::vector < std::string > l_values;
59 for (const auto& elem : configuration_)
60 l_values.push_back(elem.second);
61 return l_values;
62 }
63
get_value(const std::string & _key) const64 std::string configuration_option_impl::get_value(
65 const std::string &_key) const {
66 std::string l_value("");
67 auto l_elem = configuration_.find(_key);
68 if (l_elem != configuration_.end())
69 l_value = l_elem->second;
70 return l_value;
71 }
72
serialize(vsomeip_v3::serializer * _to) const73 bool configuration_option_impl::serialize(vsomeip_v3::serializer *_to) const {
74 bool is_successful;
75 std::string configuration_string;
76
77 for (auto i = configuration_.begin(); i != configuration_.end(); ++i) {
78 char l_length = char(1 + i->first.length() + i->second.length());
79 configuration_string.push_back(l_length);
80 configuration_string.append(i->first);
81 configuration_string.push_back('=');
82 configuration_string.append(i->second);
83 }
84 configuration_string.push_back('\0');
85
86 is_successful = option_impl::serialize(_to);
87 if (is_successful) {
88 is_successful = _to->serialize(
89 reinterpret_cast<const uint8_t*>(configuration_string.c_str()),
90 uint32_t(configuration_string.length()));
91 }
92
93 return is_successful;
94 }
95
deserialize(vsomeip_v3::deserializer * _from)96 bool configuration_option_impl::deserialize(vsomeip_v3::deserializer *_from) {
97 bool is_successful = option_impl::deserialize(_from);
98 uint8_t l_itemLength = 0;
99 std::string l_item(256, 0), l_key, l_value;
100
101 do {
102 l_itemLength = 0;
103 l_key.clear();
104 l_value.clear();
105 l_item.assign(256, '\0');
106
107 is_successful = is_successful && _from->deserialize(l_itemLength);
108 if (l_itemLength > 0) {
109 is_successful = is_successful
110 && _from->deserialize(l_item, static_cast<std::size_t>(l_itemLength));
111
112 if (is_successful) {
113 size_t l_eqPos = l_item.find('='); //SWS_SD_00292
114 l_key = l_item.substr(0, l_eqPos);
115
116 //if no "=" is found, no value is present for key (SWS_SD_00466)
117 if( l_eqPos != std::string::npos )
118 l_value = l_item.substr(l_eqPos + 1);
119 if (configuration_.end() == configuration_.find(l_key)) {
120 configuration_[l_key] = l_value;
121 } else {
122 // TODO: log reason for failing deserialization
123 is_successful = false;
124 }
125 }
126 } else {
127 break;
128 }
129 } while (is_successful && _from->get_remaining() > 0);
130
131 return is_successful;
132 }
133
134 } // namespace sd
135 } // namespace vsomeip_v3
136