Hey all, I'm writing a torrent client which involves reading bytes over a UdpSocket
/TcpStream
. I'm using the byteorder
crate to read values in BigEndian order, as specified by the bittorrent protocol. The crate defines these in a trait named ReadBytesExt
and provides examples like:
let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
I myself am using an array rather than a vector to read messages from the connection. I tried using a [u8; 512]
, like so:
fn error() {
let buffer = [0u8; 64];
let c = Cursor::new(buffer);
let msg = c.read_u32::<BigEndian>();
}
error[E0599]: no method named `read_u32` found for struct `std::io::Cursor<&[u8; 64]>` in the current scope
It seems I can get around this with two different strategies:
- Use a vector instead, which seems a bit wasteful as the data is copied (right?)
let c = Cursor::new(buffer.to_vec());
let msg = c.read_u32::<BigEndian>();
- Pass the buffer to a function which expects a reference to an unsized array
fn workaround(buffer: &[u8]) -> u32 {
let c = Cursor::new(buffer)
let msg = c.read_u32::<BigEndian>();
msg
}
If there is an implementation for std::io::Cursor<&[u8]>
, why are there also implementations for fixed size arrays? Is this for optimization reasons? Something I'm missing about arrays?
How can I use this implementation without having to construct another function to "omit" the size from the reference? Or is there something idiomatic I am missing when it comes to reading "large" (>32), non-fixed size payloads? I was planning on using a vector to build messages that are larger than the buffer (when needed)