in src/modules/networking/src/lib/Networking.cpp [814:886]
int NetworkingObjectBase::TruncateValueStrings(std::vector<std::pair<std::string, std::string>>& fieldValueVector)
{
// If m_maxPayloadSizeBytes is zero or a negative number, or too small we do not truncate
if ((m_maxPayloadSizeBytes <= 0) || (m_maxPayloadSizeBytes <= g_templateWithDotsSize))
{
return MMI_OK;
}
unsigned int maxValueSize = 0;
unsigned int totalValueSize = 0;
maxValueSize = (m_maxPayloadSizeBytes > g_templateSize) ? m_maxPayloadSizeBytes - g_templateSize : 0;
std::vector<std::string> fields;
for (size_t i = 0; i < fieldValueVector.size(); i++)
{
fields.push_back(fieldValueVector[i].first);
totalValueSize += fieldValueVector[i].second.length();
}
if (totalValueSize > maxValueSize)
{
sort(fieldValueVector.begin(), fieldValueVector.end(), [](std::pair<std::string, std::string>& a, std::pair<std::string, std::string>& b)
{
return (a.second.length() < b.second.length()) || ((a.second.length() == b.second.length()) && a.first < b.first);
});
for (size_t i = 0; i < fieldValueVector.size(); i++)
{
std::string keyString = fieldValueVector[i].first;
std::string valueString = fieldValueVector[i].second;
if (totalValueSize > maxValueSize)
{
unsigned int cutPerField = 0;
// Number of fields to truncate
unsigned int numFieldsToCut = fieldValueVector.size() - i;
// Size to truncate for each field (value string)
cutPerField = ((totalValueSize - maxValueSize) / numFieldsToCut) + (((totalValueSize - maxValueSize) % numFieldsToCut) ? 1 : 0);
unsigned int lengthBeforeCut = valueString.length();
if (valueString.length() > g_twoDotsSize)
{
if (valueString.length() < cutPerField + g_twoDotsSize)
{
// If we truncate a string, the mininum length is two
valueString = g_twoDots;
}
else
{
valueString = valueString.substr(0, valueString.length() - g_twoDotsSize - cutPerField) + g_twoDots;
}
}
// If value string size is less than two bytes, keep it as is
unsigned int lengthAfterCut = valueString.length();
totalValueSize -= ((lengthBeforeCut > lengthAfterCut) ? (lengthBeforeCut - lengthAfterCut) : 0);
fieldValueVector[i].second = valueString;
}
}
// Sort vector back to orginial order
std::unordered_map<std::string, int> position;
for (int i = 0; i < (int)fields.size(); i++)
{
position[fields[i]] = i;
}
sort(fieldValueVector.begin(), fieldValueVector.end(), [&position](std::pair<std::string, std::string>& a, std::pair<std::string, std::string>& b)
{
return (position[a.first] < position[b.first]) || ((position[a.first] == position[b.first]) && (a.second < b.second));
});
}
return (totalValueSize + g_templateSize <= m_maxPayloadSizeBytes) ? MMI_OK : ENODATA;
}