blob: 7df85cc972c2127b3ceedbfdce7ae7ccc77f9d8d [file] [log] [blame]
//
// deserializer_impl.cpp
//
// Author: Lutz Bichler
//
// This file is part of the BMW Some/IP implementation.
//
// Copyright © 2013, 2014 Bayerische Motoren Werke AG (BMW).
// All rights reserved.
//
#include <cstring>
#include <vsomeip/impl/byteorder_impl.hpp>
#include <vsomeip/impl/message_impl.hpp>
#include <vsomeip/impl/deserializer_impl.hpp>
namespace vsomeip {
deserializer_impl::deserializer_impl() {
data_ = 0;
length_ = 0;
position_ = 0;
remaining_ = 0;
is_owning_data_ = false;
}
deserializer_impl::deserializer_impl(uint8_t *_data, uint32_t _length) {
data_ = _data;
length_ = _length;
position_ = _data;
remaining_ = _length;
is_owning_data_ = true;
}
deserializer_impl::deserializer_impl(const deserializer_impl& _deserializer, bool _is_deep_copy_request) {
length_ = _deserializer.length_;
remaining_ = _deserializer.remaining_;
if (_is_deep_copy_request && _deserializer.data_) {
data_ = new uint8_t[length_];
is_owning_data_ = true;
if (data_) {
::memcpy(data_, _deserializer.data_, length_);
} else {
// TODO: throw exception here!
}
} else {
data_ = _deserializer.data_;
is_owning_data_ = false;
}
position_ = data_ + (length_ - remaining_);
}
deserializer_impl::~deserializer_impl() {
if (is_owning_data_)
delete [] data_;
}
uint32_t deserializer_impl::get_remaining() const {
return remaining_;
}
void deserializer_impl::set_remaining(uint32_t _remaining) {
remaining_ = _remaining;
}
bool deserializer_impl::deserialize(uint8_t& _value) {
if (0 == remaining_)
return false;
_value = *position_++;
remaining_--;
return true;
}
bool deserializer_impl::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_impl::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_impl::deserialize(uint8_t *_data, uint32_t _length) {
if (_length > remaining_)
return false;
::memcpy(_data, position_, _length);
position_ += _length;
remaining_ -= _length;
return true;
}
bool deserializer_impl::deserialize(std::vector<uint8_t>& _value) {
if (_value.capacity() > remaining_)
return false;
_value.assign(position_, position_ + remaining_);
remaining_ -= _value.capacity();
return true;
}
bool deserializer_impl::look_ahead(uint32_t _index, uint8_t &_value) const {
if (_index >= remaining_)
return false;
_value = position_[_index];
return true;
}
message_base * deserializer_impl::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_impl::set_data(uint8_t *_data, uint32_t _length) {
if (0 != data_)
delete [] data_;
data_ = _data;
length_ = _length;
position_ = data_;
remaining_ = length_;
}
} // namespace vsomeip