Program Listing for File message_truncator.cpp

Return to documentation for file (message_truncator.cpp)

#include "message_truncator.hpp"
#include "monitoring/tohost_monitor.hpp"

#include "ers/ers.h"

#include <format>

std::uint8_t MessageTruncator::truncate_msg_if_too_large(std::span<iovec>& iov, size_t bytes, std::uint8_t status,
    std::optional<size_t> max_msg_size) const
{
    const size_t limit = get_max_msg_size(max_msg_size);
    const bool too_many_entries = m_settings.max_iov_len != 0 and iov.size() > m_settings.max_iov_len;
    if (not too_many_entries and bytes <= limit) {
        return status;
    }

    [[maybe_unused]] const auto original_iov_size = iov.size();
    //IOV length
    if (too_many_entries) {
        iov = iov.subspan(0, m_settings.max_iov_len);
        ERS_DEBUG(1, std::format( "Truncating to IOV {}", m_settings.max_iov_len));
        status |= SW_TRUNC;
    }

    //Max message size
    size_t byte_counter = 0;
    for (size_t i = 0; i < iov.size(); ++i){
        byte_counter += iov[i].iov_len;
        if (byte_counter > limit){
            size_t retain_iov_len = iov[i].iov_len - (byte_counter - limit);
            if (retain_iov_len == 0){
                ERS_DEBUG(1, std::format( "Truncating IOV: length was {} now is {}", original_iov_size, i));
                iov = iov.subspan(0, i);
            } else {
                ERS_DEBUG(1, std::format( "Truncating IOV and last entry: length was {} now is {}, last entry was {} bytes, now {}", original_iov_size, i+1, iov[i].iov_len, retain_iov_len));
                iov = iov.subspan(0, i + 1);
                iov[i].iov_len = retain_iov_len;
            }
            status |= SW_TRUNC;
            break;
        }
    }
    return status;
}