newrelic
Version:
New Relic agent
72 lines (63 loc) • 2.26 kB
JavaScript
/*
* Copyright 2020 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Checks if a given string is within agent attribute limits.
*
* @param {string} str - Object key name or value
* @param {number} limit - String byte limit
*/
function isValidLength(str, limit) {
return Buffer.byteLength(str, 'utf8') <= limit
}
/**
* Returns the relative position of the end of the string (in bytes) and the limit.
* >1 if the string is longer than the limit
* 0 if the string is at the limit
* <1 if the string is shorter than the limit
*
* @param {string} str
* @param {number} limit - String byte limit
*/
function compareLength(str, limit) {
return Buffer.byteLength(str) - limit
}
/**
* Trims a string value to given byte limit, if necessary.
*
* @private
* @param {string} val - The value to truncate to given byte limit.
* @param {number} limit - The byte limit
* @returns {string} The truncated value.
*/
function truncate(val, limit) {
// First truncation handles the simple case of only one-byte characters.
val = val.substring(0, limit)
if (isValidLength(val, limit)) {
return val
}
// Our limitation is on byte length, and the string could contain multi-byte
// characters. Doing a byte-substring could chop a character in half. Instead
// we do a binary search over the byte length of the substrings.
let substrLen = val.length
let delta = Math.ceil(substrLen / 2)
let cmpVal = compareLength(val.substring(0, substrLen), limit)
// Continue the binary search till:
// 1) The string is the desired length (i.e. cmpVal = 0) OR
// 2) The desired string must split a character to achieve the desired byte length
// In this case, we should cut the character that would be split.
// (i.e. delta > 1 character OR the string is larger than the limit)
let substr
while (cmpVal && (cmpVal > 0 || delta > 1)) {
substrLen = cmpVal < 0 ? substrLen + delta : substrLen - delta
substr = val.substring(0, substrLen)
cmpVal = compareLength(substr, limit)
delta = Math.ceil(delta / 2)
}
return substr
}
module.exports.isValidLength = isValidLength
module.exports.compareLength = compareLength
module.exports.truncate = truncate