+ let data_size = try_read_io!(input.read_be_u16());
+
+ match try_read_io!(input.read_byte()) {
+ 0 => {
+ let mut command = CommandPacket { timestamp: try_read_io!(input.read_be_u64()), id: 0, payload: vec!() };
+ let mut encrypted_data = Vec::from_elem(data_size as uint, 0u8);
+ if try_read_io!(input.read(encrypted_data.as_mut_slice_())) != data_size as uint {
+ return Err(IOReadError(io::IoError { kind: io::EndOfFile, desc: "Unable to read all encrypted data", detail: None }));
+ }
+
+ let data = crypto::decrypt(encrypted_data.as_slice(), iv_from_timestamp(command.timestamp).as_slice());
+ if data.len() < MIN_PAYLOAD_SIZE + 2 || data.len() > MAX_PAYLOAD_SIZE + 2 {
+ return Err(UnconsistentDataSizeError)
+ }
+
+ Ok(Command(command))
+ },
+ t if t == 0x0A || t == 0x0B => {
+ let mut error = ErrorPacket { t: if t == 0x0A { DecryptError } else { AuthError }, timestamp: try_read_io!(input.read_be_u64()) };
+ // TODO
+ Ok(Error(error))
+ },
+ _ => Err(UnknownPacketTypeReadError),
+ }