From the example here, I could split bytes32 to bytes16. But I am unable to use a similar approach to split bytes9 into three parts. Can someone help me understand what am I doing wrong?
//working
function split2(bytes32 source) constant returns (bytes16, bytes16){
bytes16[2] memory y = [bytes16(0), 0];
assembly {
mstore(y, source)
mstore(add(y, 16), source)
}
return (y[0], y[1]);
}
//not working
function split3(bytes9 source) constant returns (bytes3, bytes3, bytes3){
bytes3[3] memory y = [bytes3(0), 0, 0];
assembly {
mstore(y, source)
mstore(add(y, 3), source)
mstore(add(y, 6), source)
}
return (y[0], y[1], y[2]);
}
bytes3in the array is atx+0. The second is atx+32, and the third is atx+64. In the source, the offset of the first three bytes is0, the second three bytes is3, and the third three bytes is6. So to copy everything to the right place, we takexand add the offset of thebytes3we care about and then subtract the offset of the bytes we care about in the source. The offsets are thenx+0-0,x+32-3, andx+64-6. – user19510 Jan 05 '18 at 19:32benjaminion, you mentioned, this to be a bad hack. What would be the right way? I just discovered passing strings as function argument is a bad idea becasue of gas issues, so I am replacing string with bytesn. Do you suggest, I just stick to bytes32?
– Titu Jan 05 '18 at 20:29x = (source >> 24) & 0xffffffto extract bytes 3-5 (you can do this today, but the cost may be high if the compiler decides to do>>with anEXPopcode, which it sometimes does. For certain cases, something likex = (source / 0x1000000)&0xffffffcould be efficient. – benjaminion Jan 05 '18 at 21:11