Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
feature: indexLEUint (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
prestwich authored May 26, 2020
1 parent c5617b6 commit 3a35db8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
28 changes: 28 additions & 0 deletions solidity/contracts/TypedMemView.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ library TypedMemView {
uint256 constant TWO_BYTE_MASK = 0xffff; // mask out top 28 bytes
uint256 constant FIFTEEN_BYTE_MASK = 0xffffffffffffffffffffffffffffff; // mask out top 17 bytes

/// @notice Changes the endianness of a uint256
/// @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
/// @param _b The unsigned integer to reverse
/// @return The reversed value
function reverseUint256(uint256 _b) private pure returns (uint256 v) {
v = _b;

// swap bytes
v = ((v >> 8) & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |
((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);
// swap 2-byte long pairs
v = ((v >> 16) & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |
((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);
// swap 4-byte long pairs
v = ((v >> 32) & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |
((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);
// swap 8-byte long pairs
v = ((v >> 64) & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |
((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);
// swap 16-byte long pairs
v = (v >> 128) | (v << 128);
}

/// Create a mask with the lowest `_len` bits set
function rightMask(uint8 _len) private pure returns (uint256 mask) {
mask = (1 << uint256(_len)) - 1;
Expand Down Expand Up @@ -220,6 +243,11 @@ library TypedMemView {
return uint256(index(memView, _index, _bytes)) >> ((32 - _bytes) * 8);
}

/// Parse an unsigned integer from LE bytes.
function indexLEUint(bytes32 memView, uint256 _index, uint8 _bytes) internal pure returns (uint256 result) {
return reverseUint256(uint256(index(memView, _index, _bytes))) & rightMask(_bytes * 8);
}

/// Parse a signed integer from the view at `_index`. Requires that the
/// view have >= `_bytes` bytes following that index.
function indexInt(bytes32 memView, uint256 _index, uint8 _bytes) internal pure returns (int256 result) {
Expand Down
7 changes: 6 additions & 1 deletion solidity/contracts/test/TestMemView.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ contract TestMemView {
);
}

function slicing() public pure {
function slicing() public {
// 76 bytes - 3 words

// solium-disable-next-line max-len
Expand Down Expand Up @@ -152,6 +152,11 @@ contract TestMemView {
"index mismatch 14 byte uint"
);

require(
v1.indexLEUint(0, 14) == 0x0d0c0b0a09080706050403020100,
"index mismatch 14 byte uint le"
);

require(
v1.indexInt(0, 14) == 0x000102030405060708090a0b0c0d,
"index mismatch 14 byte int"
Expand Down

0 comments on commit 3a35db8

Please sign in to comment.