How do I copy the contents of a &[u8]
slice?
I'm trying to write a function that takes a buffer as input and XOR's each byte with the given key and returns the final result.
I don't want it to mangle the input buffer.
pub fn xor_buffer(buffer_in: &[u8], key: char) -> &[u8] {
let mut buffer_out = buffer_in.clone();
for byte in &mut buffer_out[..] {
*byte ^= key as u8;
}
buffer_out
}
This code generates the following compile time error:
src/test.rs:29:22: 29:32 error: cannot borrow immutable borrowed content `*buffer_out` as mutable
src/test.rs:29 for byte in &mut buffer_out[..] {
^~~~~~~~~~
I know I have to be doing something wrong.
Any help would be apprecieated.
Select Tools > Organize Pages. Select the page you want to duplicate. Hold down the Ctrl key and drag the page with your mouse to a new position to create a duplicate.
Press Ctrl + C on your keyboard. Tip: Another way to copy your highlighted text is to click Home > Copy.
Right-click the original file and choose Copy (Ctrl+C). Put the mouse cursor on wherever you want a copy to appear, right-click this area and choose Paste (Ctrl+V). Done! Your new Word document is saved and marked as a copy.
First of all, you can't clone
a [T]
(irrespective of T
). Line 3 is not cloning the buffer, it's cloning the pointer to it. If you change the binding to
let mut buffer_out: &[u8] = buffer_in.clone();
you get the same error. If you want an independent copy of a slice, you need to turn it into a Vec
or some other owned container type; that can be done by using buffer_in.to_owned()
(which generically goes from a borrowed kind of thing to the owned equivalent).
Secondly, you cannot return a borrow to something you created in a function. You can't. No, really. No, not even doing that. Or that. You can only return a borrow (like &[u8]
) if the return value is directly borrowed from one of your arguments. That is not true here, so the return type must be Vec<u8>
or something else that's owned.
Thirdly, making a copy of the array and then mutating it is probably going to be inefficient. Ideally, you want to do your modifications in as few passes as possible (whilst avoiding even slower things like unnecessary allocations). You can do this using iterators.
Fourth, there's no guarantee key
's value actually fits in a u8
. You should probably change it to take key: u8
to make it clear to the caller what the valid range of values is.
So, all together:
pub fn xor_buffer(buffer_in: &[u8], key: u8) -> Vec<u8> {
// Get an iterator of `&u8`s from `buffer_in`.
buffer_in.iter()
// Replace each element with the xor'ed value.
.map(|byte| *byte ^ key)
// Collect the iterator into an owned collection.
.collect()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With