Add byteLengthWithFallback to ShortStrings (#4089)
Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
@ -54,7 +54,7 @@ library ShortStrings {
|
|||||||
* @dev Decode a `ShortString` back to a "normal" string.
|
* @dev Decode a `ShortString` back to a "normal" string.
|
||||||
*/
|
*/
|
||||||
function toString(ShortString sstr) internal pure returns (string memory) {
|
function toString(ShortString sstr) internal pure returns (string memory) {
|
||||||
uint256 len = length(sstr);
|
uint256 len = byteLength(sstr);
|
||||||
// using `new string(len)` would work locally but is not memory safe.
|
// using `new string(len)` would work locally but is not memory safe.
|
||||||
string memory str = new string(32);
|
string memory str = new string(32);
|
||||||
/// @solidity memory-safe-assembly
|
/// @solidity memory-safe-assembly
|
||||||
@ -68,7 +68,7 @@ library ShortStrings {
|
|||||||
/**
|
/**
|
||||||
* @dev Return the length of a `ShortString`.
|
* @dev Return the length of a `ShortString`.
|
||||||
*/
|
*/
|
||||||
function length(ShortString sstr) internal pure returns (uint256) {
|
function byteLength(ShortString sstr) internal pure returns (uint256) {
|
||||||
uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
|
uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
|
||||||
if (result > 31) {
|
if (result > 31) {
|
||||||
revert InvalidShortString();
|
revert InvalidShortString();
|
||||||
@ -98,4 +98,18 @@ library ShortStrings {
|
|||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
|
||||||
|
*
|
||||||
|
* WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
|
||||||
|
* actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
|
||||||
|
*/
|
||||||
|
function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
|
||||||
|
if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
|
||||||
|
return byteLength(value);
|
||||||
|
} else {
|
||||||
|
return bytes(store).length;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ contract('ShortStrings', function () {
|
|||||||
const encoded = await this.mock.$toShortString(str);
|
const encoded = await this.mock.$toShortString(str);
|
||||||
expect(decode(encoded)).to.be.equal(str);
|
expect(decode(encoded)).to.be.equal(str);
|
||||||
|
|
||||||
const length = await this.mock.$length(encoded);
|
const length = await this.mock.$byteLength(encoded);
|
||||||
expect(length.toNumber()).to.be.equal(str.length);
|
expect(length.toNumber()).to.be.equal(str.length);
|
||||||
|
|
||||||
const decoded = await this.mock.$toString(encoded);
|
const decoded = await this.mock.$toString(encoded);
|
||||||
@ -44,6 +44,9 @@ contract('ShortStrings', function () {
|
|||||||
await expectRevertCustomError(promise, 'InvalidShortString()');
|
await expectRevertCustomError(promise, 'InvalidShortString()');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const length = await this.mock.$byteLengthWithFallback(ret0, 0);
|
||||||
|
expect(length.toNumber()).to.be.equal(str.length);
|
||||||
|
|
||||||
const recovered = await this.mock.$toStringWithFallback(ret0, 0);
|
const recovered = await this.mock.$toStringWithFallback(ret0, 0);
|
||||||
expect(recovered).to.be.equal(str);
|
expect(recovered).to.be.equal(str);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user