1 // Copyright (C) 2014-2017 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 #ifdef VSOMEIP_DEBUGGING
9 #include <iomanip>
10 #include <sstream>
11 #endif
12 #include <vsomeip/internal/logger.hpp>
13
14 #include "../include/message_impl.hpp"
15 #include "../include/deserializer.hpp"
16 #include "../../utility/include/byteorder.hpp"
17
18 namespace vsomeip_v3 {
19
deserializer(std::uint32_t _buffer_shrink_threshold)20 deserializer::deserializer(std::uint32_t _buffer_shrink_threshold)
21 : position_(data_.begin()),
22 remaining_(0),
23 buffer_shrink_threshold_(_buffer_shrink_threshold),
24 shrink_count_(0) {
25 }
26
deserializer(byte_t * _data,std::size_t _length,std::uint32_t _buffer_shrink_threshold)27 deserializer::deserializer(byte_t *_data, std::size_t _length,
28 std::uint32_t _buffer_shrink_threshold)
29 : data_(_data, _data + _length),
30 position_(data_.begin()),
31 remaining_(_length),
32 buffer_shrink_threshold_(_buffer_shrink_threshold),
33 shrink_count_(0) {
34 }
35
deserializer(const deserializer & _other)36 deserializer::deserializer(const deserializer &_other)
37 : data_(_other.data_),
38 position_(_other.position_),
39 remaining_(_other.remaining_),
40 buffer_shrink_threshold_(_other.buffer_shrink_threshold_),
41 shrink_count_(_other.shrink_count_) {
42 }
43
~deserializer()44 deserializer::~deserializer() {
45 }
46
get_available() const47 std::size_t deserializer::get_available() const {
48 return data_.size();
49 }
50
get_remaining() const51 std::size_t deserializer::get_remaining() const {
52 return remaining_;
53 }
54
set_remaining(std::size_t _remaining)55 void deserializer::set_remaining(std::size_t _remaining) {
56 remaining_ = _remaining;
57 }
58
deserialize(uint8_t & _value)59 bool deserializer::deserialize(uint8_t& _value) {
60 if (0 == remaining_)
61 return false;
62
63 _value = *position_++;
64
65 remaining_--;
66 return true;
67 }
68
deserialize(uint16_t & _value)69 bool deserializer::deserialize(uint16_t& _value) {
70 if (2 > remaining_)
71 return false;
72
73 uint8_t byte0, byte1;
74 byte0 = *position_++;
75 byte1 = *position_++;
76 remaining_ -= 2;
77
78 _value = VSOMEIP_BYTES_TO_WORD(byte0, byte1);
79
80 return true;
81 }
82
deserialize(uint32_t & _value,bool _omit_last_byte)83 bool deserializer::deserialize(uint32_t &_value, bool _omit_last_byte) {
84 if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
85 return false;
86
87 uint8_t byte0 = 0, byte1, byte2, byte3;
88 if (!_omit_last_byte) {
89 byte0 = *position_++;
90 remaining_--;
91 }
92 byte1 = *position_++;
93 byte2 = *position_++;
94 byte3 = *position_++;
95 remaining_ -= 3;
96
97 _value = VSOMEIP_BYTES_TO_LONG(
98 byte0, byte1, byte2, byte3);
99
100 return true;
101 }
102
deserialize(uint8_t * _data,std::size_t _length)103 bool deserializer::deserialize(uint8_t *_data, std::size_t _length) {
104 if (_length > remaining_)
105 return false;
106
107 std::memcpy(_data, &data_[static_cast<std::vector<byte_t>::size_type>(position_ - data_.begin())], _length);
108 position_ += static_cast<std::vector<byte_t>::difference_type>(_length);
109 remaining_ -= _length;
110
111 return true;
112 }
113
deserialize(std::string & _target,std::size_t _length)114 bool deserializer::deserialize(std::string &_target, std::size_t _length) {
115 if (_length > remaining_ || _length > _target.capacity()) {
116 return false;
117 }
118 _target.assign(position_, position_ + long(_length));
119 position_ += long(_length);
120 remaining_ -= _length;
121
122 return true;
123 }
124
deserialize(std::vector<uint8_t> & _value)125 bool deserializer::deserialize(std::vector< uint8_t >& _value) {
126 if (_value.capacity() > remaining_)
127 return false;
128
129 _value.assign(position_, position_
130 + static_cast<std::vector<byte_t>::difference_type>(_value.capacity()));
131 position_ += static_cast<std::vector<byte_t>::difference_type>(_value.capacity());
132 remaining_ -= _value.capacity();
133
134 return true;
135 }
136
look_ahead(std::size_t _index,uint8_t & _value) const137 bool deserializer::look_ahead(std::size_t _index, uint8_t &_value) const {
138 if (_index > remaining_)
139 return false;
140
141 _value = *(position_ + static_cast<std::vector<byte_t>::difference_type>(_index));
142
143 return true;
144 }
145
look_ahead(std::size_t _index,uint16_t & _value) const146 bool deserializer::look_ahead(std::size_t _index, uint16_t &_value) const {
147 if (_index+1 > remaining_)
148 return false;
149
150 std::vector< uint8_t >::iterator i = position_ +
151 static_cast<std::vector<byte_t>::difference_type>(_index);
152 _value = VSOMEIP_BYTES_TO_WORD(*i, *(i+1));
153
154 return true;
155 }
156
look_ahead(std::size_t _index,uint32_t & _value) const157 bool deserializer::look_ahead(std::size_t _index, uint32_t &_value) const {
158 if (_index+3 > remaining_)
159 return false;
160
161 std::vector< uint8_t >::const_iterator i = position_ + static_cast<std::vector<byte_t>::difference_type>(_index);
162 _value = VSOMEIP_BYTES_TO_LONG(*i, *(i+1), *(i+2), *(i+3));
163
164 return true;
165 }
166
deserialize_message()167 message_impl * deserializer::deserialize_message() {
168 message_impl* deserialized_message = new message_impl;
169 if (0 != deserialized_message) {
170 if (false == deserialized_message->deserialize(this)) {
171 VSOMEIP_ERROR << "SOME/IP message deserialization failed!";
172 delete deserialized_message;
173 deserialized_message = nullptr;
174 }
175 }
176
177 return deserialized_message;
178 }
179
set_data(const byte_t * _data,std::size_t _length)180 void deserializer::set_data(const byte_t *_data, std::size_t _length) {
181 if (0 != _data) {
182 data_.assign(_data, _data + _length);
183 position_ = data_.begin();
184 remaining_ = static_cast<std::vector<byte_t>::size_type>(data_.end() - position_);
185 } else {
186 data_.clear();
187 position_ = data_.end();
188 remaining_ = 0;
189 }
190 }
191
append_data(const byte_t * _data,std::size_t _length)192 void deserializer::append_data(const byte_t *_data, std::size_t _length) {
193 std::vector<byte_t>::difference_type offset = (position_ - data_.begin());
194 data_.insert(data_.end(), _data, _data + _length);
195 position_ = data_.begin() + offset;
196 remaining_ += _length;
197 }
198
drop_data(std::size_t _length)199 void deserializer::drop_data(std::size_t _length) {
200 if (position_ + static_cast<std::vector<byte_t>::difference_type>(_length) < data_.end())
201 position_ += static_cast<std::vector<byte_t>::difference_type>(_length);
202 else
203 position_ = data_.end();
204 }
205
reset()206 void deserializer::reset() {
207 if (buffer_shrink_threshold_) {
208 if (data_.size() < (data_.capacity() >> 1)) {
209 shrink_count_++;
210 } else {
211 shrink_count_ = 0;
212 }
213 }
214 data_.clear();
215 position_ = data_.begin();
216 remaining_ = data_.size();
217 if (buffer_shrink_threshold_ && shrink_count_ > buffer_shrink_threshold_) {
218 data_.shrink_to_fit();
219 shrink_count_ = 0;
220 }
221 }
222
223 #ifdef VSOMEIP_DEBUGGING
show() const224 void deserializer::show() const {
225 std::stringstream its_message;
226 its_message << "("
227 << std::hex << std::setw(2) << std::setfill('0')
228 << (int)*position_ << ", "
229 << std:: dec << remaining_ << ") ";
230 for (int i = 0; i < data_.size(); ++i)
231 its_message << std::hex << std::setw(2) << std::setfill('0')
232 << (int)data_[i] << " ";
233 VSOMEIP_INFO << its_message;
234 }
235 #endif
236
237 } // namespace vsomeip_v3
238