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