Created
August 2, 2014 19:51
-
-
Save dckc/1f7f6937483c7c34c579 to your computer and use it in GitHub Desktop.
closure lifetime issues
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
pub fn decode_id_string(buf: &[u8]) -> IoResult<ServerProtocol> { | |
debug!("decode_id_string(buf={})", buf); | |
if buf.len() != 32 { | |
return Err(IoError{ kind: InvalidInput, desc: "id string length must be 32", detail: None}); | |
} | |
let pick_attr = |i: uint| { | |
let offset = i * 4; | |
let bytes = buf.slice(offset, offset + 4); | |
match from_utf8(buf.slice(offset, offset + 4)) { | |
Some(str) => Ok(str), | |
None => Err(bytes) | |
} | |
}; | |
let check = |attr: AttrIndex, expected| { | |
match pick_attr(attr as uint) { | |
Ok(txt) if txt == expected => Ok(txt), | |
Ok(txt) => Err(IoError{ kind: InvalidInput, desc: "unsupported attribute", | |
detail: Some(format!("expected {} for {} but got {}", | |
expected, attr, txt)) }), | |
Err(bytes) => Err(IoError{ kind: InvalidInput, desc: "attribute not utf-8", | |
detail: Some(format!("attribute: {} is {}", attr, bytes)) }) | |
} | |
}; | |
try!(check(IDsig, "Rsrv")); | |
try!(check(Protocol, "QAP1")); | |
let version = pick_attr(ServerVersion as uint).unwrap_or(""); | |
let attrs = range_inclusive(Opt4 as uint, Opt8 as uint).map(|ix| { | |
let offset = ix * 4; | |
let bt = |i| buf[offset + i]; | |
let ch = |i| bt(i) as char; | |
let other = || AnyAttr({ | |
let bytes = buf.slice(offset, offset + 4); | |
match from_utf8(bytes) { | |
Some(txt) => Ok(txt.to_string()), | |
None => Err((bt(0), bt(1), bt(2), bt(3))) | |
} | |
}); | |
match (ch(0), ch(1)) { | |
('R', _) => match (ch(1).to_digit(10), | |
ch(2).to_digit(10), | |
ch(3).to_digit(10)) { | |
(Some(d1), Some(d2), Some(d3)) => RVersion(d1 as u8, d2 as u8, d3 as u8), | |
_ => other() | |
}, | |
('A', 'R') => AuthorizationRequired(match (ch(2), ch(3)) { | |
('p', 't') => PlainText, | |
('u', 'c') => UnixCrypt, | |
('m', '5') => MD5, | |
(_, _) => AnyAuth(ch(2), ch(3)) | |
}), | |
('K', _) => Key(bt(1), bt(2), bt(3)), | |
(_, _) => other() | |
} | |
}).collect(); | |
Ok(QAP1(version.to_string(), attrs)) | |
} | |
pub trait ReadIDString { | |
fn read_id_string(&mut self) -> IoResult<ServerProtocol>; | |
} | |
impl<R: Reader> ReadIDString for R { | |
fn read_id_string(&mut self) -> IoResult<ServerProtocol> { | |
let mut buf = [0u8, ..32]; | |
try!(self.read_at_least(32, buf)); | |
decode_id_string(buf) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment