| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title BufferRepeater.cpp | ||
| 3 | // \author lestarch | ||
| 4 | // \brief cpp file for GenericRepeater component implementation class | ||
| 5 | // | ||
| 6 | // \copyright | ||
| 7 | // Copyright 2009-2015, by the California Institute of Technology. | ||
| 8 | // ALL RIGHTS RESERVED. United States Government Sponsorship | ||
| 9 | // acknowledged. | ||
| 10 | // | ||
| 11 | // ====================================================================== | ||
| 12 | |||
| 13 | #include <Fw/FPrimeBasicTypes.hpp> | ||
| 14 | #include <Svc/BufferRepeater/BufferRepeater.hpp> | ||
| 15 | #include <cstring> | ||
| 16 | |||
| 17 | namespace Svc { | ||
| 18 | |||
| 19 | // ---------------------------------------------------------------------- | ||
| 20 | // Construction, initialization, and destruction | ||
| 21 | // ---------------------------------------------------------------------- | ||
| 22 | |||
| 23 | 4 | BufferRepeater ::BufferRepeater(const char* const compName) | |
| 24 | : BufferRepeaterComponentBase(compName), | ||
| 25 | 4 | m_allocation_failure_response(BufferRepeater::NUM_BUFFER_REPEATER_FAILURE_OPTIONS) {} | |
| 26 | |||
| 27 | 8 | BufferRepeater ::~BufferRepeater() {} | |
| 28 | |||
| 29 | 4 | void BufferRepeater ::configure(BufferRepeater::BufferRepeaterFailureOption allocation_failure_response) { | |
| 30 | 4 | this->m_allocation_failure_response = allocation_failure_response; | |
| 31 | 4 | } | |
| 32 | |||
| 33 | 40 | bool BufferRepeater ::check_allocation(FwIndexType index, | |
| 34 | const Fw::Buffer& new_allocation, | ||
| 35 | const Fw::Buffer& incoming_buffer) { | ||
| 36 | 40 | FW_ASSERT(index < NUM_PORTOUT_OUTPUT_PORTS, static_cast<FwAssertArgType>(index)); | |
| 37 |
3/4✓ Branch 4 taken 10 times.
✓ Branch 5 taken 30 times.
✓ Branch 14 taken 10 times.
✗ Branch 15 not taken.
|
40 | bool is_valid = (new_allocation.getData() != nullptr) && (new_allocation.getSize() >= incoming_buffer.getSize()); |
| 38 | |||
| 39 | // Respond to invalid buffer allocation | ||
| 40 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 10 times.
|
40 | if (!is_valid) { |
| 41 |
4/6✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
|
30 | switch (this->m_allocation_failure_response) { |
| 42 | 10 | case NO_RESPONSE_ON_OUT_OF_MEMORY: | |
| 43 | // No response intended | ||
| 44 | 10 | break; | |
| 45 | 10 | case WARNING_ON_OUT_OF_MEMORY: | |
| 46 | 10 | this->log_WARNING_HI_AllocationSoftFailure(index, incoming_buffer.getSize()); | |
| 47 | 10 | break; | |
| 48 | 10 | case FATAL_ON_OUT_OF_MEMORY: | |
| 49 | 10 | this->log_FATAL_AllocationHardFailure(index, incoming_buffer.getSize()); | |
| 50 | 10 | break; | |
| 51 | ✗ | default: | |
| 52 | ✗ | FW_ASSERT(false); | |
| 53 | ✗ | break; | |
| 54 | } | ||
| 55 | } | ||
| 56 | 40 | return is_valid; | |
| 57 | } | ||
| 58 | |||
| 59 | // ---------------------------------------------------------------------- | ||
| 60 | // Handler implementations for user-defined serial input ports | ||
| 61 | // ---------------------------------------------------------------------- | ||
| 62 | |||
| 63 | 4 | void BufferRepeater ::portIn_handler(FwIndexType portNum, /*!< The port number*/ | |
| 64 | Fw::Buffer& buffer /*!< The serialization buffer*/ | ||
| 65 | ) { | ||
| 66 | 4 | FW_ASSERT(this->m_allocation_failure_response < NUM_BUFFER_REPEATER_FAILURE_OPTIONS); | |
| 67 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 4 times.
|
44 | for (FwIndexType i = 0; i < NUM_PORTOUT_OUTPUT_PORTS; i++) { |
| 68 |
1/2✓ Branch 5 taken 40 times.
✗ Branch 6 not taken.
|
40 | if (isConnected_portOut_OutputPort(i)) { |
| 69 |
2/2✓ Branch 6 taken 40 times.
✓ Branch 9 taken 40 times.
|
40 | Fw::Buffer new_allocation = this->allocate_out(0, buffer.getSize()); |
| 70 |
1/1✓ Branch 5 taken 40 times.
|
40 | const bool allocationValid = this->check_allocation(i, new_allocation, buffer); |
| 71 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 30 times.
|
40 | if (allocationValid) { |
| 72 | // Clone the data and send it | ||
| 73 |
2/5✓ Branch 4 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
|
10 | FW_ASSERT_NO_OVERFLOW(buffer.getSize(), size_t); |
| 74 |
5/7✓ Branch 4 taken 10 times.
✓ Branch 10 taken 10 times.
✓ Branch 14 taken 10 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 10 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 10 times.
|
10 | (void)::memcpy(new_allocation.getData(), buffer.getData(), static_cast<size_t>(buffer.getSize())); |
| 75 |
2/2✓ Branch 5 taken 10 times.
✓ Branch 8 taken 10 times.
|
10 | new_allocation.setSize(buffer.getSize()); |
| 76 |
1/1✓ Branch 5 taken 10 times.
|
10 | this->portOut_out(i, new_allocation); |
| 77 |
2/3✓ Branch 2 taken 30 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 30 times.
|
30 | } else if (new_allocation.getData() != nullptr) { |
| 78 | // Return an undersized but valid allocation rather than leaking it | ||
| 79 | ✗ | this->deallocate_out(0, new_allocation); | |
| 80 | } | ||
| 81 | 40 | } | |
| 82 | } | ||
| 83 | 4 | this->deallocate_out(0, buffer); | |
| 84 | 4 | } | |
| 85 | } // end namespace Svc | ||
| 86 |