blob: 28d45c4c03fed46ade87379e75f38172e3c8ec59 [file] [log] [blame]
// Copyright (C) 2014 BMW Group
// Author: Lutz Bichler (lutz.bichler@bmw.de)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <cstring>
#ifdef VSOMEIP_DEBUGGING
#include <iomanip>
#include <sstream>
#include <vsomeip/logger.hpp>
#endif
#include "../include/message_impl.hpp"
#include "../include/deserializer.hpp"
#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
deserializer::deserializer()
: position_(data_.begin()),
remaining_(0) {
}
deserializer::deserializer(byte_t *_data, std::size_t _length)
: data_(_data, _data + _length),
position_(data_.begin()),
remaining_(_length) {
}
deserializer::deserializer(const deserializer &_other)
: data_(_other.data_),
position_(_other.position_){
}
deserializer::~deserializer() {
}
std::size_t deserializer::get_available() const {
return data_.size();
}
std::size_t deserializer::get_remaining() const {
return remaining_;
}
void deserializer::set_remaining(std::size_t _remaining) {
remaining_ = _remaining;
}
bool deserializer::deserialize(uint8_t& _value) {
if (0 == remaining_)
return false;
_value = *position_++;
remaining_--;
return true;
}
bool deserializer::deserialize(uint16_t& _value) {
if (2 > remaining_)
return false;
uint8_t byte0, byte1;
byte0 = *position_++;
byte1 = *position_++;
remaining_ -= 2;
_value = VSOMEIP_BYTES_TO_WORD(byte0, byte1);
return true;
}
bool deserializer::deserialize(uint32_t &_value, bool _omit_last_byte) {
if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
return false;
uint8_t byte0 = 0, byte1, byte2, byte3;
if (!_omit_last_byte) {
byte0 = *position_++;
remaining_--;
}
byte1 = *position_++;
byte2 = *position_++;
byte3 = *position_++;
remaining_ -= 3;
_value = VSOMEIP_BYTES_TO_LONG(
byte0, byte1, byte2, byte3);
return true;
}
bool deserializer::deserialize(uint8_t *_data, std::size_t _length) {
if (_length > remaining_)
return false;
std::memcpy(_data, &data_[position_ - data_.begin()], _length);
position_ += _length;
remaining_ -= _length;
return true;
}
bool deserializer::deserialize(std::vector< uint8_t >& _value) {
if (_value.capacity() > remaining_)
return false;
_value.assign(position_, position_ + _value.capacity());
position_ += _value.capacity();
remaining_ -= _value.capacity();
return true;
}
bool deserializer::look_ahead(std::size_t _index, uint8_t &_value) const {
if (_index >= data_.size())
return false;
_value = *(position_ + _index);
return true;
}
bool deserializer::look_ahead(std::size_t _index, uint16_t &_value) const {
if (_index+1 >= data_.size())
return false;
std::vector< uint8_t >::iterator i = position_ + _index;
_value = VSOMEIP_BYTES_TO_WORD(*i, *(i+1));
return true;
}
bool deserializer::look_ahead(std::size_t _index, uint32_t &_value) const {
if (_index+3 >= data_.size())
return false;
std::vector< uint8_t >::const_iterator i = position_ + _index;
_value = VSOMEIP_BYTES_TO_LONG(*i, *(i+1), *(i+2), *(i+3));
return true;
}
message * deserializer::deserialize_message() {
message_impl* deserialized_message = new message_impl;
if (0 != deserialized_message) {
if (false == deserialized_message->deserialize(this)) {
delete deserialized_message;
deserialized_message = 0;
}
}
return deserialized_message;
}
void deserializer::set_data(const byte_t *_data, std::size_t _length) {
if (0 != _data) {
data_.assign(_data, _data + _length);
position_ = data_.begin();
remaining_ = data_.end() - position_;
} else {
data_.clear();
position_ = data_.end();
remaining_ = 0;
}
}
void deserializer::append_data(const byte_t *_data, std::size_t _length) {
std::size_t offset = (position_ - data_.begin());
data_.insert(data_.end(), _data, _data + _length);
position_ = data_.begin() + offset;
remaining_ += _length;
}
void deserializer::drop_data(std::size_t _length) {
if (position_ + _length < data_.end())
position_ += _length;
else
position_ = data_.end();
}
void deserializer::reset() {
data_.erase(data_.begin(), position_);
position_ = data_.begin();
remaining_ = data_.size();
}
#ifdef VSOMEIP_DEBUGGING
void deserializer::show() const {
std::stringstream its_message;
its_message << "("
<< std::hex << std::setw(2) << std::setfill('0') << (int)*position_ << ", "
<< std:: dec << remaining_ << ") ";
for (int i = 0; i < data_.size(); ++i)
its_message << std::hex << std::setw(2) << std::setfill('0') << (int)data_[i] << " ";
VSOMEIP_DEBUG << its_message;
}
#endif
} // namespace vsomeip