forked from multiformats/rust-multiaddr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change internal representation of the
Multiaddr
main struct to `Vec…
…<Addr>` instead of `Vec<u8>` (multiformats#19)
- Loading branch information
Showing
3 changed files
with
81 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,48 @@ | ||
use std::str::FromStr; | ||
use std::fmt::Write; | ||
|
||
use integer_encoding::{VarInt, VarIntWriter}; | ||
|
||
use protocol::Protocol; | ||
use protocol::{Addr, AddressSegment, Protocol}; | ||
use {Result, Error}; | ||
|
||
pub fn multiaddr_from_str(input: &str) -> Result<Vec<u8>> { | ||
// drdop trailing slashes | ||
pub fn multiaddr_from_str(input: &str) -> Result<Vec<Addr>> { | ||
// Drop trailing slashes then split address into segment parts | ||
let input = input.trim_right_matches('/'); | ||
|
||
let mut bytes = vec![]; | ||
let mut parts = input.split('/'); | ||
let next = parts.next().ok_or(Error::InvalidMultiaddr)?; | ||
|
||
if !next.is_empty() { | ||
// Expect address to start with just a slash ('/') | ||
let first = parts.next().ok_or(Error::InvalidMultiaddr)?; | ||
if !first.is_empty() { | ||
return Err(Error::InvalidMultiaddr); | ||
} | ||
|
||
let mut multiaddr = Vec::with_capacity(input.split('/').count()); | ||
while let Some(n) = parts.next() { | ||
// Determine segment protocol number and possible extra data | ||
let p = Protocol::from_str(n)?; | ||
|
||
bytes.write_varint(p as u64)?; | ||
|
||
if p.size() == 0 { | ||
continue; | ||
} | ||
|
||
let next = match parts.next() { | ||
Some(path) => path, | ||
None => return Err(Error::MissingAddress), | ||
let s = match p.size() { | ||
0 => &"", | ||
_ => parts.next().ok_or(Error::MissingAddress)? | ||
}; | ||
|
||
bytes.extend(p.string_to_bytes(next)?); | ||
} | ||
|
||
Ok(bytes) | ||
} | ||
|
||
fn read_varint_code(input: &[u8]) -> Result<(u64, usize)> { | ||
let res = u64::decode_var(input); | ||
|
||
if res.0 == 0 { | ||
return Err(Error::ParsingError) | ||
} | ||
|
||
Ok(res) | ||
} | ||
|
||
fn size_for_addr(protocol: Protocol, input: &[u8]) -> Result<(usize, usize)> { | ||
if protocol.size() > 0 { | ||
Ok((protocol.size() as usize / 8, 0)) | ||
} else if protocol.size() == 0 { | ||
Ok((0, 0)) | ||
} else { | ||
let (size, n) = read_varint_code(input)?; | ||
Ok((size as usize, n)) | ||
} | ||
} | ||
|
||
pub fn protocol_from_bytes(input: &[u8]) -> Result<Vec<Protocol>> { | ||
let mut ps = vec![]; | ||
let mut i = 0; | ||
|
||
while i < input.len() { | ||
let (code, n) = read_varint_code(&input[i..])?; | ||
let p = Protocol::from(code)?; | ||
ps.push(p); | ||
|
||
i += n; | ||
let (size, adv) = size_for_addr(p, &input[i..])?; | ||
i += size + adv; | ||
// Parse and store segment data | ||
multiaddr.push(Addr::from_protocol_str(p, s)?); | ||
} | ||
|
||
Ok(ps) | ||
Ok(multiaddr) | ||
} | ||
|
||
|
||
pub fn address_from_bytes(input: &[u8]) -> Result<String> { | ||
let mut protos = vec!["".to_string()]; | ||
let mut i = 0; | ||
|
||
while i < input.len() { | ||
pub fn multiaddr_to_str(addr: &Vec<Addr>) -> String { | ||
let mut result = String::new(); | ||
|
||
let (code, n) = read_varint_code(&input[i..])?; | ||
i += n; | ||
for addr_segment in addr { | ||
result.push('/'); | ||
result.push_str(addr_segment.protocol().as_str()); | ||
|
||
let p = Protocol::from(code)?; | ||
protos.push(p.to_string()); | ||
|
||
let (size, adv) = size_for_addr(p, &input[i..])?; | ||
i += adv; | ||
|
||
if let Some(s) = p.bytes_to_string(&input[i..i + size])? { | ||
protos.push(s); | ||
if addr_segment.protocol().size() != 0 { | ||
write!(result, "/{}", addr_segment).unwrap(); | ||
} | ||
|
||
i += size; | ||
} | ||
|
||
Ok(protos.join("/")) | ||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters