use std::io::{self, Read, Write};
use crate::{
__impl_index,
io::{ReadFrom, TooLongError, WriteTo},
message::Message,
net_addr::NetAddr,
packet::Command,
var_type::VarInt,
};
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Addr {
list: Vec<NetAddr>,
}
impl AsRef<[NetAddr]> for Addr {
fn as_ref(&self) -> &[NetAddr] {
&self.list
}
}
__impl_index!(Addr, list, NetAddr);
impl Addr {
pub const MAX_COUNT: usize = 1000;
pub fn new(list: Vec<NetAddr>) -> Result<Self, TooLongError> {
if list.len() > Self::MAX_COUNT {
return Err(TooLongError::new(Self::MAX_COUNT, list.len()));
}
Ok(Self { list })
}
}
impl WriteTo for Addr {
fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
let count: VarInt = self.list.len().into();
count.write_to(w)?;
for a in &self.list {
a.write_to(w)?
}
Ok(())
}
}
impl ReadFrom for Addr {
fn read_from(r: &mut dyn Read) -> io::Result<Self>
where
Self: Sized,
{
let count = VarInt::read_from(r)?;
if count.as_u64() > Self::MAX_COUNT as u64 {
return Err(io::Error::new(
io::ErrorKind::Other,
TooLongError::new(Self::MAX_COUNT, count.as_u64() as usize),
));
}
let mut list = Vec::<NetAddr>::new();
for _ in 0..count.as_u64() {
list.push(NetAddr::read_from(r)?);
}
Ok(Self { list })
}
}
impl Message for Addr {
const COMMAND: Command = Command::ADDR;
}
#[test]
fn test_addr_write_to() {
use crate::{message::version::LOCAL_SOCKET_ADDR, net_addr::Services};
let addr0 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr1 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr2 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let test = Addr::new([addr0, addr1, addr2].to_vec()).unwrap();
let mut bytes = Vec::new();
test.write_to(&mut bytes).unwrap();
let expected = [
3, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, ];
assert_eq!(bytes, expected.to_vec());
}
#[test]
fn test_addr_read_from() {
use std::io::Cursor;
use crate::{message::version::LOCAL_SOCKET_ADDR, net_addr::Services};
let mut bytes = Cursor::new(
[
3, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1, 0x20, 0xfc, ]
.to_vec(),
);
let test = Addr::read_from(&mut bytes).unwrap();
let addr0 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr1 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let addr2 = NetAddr::new(
0x0123_4567_89ab_cdef.into(),
1.into(),
Services::NETWORK,
LOCAL_SOCKET_ADDR.clone(),
);
let expected = Addr::new([addr0, addr1, addr2].to_vec()).unwrap();
assert_eq!(test, expected);
}