Skip to content

Instantly share code, notes, and snippets.

@axic
Created December 2, 2016 09:34
Show Gist options
  • Save axic/3746cb1228ced4345ae882d8ec9773b9 to your computer and use it in GitHub Desktop.
Save axic/3746cb1228ced4345ae882d8ec9773b9 to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.6;
contract MemcpyTest {
function test(string input) returns (string output) {
uint len = bytes(input).length;
output = new string(len);
uint _input;
uint _output;
assembly {
_input := add(input, 32)
_output := add(output, 32)
}
memcpySolidity(_output, _input, len);
}
function memcpyIdentity(uint _dst, uint _src, uint _len) private {
assembly {
let cost := add(15, mul(3, _len))
jumpi(invalidJumpLabel, iszero(call(cost, 4, 0, _src, _len, _dst, _len)))
}
}
function memcpyAssembly(uint dst, uint src, uint len) private {
assembly {
// copy 32 bytes at once
start32:
jumpi(end32, lt(len, 32))
mstore(dst, mload(src))
dst := add(dst, 32)
src := add(src, 32)
len := sub(len, 32)
jump(start32)
end32:
// copy the last byte
let mask := exp(256, sub(31, len))
let srcpart := and(mload(src), not(mask))
let dstpart := and(mload(dst), mask)
mstore(dst, or(srcpart, dstpart))
}
}
// from Arachnid/solidity-stringutils
function memcpySolidity(uint dest, uint src, uint len) private {
// Copy word-length chunks while possible
for(; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
// Copy remaining bytes
uint mask = 256 ** (32 - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment