Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : #include "transport/TransportMessage.h" 4 : 5 : #include "transport/IDataProgressListener.h" 6 : #include "transport/TransportLogger.h" 7 : 8 : #include <estd/assert.h> 9 : #include <estd/memory.h> 10 : 11 : #include <cstring> 12 : 13 : namespace transport 14 : { 15 : using ::util::logger::_CRITICAL; 16 : using ::util::logger::Logger; 17 : using ::util::logger::TRANSPORT; 18 : 19 950 : TransportMessage::TransportMessage() 20 950 : : fpDataProgressListener(nullptr) 21 950 : , fBuffer() 22 950 : , fSourceId(INVALID_ADDRESS) 23 950 : , fTargetId(INVALID_ADDRESS) 24 950 : , fPayloadLength(0U) 25 950 : , fValidBytes(0U) 26 950 : {} 27 : 28 24 : TransportMessage::TransportMessage(uint8_t* const buffer, uint32_t const bufferLength) 29 24 : : fpDataProgressListener(nullptr) 30 24 : , fBuffer(::estd::slice<uint8_t>::from_pointer(buffer, bufferLength)) 31 24 : , fSourceId(INVALID_ADDRESS) 32 24 : , fTargetId(INVALID_ADDRESS) 33 24 : , fPayloadLength(0U) 34 24 : , fValidBytes(0U) 35 24 : {} 36 : 37 759 : void TransportMessage::init(uint8_t* const buffer, uint32_t const bufferLength) 38 : { 39 759 : if ((buffer == nullptr) && (bufferLength > 0U)) 40 : { 41 2 : Logger::critical( 42 : TRANSPORT, 43 : "TransportMessage::init(): buffer is NULL but bufferLength is %d!", 44 : bufferLength); 45 2 : estd_assert(false); 46 : } 47 757 : fpDataProgressListener = nullptr; 48 757 : fBuffer = ::estd::slice<uint8_t>::from_pointer(buffer, bufferLength); 49 757 : fValidBytes = 0U; 50 757 : if (fBuffer.size() != 0U) 51 : { 52 752 : setPayloadLength(0U); 53 : } 54 757 : } 55 : 56 17 : void TransportMessage::setServiceId(uint8_t const theServiceId) 57 : { 58 17 : if (fBuffer.size() == 0U) 59 : { 60 1 : Logger::critical(TRANSPORT, "TransportMessage::setServiceId(): fpBuffer is NULL!"); 61 1 : estd_assert(false); 62 : } 63 16 : fBuffer[SERVICE_ID_INDEX] = theServiceId; 64 : // to be consistent with append, valid bytes must be increased here! 65 16 : if (0U == fValidBytes) 66 : { 67 4 : (void)increaseValidBytes(1U); 68 : } 69 16 : } 70 : 71 1045 : void TransportMessage::setPayloadLength(uint16_t const length) 72 : { 73 1045 : if (length > getMaxPayloadLength()) 74 : { 75 2 : Logger::critical( 76 : TRANSPORT, 77 : "TransportMessage::setPayloadLength(): length is too large (%d)," 78 : " maxLength is:%d!", 79 : length, 80 2 : getMaxPayloadLength()); 81 2 : estd_assert(false); 82 : } 83 1043 : fPayloadLength = length; 84 1043 : } 85 : 86 : TransportMessage::ErrorCode 87 1884 : TransportMessage::append(uint8_t const* const data, uint16_t const length) 88 : { 89 1884 : if ((fValidBytes + length) > getMaxPayloadLength()) 90 : { 91 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED; 92 : } 93 : 94 1882 : (void)::estd::memory::copy( 95 : fBuffer.offset(fValidBytes), ::estd::slice<uint8_t const>::from_pointer(data, length)); 96 1882 : (void)increaseValidBytes(length); 97 1882 : return ErrorCode::TP_MSG_OK; 98 : } 99 : 100 411 : TransportMessage::ErrorCode TransportMessage::append(uint8_t const data) 101 : { 102 411 : if ((fValidBytes + 1U) > getMaxPayloadLength()) 103 : { 104 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED; 105 : } 106 410 : fBuffer[static_cast<size_t>(fValidBytes)] = data; 107 410 : (void)increaseValidBytes(1U); 108 410 : return ErrorCode::TP_MSG_OK; 109 : } 110 : 111 2376 : TransportMessage::ErrorCode TransportMessage::increaseValidBytes(uint16_t const n) 112 : { 113 2376 : if ((fValidBytes + n) > getMaxPayloadLength()) 114 : { 115 : // this is an overflow, we only add as much as possible 116 1 : uint32_t const numberOfNewValidBytes 117 1 : = static_cast<uint32_t>(getMaxPayloadLength()) - static_cast<uint32_t>(fValidBytes); 118 1 : fValidBytes = getMaxPayloadLength(); 119 1 : notifyDataProgressListener(numberOfNewValidBytes); 120 1 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED; 121 : } 122 : 123 2375 : fValidBytes += n; 124 2375 : notifyDataProgressListener(static_cast<uint32_t>(n)); 125 2375 : return ErrorCode::TP_MSG_OK; 126 : } 127 : 128 20 : bool TransportMessage::operator==(TransportMessage const& rhs) const 129 : { 130 20 : if (getPayloadLength() != rhs.getPayloadLength()) 131 : { 132 : return false; 133 : } 134 : // compare only valid bytes because a larger message may be used to receive 135 : // a small amount of data 136 19 : if (fValidBytes != rhs.fValidBytes) 137 : { 138 : return false; 139 : } 140 18 : if ((getTargetId() != rhs.getTargetId()) || (getSourceId() != rhs.getSourceId())) 141 : { 142 : return false; 143 : } 144 : 145 16 : return 0 == ::memcmp(rhs.fBuffer.data(), fBuffer.data(), fValidBytes); 146 : } 147 : 148 1 : void TransportMessage::setDataProgressListener(IDataProgressListener& listener) 149 : { 150 1 : fpDataProgressListener = &listener; 151 1 : } 152 : 153 3 : bool TransportMessage::isDataProgressListener(IDataProgressListener const& listener) const 154 : { 155 3 : return fpDataProgressListener == &listener; 156 : } 157 : 158 1 : void TransportMessage::removeDataProgressListener() { fpDataProgressListener = nullptr; } 159 : 160 2376 : void TransportMessage::notifyDataProgressListener(uint32_t const numberOfNewValidBytes) 161 : { 162 2376 : if (fpDataProgressListener != nullptr) 163 : { 164 1 : fpDataProgressListener->dataProgressed(*this, numberOfNewValidBytes); 165 : } 166 2376 : } 167 : 168 : } // namespace transport