<commit_before>//! Messages to and from the server.
use std::borrow::ToOwned;
use std::str::FromStr;

/// IRC Message data.
#[derive(Clone, PartialEq, Debug)]
pub struct Message {
    /// Message tags as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html).
    pub tags: Option<Vec<Tag>>,
    /// The message prefix (or source) as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
    pub prefix: Option<String>,
    /// The IRC command as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
    pub command: String,
    /// The command arguments.
    pub args: Vec<String>,
    /// The message suffix as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
    /// This is the only part of the message that is allowed to contain spaces.
    pub suffix: Option<String>,
}

impl Message {
    /// Creates a new Message.
    pub fn new(prefix: Option<&str>, command: &str, args: Option<Vec<&str>>, suffix: Option<&str>)
        -> Message {
        Message::with_tags(None, prefix, command, args, suffix)
    }

    /// Creates a new Message optionally including IRCv3.2 message tags.
    pub fn with_tags(tags: Option<Vec<Tag>>, prefix: Option<&str>, command: &str,
                     args: Option<Vec<&str>>, suffix: Option<&str>) -> Message {
        Message {
            tags: tags,
            prefix: prefix.map(|s| s.to_owned()),
            command: command.to_owned(),
            args: args.map_or(Vec::new(), |v| v.iter().map(|&s| s.to_owned()).collect()),
            suffix: suffix.map(|s| s.to_owned()),
        }
    }

    /// Creates a new Message from already owned data.
    pub fn from_owned(prefix: Option<String>, command: String, args: Option<Vec<String>>,
                      suffix: Option<String>) -> Message {
        Message {
            tags: None, prefix: prefix, command: command, args: args.unwrap_or(Vec::new()), suffix: suffix
        }
    }

    /// Gets the nickname of the message source, if it exists.
    pub fn get_source_nickname(&self) -> Option<&str> {
        self.prefix.as_ref().and_then(|s| s.find('!').map(|i| &s[..i]))
    }

    /// Converts a Message into a String according to the IRC protocol.
    pub fn into_string(&self) -> String {
        let mut ret = String::new();
        if let Some(ref prefix) = self.prefix {
            ret.push(':');
            ret.push_str(&prefix);
            ret.push(' ');
        }
        ret.push_str(&self.command);
        for arg in self.args.iter() {
            ret.push(' ');
            ret.push_str(&arg);
        }
        if let Some(ref suffix) = self.suffix {
            ret.push_str(" :");
            ret.push_str(&suffix);
        }
        ret.push_str("\r\n");
        ret
    }
}

impl FromStr for Message {
    type Err = &'static str;
    fn from_str(s: &str) -> Result<Message, &'static str> {
        let mut state = s.clone();
        if s.len() == 0 { return Err("Cannot parse an empty string as a message.") }
        let tags = if state.starts_with("@") {
            let tags = state.find(' ').map(|i| &state[1..i]);
            state = state.find(' ').map_or("", |i| &state[i+1..]);
            tags.map(|ts| ts.split(";").filter(|s| s.len() != 0).map(|s: &str| {
                let mut iter = s.splitn(2, "=");
                let (fst, snd) = (iter.next(), iter.next());
                Tag(fst.unwrap_or("").to_owned(), snd.map(|s| s.to_owned()))
            }).collect::<Vec<_>>())
        } else {
            None
        };
        let prefix = if state.starts_with(":") {
            let prefix = state.find(' ').map(|i| &state[1..i]);
            state = state.find(' ').map_or("", |i| &state[i+1..]);
            prefix
        } else {
            None
        };
        let suffix = if state.contains(" :") {
            let suffix = state.find(" :").map(|i| &state[i+2..state.len()-2]);
            state = state.find(" :").map_or("", |i| &state[..i+1]);
            suffix
        } else {
            None
        };
        let command = match state.find(' ').map(|i| &state[..i]) {
            Some(cmd) => {
                state = state.find(' ').map_or("", |i| &state[i+1..]);
                cmd
            }
            _ => return Err("Cannot parse a message without a command.")
        };
        if suffix.is_none() { state = &state[..state.len() - 2] }
        let args: Vec<_> = state.splitn(14, ' ').filter(|s| s.len() != 0).collect();
        Ok(Message::with_tags(
            tags, prefix, command, if args.len() > 0 { Some(args) } else { None }, suffix
        ))
    }
}

impl<'a> From<&'a str> for Message {
    fn from(s: &'a str) -> Message {
        s.parse().unwrap()
    }
}

/// A message tag as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html).
#[derive(Clone, PartialEq, Debug)]
pub struct Tag(String, Option<String>);

#[cfg(test)]
mod test {
    use super::{Message, Tag};

    #[test]
    fn new() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        assert_eq!(Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("Testing!")), message);
    }

    #[test]
    fn get_source_nickname() {
        assert_eq!(Message::new(None, "PING", None, None).get_source_nickname(), None);
        assert_eq!(Message::new(
            Some("irc.test.net"), "PING", None, None
        ).get_source_nickname(), None);
        assert_eq!(Message::new(
            Some("test!test@test"), "PING", None, None
        ).get_source_nickname(), Some("test"));
    }

    #[test]
    fn into_string() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        assert_eq!(&message.into_string()[..], "PRIVMSG test :Testing!\r\n");
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Still testing!")),
        };
        assert_eq!(&message.into_string()[..], ":test!test@test PRIVMSG test :Still testing!\r\n");
    }

    #[test]
    fn from_string() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        assert_eq!("PRIVMSG test :Testing!\r\n".parse(), Ok(message));
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Still testing!")),
        };
        assert_eq!(":test!test@test PRIVMSG test :Still testing!\r\n".parse(), Ok(message));
        let message = Message {
            tags: Some(vec![Tag(format!("aaa"), Some(format!("bbb"))),
                            Tag(format!("ccc"), None),
                            Tag(format!("example.com/ddd"), Some(format!("eee")))]),
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing with tags!")),
        };
        assert_eq!("@aaa=bbb;ccc;example.com/ddd=eee :test!test@test PRIVMSG test :Testing with \
                    tags!\r\n".parse(), Ok(message))
    }

    #[test]
    fn to_message() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        let msg: Message = "PRIVMSG test :Testing!\r\n".into();
        assert_eq!(msg, message);
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Still testing!")),
        };
        let msg: Message = ":test!test@test PRIVMSG test :Still testing!\r\n".into();
        assert_eq!(msg, message);
    }

    #[test]
    fn to_message_with_colon_in_arg() {
        // Apparently, UnrealIRCd (and perhaps some others) send some messages that include
        // colons within individual parameters. So, let's make sure it parses correctly.
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("COMMAND"),
            args: vec![format!("ARG:test")],
            suffix: Some(format!("Testing!")),
        };
        let msg: Message = ":test!test@test COMMAND ARG:test :Testing!\r\n".into();
        assert_eq!(msg, message);
    }

    #[test]
    #[should_panic]
    fn to_message_invalid_format() {
        let _: Message = ":invalid :message".into();
    }
}
<commit_msg>Updated get_source_nickname behavior to match spec (fixes #40).<commit_after>//! Messages to and from the server.
use std::borrow::ToOwned;
use std::str::FromStr;

/// IRC Message data.
#[derive(Clone, PartialEq, Debug)]
pub struct Message {
    /// Message tags as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html).
    pub tags: Option<Vec<Tag>>,
    /// The message prefix (or source) as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
    pub prefix: Option<String>,
    /// The IRC command as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
    pub command: String,
    /// The command arguments.
    pub args: Vec<String>,
    /// The message suffix as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
    /// This is the only part of the message that is allowed to contain spaces.
    pub suffix: Option<String>,
}

impl Message {
    /// Creates a new Message.
    pub fn new(prefix: Option<&str>, command: &str, args: Option<Vec<&str>>, suffix: Option<&str>)
        -> Message {
        Message::with_tags(None, prefix, command, args, suffix)
    }

    /// Creates a new Message optionally including IRCv3.2 message tags.
    pub fn with_tags(tags: Option<Vec<Tag>>, prefix: Option<&str>, command: &str,
                     args: Option<Vec<&str>>, suffix: Option<&str>) -> Message {
        Message {
            tags: tags,
            prefix: prefix.map(|s| s.to_owned()),
            command: command.to_owned(),
            args: args.map_or(Vec::new(), |v| v.iter().map(|&s| s.to_owned()).collect()),
            suffix: suffix.map(|s| s.to_owned()),
        }
    }

    /// Creates a new Message from already owned data.
    pub fn from_owned(prefix: Option<String>, command: String, args: Option<Vec<String>>,
                      suffix: Option<String>) -> Message {
        Message {
            tags: None, prefix: prefix, command: command, args: args.unwrap_or(Vec::new()), suffix: suffix
        }
    }

    /// Gets the nickname of the message source, if it exists.
    pub fn get_source_nickname(&self) -> Option<&str> {
        self.prefix.as_ref().and_then(|s|
            match (s.find('!'), s.find('@'), s.find('.')) {
                (_, _, Some(_)) => None,
                (Some(i), _, None) => Some(&s[..i]),
                (None, Some(i), None) => Some(&s[..i]),
                (None, None, None) => Some(&s)
            }
        )
    }

    /// Converts a Message into a String according to the IRC protocol.
    pub fn into_string(&self) -> String {
        let mut ret = String::new();
        if let Some(ref prefix) = self.prefix {
            ret.push(':');
            ret.push_str(&prefix);
            ret.push(' ');
        }
        ret.push_str(&self.command);
        for arg in self.args.iter() {
            ret.push(' ');
            ret.push_str(&arg);
        }
        if let Some(ref suffix) = self.suffix {
            ret.push_str(" :");
            ret.push_str(&suffix);
        }
        ret.push_str("\r\n");
        ret
    }
}

impl FromStr for Message {
    type Err = &'static str;
    fn from_str(s: &str) -> Result<Message, &'static str> {
        let mut state = s.clone();
        if s.len() == 0 { return Err("Cannot parse an empty string as a message.") }
        let tags = if state.starts_with("@") {
            let tags = state.find(' ').map(|i| &state[1..i]);
            state = state.find(' ').map_or("", |i| &state[i+1..]);
            tags.map(|ts| ts.split(";").filter(|s| s.len() != 0).map(|s: &str| {
                let mut iter = s.splitn(2, "=");
                let (fst, snd) = (iter.next(), iter.next());
                Tag(fst.unwrap_or("").to_owned(), snd.map(|s| s.to_owned()))
            }).collect::<Vec<_>>())
        } else {
            None
        };
        let prefix = if state.starts_with(":") {
            let prefix = state.find(' ').map(|i| &state[1..i]);
            state = state.find(' ').map_or("", |i| &state[i+1..]);
            prefix
        } else {
            None
        };
        let suffix = if state.contains(" :") {
            let suffix = state.find(" :").map(|i| &state[i+2..state.len()-2]);
            state = state.find(" :").map_or("", |i| &state[..i+1]);
            suffix
        } else {
            None
        };
        let command = match state.find(' ').map(|i| &state[..i]) {
            Some(cmd) => {
                state = state.find(' ').map_or("", |i| &state[i+1..]);
                cmd
            }
            _ => return Err("Cannot parse a message without a command.")
        };
        if suffix.is_none() { state = &state[..state.len() - 2] }
        let args: Vec<_> = state.splitn(14, ' ').filter(|s| s.len() != 0).collect();
        Ok(Message::with_tags(
            tags, prefix, command, if args.len() > 0 { Some(args) } else { None }, suffix
        ))
    }
}

impl<'a> From<&'a str> for Message {
    fn from(s: &'a str) -> Message {
        s.parse().unwrap()
    }
}

/// A message tag as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html).
#[derive(Clone, PartialEq, Debug)]
pub struct Tag(String, Option<String>);

#[cfg(test)]
mod test {
    use super::{Message, Tag};

    #[test]
    fn new() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        assert_eq!(Message::new(None, "PRIVMSG", Some(vec!["test"]), Some("Testing!")), message);
    }

    #[test]
    fn get_source_nickname() {
        assert_eq!(Message::new(None, "PING", None, None).get_source_nickname(), None);
        assert_eq!(Message::new(
            Some("irc.test.net"), "PING", None, None
        ).get_source_nickname(), None);
        assert_eq!(Message::new(
            Some("test!test@test"), "PING", None, None
        ).get_source_nickname(), Some("test"));
        assert_eq!(Message::new(
            Some("test@test"), "PING", None, None
        ).get_source_nickname(), Some("test"));
        assert_eq!(Message::new(
            Some("test"), "PING", None, None
        ).get_source_nickname(), Some("test"));
    }

    #[test]
    fn into_string() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        assert_eq!(&message.into_string()[..], "PRIVMSG test :Testing!\r\n");
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Still testing!")),
        };
        assert_eq!(&message.into_string()[..], ":test!test@test PRIVMSG test :Still testing!\r\n");
    }

    #[test]
    fn from_string() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        assert_eq!("PRIVMSG test :Testing!\r\n".parse(), Ok(message));
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Still testing!")),
        };
        assert_eq!(":test!test@test PRIVMSG test :Still testing!\r\n".parse(), Ok(message));
        let message = Message {
            tags: Some(vec![Tag(format!("aaa"), Some(format!("bbb"))),
                            Tag(format!("ccc"), None),
                            Tag(format!("example.com/ddd"), Some(format!("eee")))]),
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing with tags!")),
        };
        assert_eq!("@aaa=bbb;ccc;example.com/ddd=eee :test!test@test PRIVMSG test :Testing with \
                    tags!\r\n".parse(), Ok(message))
    }

    #[test]
    fn to_message() {
        let message = Message {
            tags: None,
            prefix: None,
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Testing!")),
        };
        let msg: Message = "PRIVMSG test :Testing!\r\n".into();
        assert_eq!(msg, message);
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("PRIVMSG"),
            args: vec![format!("test")],
            suffix: Some(format!("Still testing!")),
        };
        let msg: Message = ":test!test@test PRIVMSG test :Still testing!\r\n".into();
        assert_eq!(msg, message);
    }

    #[test]
    fn to_message_with_colon_in_arg() {
        // Apparently, UnrealIRCd (and perhaps some others) send some messages that include
        // colons within individual parameters. So, let's make sure it parses correctly.
        let message = Message {
            tags: None,
            prefix: Some(format!("test!test@test")),
            command: format!("COMMAND"),
            args: vec![format!("ARG:test")],
            suffix: Some(format!("Testing!")),
        };
        let msg: Message = ":test!test@test COMMAND ARG:test :Testing!\r\n".into();
        assert_eq!(msg, message);
    }

    #[test]
    #[should_panic]
    fn to_message_invalid_format() {
        let _: Message = ":invalid :message".into();
    }
}
<|endoftext|>


<commit_before>use std::sync::{Arc, RwLock};

use rocksdb::{DB, WriteBatch};

use proto::metapb;
use proto::raftpb;
use raft::{self, Ready, RawNode};
use raftserver::{Result, other};
use super::store::Store;
use super::peer_storage::{self, PeerStorage, RaftStorage, ApplySnapResult};
use super::util;

pub struct Peer {
    engine: Arc<DB>,
    store_id: u64,
    peer_id: u64,
    region_id: u64,
    pub raft_group: RawNode<RaftStorage>,
    pub storage: Arc<RwLock<PeerStorage>>,
}

impl Peer {
    // If we create the peer actively, like bootstrap/split/merge region, we should
    // use this function to create the peer. The region must contain the peer info
    // for this store.
    pub fn create(store: &mut Store, region: metapb::Region) -> Result<Peer> {
        let store_id = store.get_store_id();
        let peer_id = match util::find_peer(&region, store_id) {
            None => return Err(other(format!("find no peer for store {}", store_id))),
            Some(peer) => peer.get_peer_id(),
        };

        Peer::new(store, region, peer_id)
    }

    // The peer can be created from another node with raft membership changes, and we only
    // know the region_id and peer_id when creating this replicated peer, the region info
    // will be retrieved later after appling snapshot.
    pub fn replicate(store: &mut Store, region_id: u64, peer_id: u64) -> Result<Peer> {
        let mut region = metapb::Region::new();
        region.set_region_id(region_id);
        Peer::new(store, region, peer_id)
    }

    fn new(store: &mut Store, region: metapb::Region, peer_id: u64) -> Result<Peer> {
        let store_id = store.get_store_id();

        let s = try!(PeerStorage::new(store.get_engine(), &region));

        let applied_index = s.applied_index();
        let storage = Arc::new(RwLock::new(s));

        let cfg = store.get_config();
        let raft_cfg = raft::Config {
            id: peer_id,
            peers: vec![],
            election_tick: cfg.raft_election_timeout_ticks,
            heartbeat_tick: cfg.raft_heartbeat_ticks,
            max_size_per_msg: cfg.raft_max_size_per_msg,
            max_inflight_msgs: cfg.raft_max_inflight_msgs,
            applied: applied_index,
            check_quorum: false,
            storage: Arc::new(RaftStorage::new(storage.clone())),
        };

        let raft_group = try!(RawNode::new(&raft_cfg, &[]));

        let mut peer = Peer {
            engine: store.get_engine(),
            store_id: store_id,
            peer_id: peer_id,
            region_id: region.get_region_id(),
            storage: storage,
            raft_group: raft_group,
        };

        // If this region has only one peer and I am the one, campaign directly.
        if region.get_peers().len() == 1 && region.get_peers()[0].get_store_id() == store_id {
            try!(peer.raft_group.campaign());
        }

        Ok(peer)
    }

    pub fn update_region(&mut self, region: &metapb::Region) -> Result<()> {
        if self.region_id != region.get_region_id() {
            return Err(other(format!("invalid region id {} != {}",
                                     region.get_region_id(),
                                     self.region_id)));
        }

        let mut store = self.storage.write().unwrap();
        store.set_region(region);
        Ok(())
    }

    pub fn get_region(&self) -> metapb::Region {
        let store = self.storage.read().unwrap();
        store.get_region().clone()
    }

    pub fn get_peer_id(&self) -> u64 {
        self.peer_id
    }

    pub fn get_raft_status(&self) -> raft::Status {
        self.raft_group.status()
    }

    pub fn handle_raft_ready(&mut self) -> Result<()> {
        if !self.raft_group.has_ready() {
            debug!("raft group is not ready for {}", self.peer_id);
            return Ok(());
        }

        debug!("handle raft ready for peer {} at region {}",
               self.peer_id,
               self.region_id);

        let ready = self.raft_group.ready();

        try!(self.handle_raft_ready_in_storage(&ready));

        for msg in &ready.messages {
            try!(self.send_raft_message(&msg));
        }

        try!(self.handle_raft_commit_entries(&ready.committed_entries));

        self.raft_group.advance(ready);
        Ok(())
    }

    fn handle_raft_ready_in_storage(&mut self, ready: &Ready) -> Result<()> {
        let batch = WriteBatch::new();
        let mut storage = self.storage.write().unwrap();
        let mut last_index = storage.last_index();
        let mut apply_snap_res: Option<ApplySnapResult> = None;
        if !raft::is_empty_snap(&ready.snapshot) {
            apply_snap_res = try!(storage.apply_snapshot(&batch, &ready.snapshot).map(|res| {
                last_index = res.last_index;
                Some(res)
            }));
        }

        if ready.entries.len() > 0 {
            last_index = try!(storage.append(&batch, last_index, &ready.entries));
        }

        if let Some(ref hs) = ready.hs {
            try!(peer_storage::save_hard_state(&batch, self.region_id, hs));
        }

        try!(self.engine.write(batch));

        storage.set_last_index(last_index);
        // If we apply snapshot ok, we should update some infos like applied index too.
        if let Some(res) = apply_snap_res {
            storage.set_applied_index(res.applied_index);
            storage.set_region(&res.region);
        }

        Ok(())
    }

    fn send_raft_message(&mut self, msg: &raftpb::Message) -> Result<()> {
        // TODO: implement it later.
        Ok(())
    }

    fn handle_raft_commit_entries(&mut self, committed_entries: &[raftpb::Entry]) -> Result<()> {
        // TODO: implement it later.
        Ok(())
    }
}
<commit_msg>raftserver: supports destroy peer data.<commit_after>use std::sync::{Arc, RwLock};

use rocksdb::{DB, WriteBatch, Writable};

use proto::metapb;
use proto::raftpb;
use raft::{self, Ready, RawNode};
use raftserver::{Result, other};
use super::store::Store;
use super::peer_storage::{self, PeerStorage, RaftStorage, ApplySnapResult};
use super::util;

pub struct Peer {
    engine: Arc<DB>,
    store_id: u64,
    peer_id: u64,
    region_id: u64,
    pub raft_group: RawNode<RaftStorage>,
    pub storage: Arc<RwLock<PeerStorage>>,
}

impl Peer {
    // If we create the peer actively, like bootstrap/split/merge region, we should
    // use this function to create the peer. The region must contain the peer info
    // for this store.
    pub fn create(store: &mut Store, region: metapb::Region) -> Result<Peer> {
        let store_id = store.get_store_id();
        let peer_id = match util::find_peer(&region, store_id) {
            None => return Err(other(format!("find no peer for store {}", store_id))),
            Some(peer) => peer.get_peer_id(),
        };

        Peer::new(store, region, peer_id)
    }

    // The peer can be created from another node with raft membership changes, and we only
    // know the region_id and peer_id when creating this replicated peer, the region info
    // will be retrieved later after appling snapshot.
    pub fn replicate(store: &mut Store, region_id: u64, peer_id: u64) -> Result<Peer> {
        let mut region = metapb::Region::new();
        region.set_region_id(region_id);
        Peer::new(store, region, peer_id)
    }

    fn new(store: &mut Store, region: metapb::Region, peer_id: u64) -> Result<Peer> {
        let store_id = store.get_store_id();

        let s = try!(PeerStorage::new(store.get_engine(), &region));

        let applied_index = s.applied_index();
        let storage = Arc::new(RwLock::new(s));

        let cfg = store.get_config();
        let raft_cfg = raft::Config {
            id: peer_id,
            peers: vec![],
            election_tick: cfg.raft_election_timeout_ticks,
            heartbeat_tick: cfg.raft_heartbeat_ticks,
            max_size_per_msg: cfg.raft_max_size_per_msg,
            max_inflight_msgs: cfg.raft_max_inflight_msgs,
            applied: applied_index,
            check_quorum: false,
            storage: Arc::new(RaftStorage::new(storage.clone())),
        };

        let raft_group = try!(RawNode::new(&raft_cfg, &[]));

        let mut peer = Peer {
            engine: store.get_engine(),
            store_id: store_id,
            peer_id: peer_id,
            region_id: region.get_region_id(),
            storage: storage,
            raft_group: raft_group,
        };

        // If this region has only one peer and I am the one, campaign directly.
        if region.get_peers().len() == 1 && region.get_peers()[0].get_store_id() == store_id {
            try!(peer.raft_group.campaign());
        }

        Ok(peer)
    }

    pub fn destroy(&mut self) -> Result<()> {
        // Delete all data in this peer.
        let mut store = self.storage.write().unwrap();
        let batch = WriteBatch::new();
        try!(store.scan_region(self.engine.as_ref(),
                               &mut |key, _| -> Result<bool> {
                                   try!(batch.delete(key));
                                   Ok(true)
                               }));

        try!(self.engine.write(batch));

        Ok(())
    }

    pub fn update_region(&mut self, region: &metapb::Region) -> Result<()> {
        if self.region_id != region.get_region_id() {
            return Err(other(format!("invalid region id {} != {}",
                                     region.get_region_id(),
                                     self.region_id)));
        }

        let mut store = self.storage.write().unwrap();
        store.set_region(region);
        Ok(())
    }

    pub fn get_region(&self) -> metapb::Region {
        let store = self.storage.read().unwrap();
        store.get_region().clone()
    }

    pub fn get_peer_id(&self) -> u64 {
        self.peer_id
    }

    pub fn get_raft_status(&self) -> raft::Status {
        self.raft_group.status()
    }

    pub fn handle_raft_ready(&mut self) -> Result<()> {
        if !self.raft_group.has_ready() {
            debug!("raft group is not ready for {}", self.peer_id);
            return Ok(());
        }

        debug!("handle raft ready for peer {} at region {}",
               self.peer_id,
               self.region_id);

        let ready = self.raft_group.ready();

        try!(self.handle_raft_ready_in_storage(&ready));

        for msg in &ready.messages {
            try!(self.send_raft_message(&msg));
        }

        try!(self.handle_raft_commit_entries(&ready.committed_entries));

        self.raft_group.advance(ready);
        Ok(())
    }

    fn handle_raft_ready_in_storage(&mut self, ready: &Ready) -> Result<()> {
        let batch = WriteBatch::new();
        let mut storage = self.storage.write().unwrap();
        let mut last_index = storage.last_index();
        let mut apply_snap_res: Option<ApplySnapResult> = None;
        if !raft::is_empty_snap(&ready.snapshot) {
            apply_snap_res = try!(storage.apply_snapshot(&batch, &ready.snapshot).map(|res| {
                last_index = res.last_index;
                Some(res)
            }));
        }

        if ready.entries.len() > 0 {
            last_index = try!(storage.append(&batch, last_index, &ready.entries));
        }

        if let Some(ref hs) = ready.hs {
            try!(peer_storage::save_hard_state(&batch, self.region_id, hs));
        }

        try!(self.engine.write(batch));

        storage.set_last_index(last_index);
        // If we apply snapshot ok, we should update some infos like applied index too.
        if let Some(res) = apply_snap_res {
            storage.set_applied_index(res.applied_index);
            storage.set_region(&res.region);
        }

        Ok(())
    }

    fn send_raft_message(&mut self, msg: &raftpb::Message) -> Result<()> {
        // TODO: implement it later.
        Ok(())
    }

    fn handle_raft_commit_entries(&mut self, committed_entries: &[raftpb::Entry]) -> Result<()> {
        // TODO: implement it later.
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::fmt;
use std::str::FromStr;

use grammar;
use kind::{TypeKind, StackKind};

pub trait KindVar {
    type Kind;

    fn new<S: ToString>(name: S) -> Self;

    fn gen() -> Self;
}

macro_rules! kind_var {
    ($KindVar:ident, $Kind:ident, $prefix:expr) => {
        #[derive(Clone, Debug, Hash, PartialEq)]
        pub struct $KindVar {
            name: String,
        }

        impl KindVar for $KindVar {
            type Kind = $Kind;

            fn new<S: ToString>(name: S) -> Self {
                $KindVar {
                    name: name.to_string(),
                }
            }

            fn gen() -> $KindVar {
                use std::cell::Cell;

                thread_local!(static NEXT_ID: Cell<usize> = Cell::new(0));

                NEXT_ID.with(|next_id| {
                    let id = next_id.get();
                    next_id.set(id + 1);

                    $KindVar::new(format!("{}${}", $prefix, id))
                })
            }
        }

        impl fmt::Display for $KindVar {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{}", self.name)
            }
        }
    };
}

kind_var!(TypeVar, TypeKind, "t");
kind_var!(StackVar, StackKind, "S");

impl FromStr for TypeVar {
    type Err = grammar::ParseError;

    fn from_str(src: &str) -> Result<TypeVar, grammar::ParseError> {
        grammar::type_var(src)
    }
}

impl FromStr for StackVar {
    type Err = grammar::ParseError;

    fn from_str(src: &str) -> Result<StackVar, grammar::ParseError> {
        grammar::stack_var(src)
    }
}

macro_rules! forall_fn {
    ($name:ident($($Var:ident),*)) => {
        #[allow(dead_code)]
        pub fn $name<F: FnOnce($($Var),*) -> Output, $($Var: KindVar,)* Output>(f: F) -> Output {
            f($($Var::gen()),*)
        }
    }
}

forall_fn!(forall1(Var1));
forall_fn!(forall2(Var1, Var2));
forall_fn!(forall3(Var1, Var2, Var3));
forall_fn!(forall4(Var1, Var2, Var3, Var4));
forall_fn!(forall5(Var1, Var2, Var3, Var4, Var5));
<commit_msg>Move FromStr impl into kind_var!<commit_after>use std::fmt;
use std::str::FromStr;

use grammar;
use kind::{TypeKind, StackKind};

pub trait KindVar {
    type Kind;

    fn new<S: ToString>(name: S) -> Self;

    fn gen() -> Self;
}

macro_rules! kind_var {
    ($KindVar:ident, $Kind:ident, $prefix:expr, $parse_var:ident) => {
        #[derive(Clone, Debug, Hash, PartialEq)]
        pub struct $KindVar {
            name: String,
        }

        impl KindVar for $KindVar {
            type Kind = $Kind;

            fn new<S: ToString>(name: S) -> Self {
                $KindVar {
                    name: name.to_string(),
                }
            }

            fn gen() -> $KindVar {
                use std::cell::Cell;

                thread_local!(static NEXT_ID: Cell<usize> = Cell::new(0));

                NEXT_ID.with(|next_id| {
                    let id = next_id.get();
                    next_id.set(id + 1);

                    $KindVar::new(format!("{}${}", $prefix, id))
                })
            }
        }

        impl fmt::Display for $KindVar {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{}", self.name)
            }
        }

        impl FromStr for $KindVar {
            type Err = grammar::ParseError;

            fn from_str(src: &str) -> Result<$KindVar, grammar::ParseError> {
                grammar::$parse_var(src)
            }
        }
    };
}

kind_var!(TypeVar, TypeKind, "t", type_var);
kind_var!(StackVar, StackKind, "S", stack_var);

macro_rules! forall_fn {
    ($name:ident($($Var:ident),*)) => {
        #[allow(dead_code)]
        pub fn $name<F: FnOnce($($Var),*) -> Output, $($Var: KindVar,)* Output>(f: F) -> Output {
            f($($Var::gen()),*)
        }
    }
}

forall_fn!(forall1(Var1));
forall_fn!(forall2(Var1, Var2));
forall_fn!(forall3(Var1, Var2, Var3));
forall_fn!(forall4(Var1, Var2, Var3, Var4));
forall_fn!(forall5(Var1, Var2, Var3, Var4, Var5));
<|endoftext|>


<commit_before>
export t;
export create;
export union;
export intersect;
export assign;
export clone;
export get;
export equal;
export clear;
export set_all;
export invert;
export difference;
export set;
export is_true;
export is_false;
export to_ivec;
export to_str;
export eq_ivec;

// FIXME: With recursive object types, we could implement binary methods like
//        union, intersection, and difference. At that point, we could write
//        an optimizing version of this module that produces a different obj
//        for the case where nbits <= 32.

type t = @{storage: [mutable uint], nbits: uint};

// FIXME: this should be a constant once they work
fn uint_bits() -> uint { ret 32u + (1u << 32u >> 27u); }

fn create(nbits: uint, init: bool) -> t {
    let elt = if init { !0u } else { 0u };
    let storage = ivec::init_elt_mut[uint](elt, nbits / uint_bits() + 1u);
    ret @{storage: storage, nbits: nbits};
}

fn process(op: &block(uint, uint) -> uint , v0: &t, v1: &t) -> bool {
    let len = ivec::len(v1.storage);
    assert (ivec::len(v0.storage) == len);
    assert (v0.nbits == v1.nbits);
    let changed = false;
    for each i: uint in uint::range(0u, len) {
        let w0 = v0.storage.(i);
        let w1 = v1.storage.(i);
        let w = op(w0, w1);
        if w0 != w { changed = true; v0.storage.(i) = w; }
    }
    ret changed;
}

fn lor(w0: uint, w1: uint) -> uint { ret w0 | w1; }

fn union(v0: &t, v1: &t) -> bool { let sub = lor; ret process(sub, v0, v1); }

fn land(w0: uint, w1: uint) -> uint { ret w0 & w1; }

fn intersect(v0: &t, v1: &t) -> bool {
    let sub = land;
    ret process(sub, v0, v1);
}

fn right(w0: uint, w1: uint) -> uint { ret w1; }

fn assign(v0: &t, v1: t) -> bool {
    let sub = right;
    ret process(sub, v0, v1);
}

fn clone(v: t) -> t {
    let storage = ivec::init_elt_mut[uint](0u, v.nbits / uint_bits() + 1u);
    let len = ivec::len(v.storage);
    for each i: uint in uint::range(0u, len) { storage.(i) = v.storage.(i); }
    ret @{storage: storage, nbits: v.nbits};
}

fn get(v: &t, i: uint) -> bool {
    assert (i < v.nbits);
    let bits = uint_bits();
    let w = i / bits;
    let b = i % bits;
    let x = 1u & v.storage.(w) >> b;
    ret x == 1u;
}

fn equal(v0: &t, v1: &t) -> bool {
    // FIXME: when we can break or return from inside an iterator loop,
    //        we can eliminate this painful while-loop

    let len = ivec::len(v1.storage);
    let i = 0u;
    while i < len {
        if v0.storage.(i) != v1.storage.(i) { ret false; }
        i = i + 1u;
    }
    ret true;
}

fn clear(v: &t) {
    for each i: uint in uint::range(0u, ivec::len(v.storage)) {
        v.storage.(i) = 0u;
    }
}

fn set_all(v: &t) {
    for each i: uint in uint::range(0u, v.nbits) { set(v, i, true); }
}

fn invert(v: &t) {
    for each i: uint in uint::range(0u, ivec::len(v.storage)) {
        v.storage.(i) = !v.storage.(i);
    }
}

/* v0 = v0 - v1 */
fn difference(v0: &t, v1: &t) -> bool {
    invert(v1);
    let b = intersect(v0, v1);
    invert(v1);
    ret b;
}

fn set(v: &t, i: uint, x: bool) {
    assert (i < v.nbits);
    let bits = uint_bits();
    let w = i / bits;
    let b = i % bits;
    let flag = 1u << b;
    v.storage.(w) =
        if x { v.storage.(w) | flag } else { v.storage.(w) & !flag };
}

/* true if all bits are 1 */
fn is_true(v: &t) -> bool {
    for i: uint in to_ivec(v) { if i != 1u { ret false; } }
    ret true;
}

/* true if all bits are non-1 */
fn is_false(v: &t) -> bool {
    for i: uint in to_ivec(v) { if i == 1u { ret false; } }
    ret true;
}

fn init_to_vec(v: t, i: uint) -> uint { ret if get(v, i) { 1u } else { 0u }; }

fn to_ivec(v: &t) -> [uint] {
    let sub = bind init_to_vec(v, _);
    ret ivec::init_fn[uint](sub, v.nbits);
}

fn to_str(v: &t) -> str {
    let rs = "";
    for i: uint in to_ivec(v) {
        if i == 1u { rs += "1"; } else { rs += "0"; }
    }
    ret rs;
}

fn eq_ivec(v0: &t, v1: &[uint]) -> bool {
    assert (v0.nbits == ivec::len[uint](v1));
    let len = v0.nbits;
    let i = 0u;
    while i < len {
        let w0 = get(v0, i);
        let w1 = v1.(i);
        if !w0 && w1 != 0u || w0 && w1 == 0u { ret false; }
        i = i + 1u;
    }
    ret true;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Rename bitv::to_ivec to to_vec<commit_after>
export t;
export create;
export union;
export intersect;
export assign;
export clone;
export get;
export equal;
export clear;
export set_all;
export invert;
export difference;
export set;
export is_true;
export is_false;
export to_vec;
export to_str;
export eq_ivec;

// FIXME: With recursive object types, we could implement binary methods like
//        union, intersection, and difference. At that point, we could write
//        an optimizing version of this module that produces a different obj
//        for the case where nbits <= 32.

type t = @{storage: [mutable uint], nbits: uint};

// FIXME: this should be a constant once they work
fn uint_bits() -> uint { ret 32u + (1u << 32u >> 27u); }

fn create(nbits: uint, init: bool) -> t {
    let elt = if init { !0u } else { 0u };
    let storage = ivec::init_elt_mut[uint](elt, nbits / uint_bits() + 1u);
    ret @{storage: storage, nbits: nbits};
}

fn process(op: &block(uint, uint) -> uint , v0: &t, v1: &t) -> bool {
    let len = ivec::len(v1.storage);
    assert (ivec::len(v0.storage) == len);
    assert (v0.nbits == v1.nbits);
    let changed = false;
    for each i: uint in uint::range(0u, len) {
        let w0 = v0.storage.(i);
        let w1 = v1.storage.(i);
        let w = op(w0, w1);
        if w0 != w { changed = true; v0.storage.(i) = w; }
    }
    ret changed;
}

fn lor(w0: uint, w1: uint) -> uint { ret w0 | w1; }

fn union(v0: &t, v1: &t) -> bool { let sub = lor; ret process(sub, v0, v1); }

fn land(w0: uint, w1: uint) -> uint { ret w0 & w1; }

fn intersect(v0: &t, v1: &t) -> bool {
    let sub = land;
    ret process(sub, v0, v1);
}

fn right(w0: uint, w1: uint) -> uint { ret w1; }

fn assign(v0: &t, v1: t) -> bool {
    let sub = right;
    ret process(sub, v0, v1);
}

fn clone(v: t) -> t {
    let storage = ivec::init_elt_mut[uint](0u, v.nbits / uint_bits() + 1u);
    let len = ivec::len(v.storage);
    for each i: uint in uint::range(0u, len) { storage.(i) = v.storage.(i); }
    ret @{storage: storage, nbits: v.nbits};
}

fn get(v: &t, i: uint) -> bool {
    assert (i < v.nbits);
    let bits = uint_bits();
    let w = i / bits;
    let b = i % bits;
    let x = 1u & v.storage.(w) >> b;
    ret x == 1u;
}

fn equal(v0: &t, v1: &t) -> bool {
    // FIXME: when we can break or return from inside an iterator loop,
    //        we can eliminate this painful while-loop

    let len = ivec::len(v1.storage);
    let i = 0u;
    while i < len {
        if v0.storage.(i) != v1.storage.(i) { ret false; }
        i = i + 1u;
    }
    ret true;
}

fn clear(v: &t) {
    for each i: uint in uint::range(0u, ivec::len(v.storage)) {
        v.storage.(i) = 0u;
    }
}

fn set_all(v: &t) {
    for each i: uint in uint::range(0u, v.nbits) { set(v, i, true); }
}

fn invert(v: &t) {
    for each i: uint in uint::range(0u, ivec::len(v.storage)) {
        v.storage.(i) = !v.storage.(i);
    }
}

/* v0 = v0 - v1 */
fn difference(v0: &t, v1: &t) -> bool {
    invert(v1);
    let b = intersect(v0, v1);
    invert(v1);
    ret b;
}

fn set(v: &t, i: uint, x: bool) {
    assert (i < v.nbits);
    let bits = uint_bits();
    let w = i / bits;
    let b = i % bits;
    let flag = 1u << b;
    v.storage.(w) =
        if x { v.storage.(w) | flag } else { v.storage.(w) & !flag };
}

/* true if all bits are 1 */
fn is_true(v: &t) -> bool {
    for i: uint in to_vec(v) { if i != 1u { ret false; } }
    ret true;
}

/* true if all bits are non-1 */
fn is_false(v: &t) -> bool {
    for i: uint in to_vec(v) { if i == 1u { ret false; } }
    ret true;
}

fn init_to_vec(v: t, i: uint) -> uint { ret if get(v, i) { 1u } else { 0u }; }

fn to_vec(v: &t) -> [uint] {
    let sub = bind init_to_vec(v, _);
    ret ivec::init_fn[uint](sub, v.nbits);
}

fn to_str(v: &t) -> str {
    let rs = "";
    for i: uint in to_vec(v) {
        if i == 1u { rs += "1"; } else { rs += "0"; }
    }
    ret rs;
}

fn eq_ivec(v0: &t, v1: &[uint]) -> bool {
    assert (v0.nbits == ivec::len[uint](v1));
    let len = v0.nbits;
    let i = 0u;
    while i < len {
        let w0 = get(v0, i);
        let w1 = v1.(i);
        if !w0 && w1 != 0u || w0 && w1 == 0u { ret false; }
        i = i + 1u;
    }
    ret true;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::hash::{Hash, Hasher};

use proc_macro2::{Span, Term};
use unicode_xid::UnicodeXID;

/// A Rust lifetime: `'a`.
///
/// Lifetime names must conform to the following rules:
///
/// - Must start with an apostrophe.
/// - Must not consist of just an apostrophe: `'`.
/// - Must not consist of apostrophe + underscore: `'_`.
/// - Character after the apostrophe must be `_` or a Unicode code point with
///   the XID_Start property.
/// - All following characters must be Unicode code points with the XID_Continue
///   property.
///
/// *This type is available if Syn is built with the `"derive"` or `"full"`
/// feature.*
#[cfg_attr(feature = "extra-traits", derive(Debug))]
#[cfg_attr(feature = "clone-impls", derive(Clone))]
pub struct Lifetime {
    term: Term,
    pub span: Span,
}

impl Lifetime {
    pub fn new(term: Term, span: Span) -> Self {
        let s = term.as_str();

        if !s.starts_with('\'') {
            panic!(
                "lifetime name must start with apostrophe as in \"'a\", \
                 got {:?}",
                s
            );
        }

        if s == "'" {
            panic!("lifetime name must not be empty");
        }

        if s == "'_" {
            panic!("\"'_\" is not a valid lifetime name");
        }

        fn xid_ok(s: &str) -> bool {
            let mut chars = s.chars();
            let first = chars.next().unwrap();
            if !(UnicodeXID::is_xid_start(first) || first == '_') {
                return false;
            }
            for ch in chars {
                if !UnicodeXID::is_xid_continue(ch) {
                    return false;
                }
            }
            true
        }

        if !xid_ok(&s[1..]) {
            panic!("{:?} is not a valid lifetime name", s);
        }

        Lifetime {
            term: term,
            span: span,
        }
    }
}

impl Display for Lifetime {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.term.as_str().fmt(formatter)
    }
}

impl PartialEq for Lifetime {
    fn eq(&self, other: &Lifetime) -> bool {
        self.term.as_str() == other.term.as_str()
    }
}

impl Eq for Lifetime {}

impl PartialOrd for Lifetime {
    fn partial_cmp(&self, other: &Lifetime) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Lifetime {
    fn cmp(&self, other: &Lifetime) -> Ordering {
        self.term.as_str().cmp(other.term.as_str())
    }
}

impl Hash for Lifetime {
    fn hash<H: Hasher>(&self, h: &mut H) {
        self.term.as_str().hash(h)
    }
}

#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;
    use synom::Synom;
    use buffer::Cursor;
    use parse_error;
    use synom::PResult;

    impl Synom for Lifetime {
        fn parse(input: Cursor) -> PResult<Self> {
            let (span, term, rest) = match input.term() {
                Some(term) => term,
                _ => return parse_error(),
            };
            if !term.as_str().starts_with('\'') {
                return parse_error();
            }

            Ok((
                Lifetime {
                    term: term,
                    span: span,
                },
                rest,
            ))
        }

        fn description() -> Option<&'static str> {
            Some("lifetime")
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use quote::{ToTokens, Tokens};
    use proc_macro2::{TokenNode, TokenTree};

    impl ToTokens for Lifetime {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append(TokenTree {
                span: self.span,
                kind: TokenNode::Term(self.term),
            })
        }
    }
}
<commit_msg>Copy and Clone for Lifetime without a feature gate<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cmp::Ordering;
use std::fmt::{self, Display};
use std::hash::{Hash, Hasher};

use proc_macro2::{Span, Term};
use unicode_xid::UnicodeXID;

/// A Rust lifetime: `'a`.
///
/// Lifetime names must conform to the following rules:
///
/// - Must start with an apostrophe.
/// - Must not consist of just an apostrophe: `'`.
/// - Must not consist of apostrophe + underscore: `'_`.
/// - Character after the apostrophe must be `_` or a Unicode code point with
///   the XID_Start property.
/// - All following characters must be Unicode code points with the XID_Continue
///   property.
///
/// *This type is available if Syn is built with the `"derive"` or `"full"`
/// feature.*
#[cfg_attr(feature = "extra-traits", derive(Debug))]
#[derive(Copy, Clone)]
pub struct Lifetime {
    term: Term,
    pub span: Span,
}

impl Lifetime {
    pub fn new(term: Term, span: Span) -> Self {
        let s = term.as_str();

        if !s.starts_with('\'') {
            panic!(
                "lifetime name must start with apostrophe as in \"'a\", \
                 got {:?}",
                s
            );
        }

        if s == "'" {
            panic!("lifetime name must not be empty");
        }

        if s == "'_" {
            panic!("\"'_\" is not a valid lifetime name");
        }

        fn xid_ok(s: &str) -> bool {
            let mut chars = s.chars();
            let first = chars.next().unwrap();
            if !(UnicodeXID::is_xid_start(first) || first == '_') {
                return false;
            }
            for ch in chars {
                if !UnicodeXID::is_xid_continue(ch) {
                    return false;
                }
            }
            true
        }

        if !xid_ok(&s[1..]) {
            panic!("{:?} is not a valid lifetime name", s);
        }

        Lifetime {
            term: term,
            span: span,
        }
    }
}

impl Display for Lifetime {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.term.as_str().fmt(formatter)
    }
}

impl PartialEq for Lifetime {
    fn eq(&self, other: &Lifetime) -> bool {
        self.term.as_str() == other.term.as_str()
    }
}

impl Eq for Lifetime {}

impl PartialOrd for Lifetime {
    fn partial_cmp(&self, other: &Lifetime) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Lifetime {
    fn cmp(&self, other: &Lifetime) -> Ordering {
        self.term.as_str().cmp(other.term.as_str())
    }
}

impl Hash for Lifetime {
    fn hash<H: Hasher>(&self, h: &mut H) {
        self.term.as_str().hash(h)
    }
}

#[cfg(feature = "parsing")]
pub mod parsing {
    use super::*;
    use synom::Synom;
    use buffer::Cursor;
    use parse_error;
    use synom::PResult;

    impl Synom for Lifetime {
        fn parse(input: Cursor) -> PResult<Self> {
            let (span, term, rest) = match input.term() {
                Some(term) => term,
                _ => return parse_error(),
            };
            if !term.as_str().starts_with('\'') {
                return parse_error();
            }

            Ok((
                Lifetime {
                    term: term,
                    span: span,
                },
                rest,
            ))
        }

        fn description() -> Option<&'static str> {
            Some("lifetime")
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use quote::{ToTokens, Tokens};
    use proc_macro2::{TokenNode, TokenTree};

    impl ToTokens for Lifetime {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append(TokenTree {
                span: self.span,
                kind: TokenNode::Term(self.term),
            })
        }
    }
}
<|endoftext|>


<commit_before>use getopts::{Options,Matches};
use std::net::{TcpListener,TcpStream};
use std::thread::Thread;
use std::io::{Read,BufStream,BufRead};
use std::old_io::{LineBufferedWriter,stdio};

pub fn listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let listener = TcpListener::bind(s.as_slice()).unwrap();
    // block until we get connection
    match listener.accept() {
        Ok(res) => {
            let (stream, socket_addr) = res;
            // nc doesn't handle multiple connections, so no need to do `handle_client`
            // in thread.
            handle_client(stream);
        },
        Err(f) => {
            panic!(f.to_string());
        }
    }
}

fn handle_client(stream: TcpStream) {
    let mut buf_stream = BufStream::new(stream);
    let mut read_buf = [0; 4096];
    let mut writer = LineBufferedWriter::new(stdio::stdout());
    loop {
        match(buf_stream.read(&mut read_buf)) {
            Ok(n) => {
                if n > 0 {
                    writer.write_all(&read_buf);
                }
                else {
                    return;
                }
            }
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<commit_msg>No need for thread module in listener.<commit_after>use getopts::{Options,Matches};
use std::net::{TcpListener,TcpStream};
use std::io::{Read,BufStream,BufRead};
use std::old_io::{LineBufferedWriter,stdio};

pub fn listen(matches: &Matches) {
    // append port to localhost IP address
    let mut s = String::from_str("127.0.0.1:");
    s.push_str(matches.free[0].as_slice());
    let listener = TcpListener::bind(s.as_slice()).unwrap();
    // block until we get connection
    match listener.accept() {
        Ok(res) => {
            let (stream, socket_addr) = res;
            // nc doesn't handle multiple connections, so no need to do `handle_client`
            // in thread.
            handle_client(stream);
        },
        Err(f) => {
            panic!(f.to_string());
        }
    }
}

fn handle_client(stream: TcpStream) {
    let mut buf_stream = BufStream::new(stream);
    let mut read_buf = [0; 4096];
    let mut writer = LineBufferedWriter::new(stdio::stdout());
    loop {
        match(buf_stream.read(&mut read_buf)) {
            Ok(n) => {
                if n > 0 {
                    writer.write_all(&read_buf);
                }
                else {
                    return;
                }
            }
            Err(f) => {
                panic!(f.to_string());
            }
        }
    }
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

// This requires Rust 1.54.0 or later. The double cfg_attr is required so older versions can compile it.
#![cfg_attr(doc, cfg_attr(doc, doc = include_str!("../README.md")))]
#![cfg_attr(not(doc), doc = "Run cargo doc to see the docs (needs Rust 1.54.0 or later)")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/icedland/iced/master/logo.png")]
#![doc(html_root_url = "https://docs.rs/iced-x86/1.15.0")]
#![allow(unknown_lints)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(anonymous_parameters)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(invalid_html_tags)]
#![warn(keyword_idents)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_must_use)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::branches_sharing_code)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::redundant_closure)] // Clippy is buggy
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wrong_self_convention)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::debug_assert_with_mut_call)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::empty_line_after_outer_attr)]
#![warn(clippy::explicit_into_iter_loop)]
#![warn(clippy::explicit_iter_loop)]
#![warn(clippy::fallible_impl_from)]
#![warn(clippy::get_unwrap)]
#![warn(clippy::implicit_saturating_sub)]
#![warn(clippy::large_digit_groups)]
#![warn(clippy::let_unit_value)]
#![warn(clippy::match_bool)]
#![warn(clippy::match_on_vec_items)]
#![warn(clippy::match_wild_err_arm)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::missing_inline_in_public_items)]
#![warn(clippy::must_use_candidate)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::redundant_closure_for_method_calls)]
#![warn(clippy::same_functions_in_if_condition)]
#![warn(clippy::todo)]
#![warn(clippy::unimplemented)]
#![warn(clippy::unreadable_literal)]
#![warn(clippy::unused_self)]
#![warn(clippy::unwrap_in_result)]
#![warn(clippy::used_underscore_binding)]
#![warn(clippy::useless_let_if_seq)]
#![warn(clippy::useless_transmute)]
#![warn(clippy::zero_sized_map_values)]
#![cfg_attr(not(test), warn(clippy::expect_used))]
#![cfg_attr(not(test), warn(clippy::unwrap_used))]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(test(attr(deny(warnings))))]

// This should be the only place in the source code that uses no_std
#[cfg(all(feature = "std", feature = "no_std"))]
compile_error!("`std` and `no_std` features can't be used at the same time");
#[cfg(all(not(feature = "std"), not(feature = "no_std")))]
compile_error!("`std` or `no_std` feature must be defined");

#[cfg_attr(
	any(
		feature = "encoder",
		feature = "block_encoder",
		feature = "op_code_info",
		feature = "gas",
		feature = "intel",
		feature = "masm",
		feature = "nasm",
		feature = "fast_fmt"
	),
	macro_use
)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;

#[macro_use]
mod iced_assert {
	macro_rules! iced_assert {
		($($expr:tt)*) => {{
			// If it's a debug build, include the expression string
			#[cfg(debug_assertions)]
			{
				assert!($($expr)*);
			}

			// If it's not a debug build, don't include the expression string
			#[cfg(not(debug_assertions))]
			{
				if !($($expr)*) {
					panic!();
				}
			}
		}};
	}
}

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
mod block_enc;
mod code;
#[cfg(feature = "code_asm")]
pub mod code_asm;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod constant_offsets;
#[cfg(any(feature = "decoder", feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod data_reader;
#[cfg(feature = "decoder")]
mod decoder;
#[cfg(feature = "encoder")]
mod encoder;
mod enums;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod formatter;
pub(crate) mod iced_constants;
mod iced_error;
mod iced_features;
#[cfg(feature = "instr_info")]
mod info;
mod instruction;
#[cfg(feature = "encoder")]
mod instruction_create;
mod instruction_internal;
mod instruction_memory_sizes;
mod instruction_op_counts;
mod memory_size;
mod mnemonic;
mod mnemonics;
#[cfg(feature = "mvex")]
mod mvex;
mod register;
#[cfg(test)]
pub(crate) mod test;
#[cfg(test)]
pub(crate) mod test_utils;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod tuple_type_tbl;

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
pub use crate::block_enc::*;
pub use crate::code::*;
#[cfg(any(feature = "decoder", feature = "encoder"))]
pub use crate::constant_offsets::*;
#[cfg(feature = "decoder")]
pub use crate::decoder::*;
#[cfg(feature = "encoder")]
pub use crate::encoder::*;
pub use crate::enums::*;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
pub use crate::formatter::*;
pub use crate::iced_error::*;
pub use crate::iced_features::*;
#[cfg(feature = "instr_info")]
pub use crate::info::*;
pub use crate::instruction::*;
pub use crate::memory_size::*;
pub use crate::mnemonic::*;
pub use crate::register::*;
<commit_msg>Remove html_root_url<commit_after>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

// This requires Rust 1.54.0 or later. The double cfg_attr is required so older versions can compile it.
#![cfg_attr(doc, cfg_attr(doc, doc = include_str!("../README.md")))]
#![cfg_attr(not(doc), doc = "Run cargo doc to see the docs (needs Rust 1.54.0 or later)")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/icedland/iced/master/logo.png")]
#![allow(unknown_lints)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(anonymous_parameters)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(invalid_html_tags)]
#![warn(keyword_idents)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_must_use)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::branches_sharing_code)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::redundant_closure)] // Clippy is buggy
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wrong_self_convention)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::debug_assert_with_mut_call)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::empty_line_after_outer_attr)]
#![warn(clippy::explicit_into_iter_loop)]
#![warn(clippy::explicit_iter_loop)]
#![warn(clippy::fallible_impl_from)]
#![warn(clippy::get_unwrap)]
#![warn(clippy::implicit_saturating_sub)]
#![warn(clippy::large_digit_groups)]
#![warn(clippy::let_unit_value)]
#![warn(clippy::match_bool)]
#![warn(clippy::match_on_vec_items)]
#![warn(clippy::match_wild_err_arm)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::missing_inline_in_public_items)]
#![warn(clippy::must_use_candidate)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::redundant_closure_for_method_calls)]
#![warn(clippy::same_functions_in_if_condition)]
#![warn(clippy::todo)]
#![warn(clippy::unimplemented)]
#![warn(clippy::unreadable_literal)]
#![warn(clippy::unused_self)]
#![warn(clippy::unwrap_in_result)]
#![warn(clippy::used_underscore_binding)]
#![warn(clippy::useless_let_if_seq)]
#![warn(clippy::useless_transmute)]
#![warn(clippy::zero_sized_map_values)]
#![cfg_attr(not(test), warn(clippy::expect_used))]
#![cfg_attr(not(test), warn(clippy::unwrap_used))]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(test(attr(deny(warnings))))]

// This should be the only place in the source code that uses no_std
#[cfg(all(feature = "std", feature = "no_std"))]
compile_error!("`std` and `no_std` features can't be used at the same time");
#[cfg(all(not(feature = "std"), not(feature = "no_std")))]
compile_error!("`std` or `no_std` feature must be defined");

#[cfg_attr(
	any(
		feature = "encoder",
		feature = "block_encoder",
		feature = "op_code_info",
		feature = "gas",
		feature = "intel",
		feature = "masm",
		feature = "nasm",
		feature = "fast_fmt"
	),
	macro_use
)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;

#[macro_use]
mod iced_assert {
	macro_rules! iced_assert {
		($($expr:tt)*) => {{
			// If it's a debug build, include the expression string
			#[cfg(debug_assertions)]
			{
				assert!($($expr)*);
			}

			// If it's not a debug build, don't include the expression string
			#[cfg(not(debug_assertions))]
			{
				if !($($expr)*) {
					panic!();
				}
			}
		}};
	}
}

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
mod block_enc;
mod code;
#[cfg(feature = "code_asm")]
pub mod code_asm;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod constant_offsets;
#[cfg(any(feature = "decoder", feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod data_reader;
#[cfg(feature = "decoder")]
mod decoder;
#[cfg(feature = "encoder")]
mod encoder;
mod enums;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod formatter;
pub(crate) mod iced_constants;
mod iced_error;
mod iced_features;
#[cfg(feature = "instr_info")]
mod info;
mod instruction;
#[cfg(feature = "encoder")]
mod instruction_create;
mod instruction_internal;
mod instruction_memory_sizes;
mod instruction_op_counts;
mod memory_size;
mod mnemonic;
mod mnemonics;
#[cfg(feature = "mvex")]
mod mvex;
mod register;
#[cfg(test)]
pub(crate) mod test;
#[cfg(test)]
pub(crate) mod test_utils;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod tuple_type_tbl;

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
pub use crate::block_enc::*;
pub use crate::code::*;
#[cfg(any(feature = "decoder", feature = "encoder"))]
pub use crate::constant_offsets::*;
#[cfg(feature = "decoder")]
pub use crate::decoder::*;
#[cfg(feature = "encoder")]
pub use crate::encoder::*;
pub use crate::enums::*;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
pub use crate::formatter::*;
pub use crate::iced_error::*;
pub use crate::iced_features::*;
#[cfg(feature = "instr_info")]
pub use crate::info::*;
pub use crate::instruction::*;
pub use crate::memory_size::*;
pub use crate::mnemonic::*;
pub use crate::register::*;
<|endoftext|>


<commit_before>#![allow(dead_code, unused_variables)]
use alloc::heap::{Heap, Alloc, Layout};
use bytes::BytesMut;

use std::sync::Arc;

use audiosample::*;
use pixel::*;
use timeinfo::*;

use byte_slice_cast::*;

#[derive(Fail, Debug)]
pub enum FrameError {
    #[fail(display = "Invalid Index")]
    InvalidIndex,
    #[fail(display = "Invalid Conversion")]
    InvalidConversion,
}

use self::FrameError::*;

// TODO: Document
// TODO: Change it to provide Droppable/Seekable information or use a separate enum?
#[derive(Clone, Debug, PartialEq)]
pub enum PictureType {
    UNKNOWN,
    I,
    P,
    B,
    S,
    SI,
    SP,
    SB,
    BI,
}

#[derive(Clone, Debug, PartialEq)]
pub struct VideoInfo {
    pub pic_type: PictureType,
    pub width: usize,
    pub height: usize,
    pub format: Arc<Formaton>,
}

impl VideoInfo {
    fn size(&self, align: usize) -> usize {
        let mut size = 0;
        for &component in self.format.into_iter() {
            if let Some(c) = component {
                size += c.get_data_size(self.width, self.height, align);
            }
        }
        size
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AudioInfo {
    pub samples: usize,
    pub rate: usize,
    pub map: ChannelMap,
    pub format: Arc<Soniton>,
}

impl AudioInfo {
    fn size(&self, align: usize) -> usize {
        self.format.get_audio_size(self.samples, align) * self.map.len()
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

use std::convert::From;

impl From<VideoInfo> for MediaKind {
    fn from(v: VideoInfo) -> Self {
        MediaKind::Video(v)
    }
}

impl From<AudioInfo> for MediaKind {
    fn from(a: AudioInfo) -> Self {
        MediaKind::Audio(a)
    }
}

use self::MediaKind::*;

pub trait FrameBuffer : Send + Sync {
    fn linesize(&self, idx: usize) -> Result<usize, FrameError>;
    fn count(&self) -> usize;
    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8], FrameError>;
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8], FrameError>;
}

mod private {
    use byte_slice_cast::*;

    pub trait Supported: FromByteSlice {}
    impl Supported for u8 {}
    impl Supported for i16 {}
    impl Supported for f32 {}
}

pub trait FrameBufferConv<T: private::Supported> : FrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [T], FrameError> {
        self.as_slice_inner(idx)?.as_slice_of::<T>().map_err(|e| InvalidConversion)
    }
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [T], FrameError> {
        self.as_mut_slice_inner(idx)?.as_mut_slice_of::<T>().map_err(|e| InvalidConversion)
    }
}

impl FrameBufferConv<u8> for FrameBuffer {}
impl FrameBufferConv<i16> for FrameBuffer {}
impl FrameBufferConv<f32> for FrameBuffer {}

use std::fmt;

impl fmt::Debug for FrameBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "FrameBuffer")
    }
}

#[derive(Debug)]
pub struct Frame {
    pub kind: MediaKind,
    pub buf: Box<FrameBuffer>,
    pub t: TimeInfo,
}

const ALIGNMENT: usize = 32;

struct Plane {
    buf: BytesMut,
    linesize: usize,
}

struct DefaultFrameBuffer {
    buf: BytesMut,
    planes: Vec<Plane>,
}

impl FrameBuffer for DefaultFrameBuffer {
    fn linesize(&self, idx: usize) -> Result<usize, FrameError> {
        match self.planes.get(idx) {
            None => Err(InvalidIndex),
            Some(plane) => Ok(plane.linesize),
        }
    }
    fn count(&self) -> usize {
        self.planes.len()
    }

    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8], FrameError> {
        match self.planes.get(idx) {
            None => Err(InvalidIndex),
            Some(plane) => Ok(&plane.buf),
        }
    }
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8], FrameError> {
        match self.planes.get_mut(idx) {
            None => Err(InvalidIndex),
            Some(plane) => Ok(&mut plane.buf),
        }
    }
}

impl DefaultFrameBuffer {
    pub fn new<'a>(kind: &'a MediaKind) -> DefaultFrameBuffer {
        match kind {
            &Video(ref video) => {
                let size = video.size(ALIGNMENT);
                let data = unsafe {
                    Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                //let data = unsafe { Heap.alloc_zeroed(Layout::from_size_align(size, ALIGNMENT)) };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for &component in video.format.iter() {
                    if let Some(c) = component {
                        let planesize = c.get_data_size(video.width, video.height, ALIGNMENT);
                        let linesize = c.get_linesize(video.width, ALIGNMENT);
                        buffer.planes.push(Plane {
                            buf: buffer.buf.split_to(planesize),
                            linesize: linesize,
                        });
                    }
                }
                buffer
            },
            &Audio(ref audio) => {
                let size = audio.size(ALIGNMENT);
                let data = unsafe {
                    Heap.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for _ in 0..audio.map.len() {
                    let size = audio.format.get_audio_size(audio.samples, ALIGNMENT);
                    buffer.planes.push(Plane {
                        buf: buffer.buf.split_to(size),
                        linesize: size,
                    });
                }
                buffer
            },
        }
    }
}

pub type ArcFrame = Arc<Frame>;

pub fn new_default_frame<T>(kind: T, t: Option<TimeInfo>) -> Frame
where T: Into<MediaKind> + Clone
{
    let k = kind.into();
    let buf = DefaultFrameBuffer::new(&k);

    Frame {
        kind: k,
        buf: box buf,
        t: t.unwrap_or_default(),
    }
}

use std::ptr::copy_nonoverlapping;

fn copy_plane(
    dst: &mut [u8],
    dst_linesize: usize,
    src: &[u8],
    src_linesize: usize,
    w: usize,
    h: usize,
) {
    let dst_chunks = dst.chunks_mut(dst_linesize);
    let src_chunks = src.chunks(src_linesize);

    for (d, s) in dst_chunks.zip(src_chunks).take(h) {
        unsafe {
            copy_nonoverlapping(s.as_ptr(), d.as_mut_ptr(), w);
        }
    }
}

fn copy_image<'a, IM, IU, I>(
    dst: IM,
    dst_linesizes: IU,
    src: I,
    src_linesizes: IU,
    w: usize,
    h: usize,
    fmt: &Formaton,
) where
    IM: Iterator<Item = &'a mut [u8]>,
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    let dst_iter = dst.zip(dst_linesizes);
    let src_iter = src.zip(src_linesizes);
    let iter = dst_iter.zip(src_iter).zip(fmt.iter());

    for (((d, d_linesize), (s, s_linesize)), c) in iter {
        copy_plane(
            d,
            d_linesize,
            s,
            s_linesize,
            c.unwrap().get_width(w),
            c.unwrap().get_height(h),
        );
    }
}

// TODO: Add proper tests
fn copy_to_frame<'a, I, IU>(dst: &mut Frame, mut src: I, mut src_linesize: IU, w: usize, h: usize)
where
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    if let MediaKind::Video(ref fmt) = dst.kind {
        let mut f_iter = fmt.format.iter();
        let w = fmt.width;
        let h = fmt.height;
        for i in 0..dst.buf.count() {
            let d_linesize = dst.buf.linesize(i).unwrap();
            let s_linesize = src_linesize.next().unwrap();
            let d = dst.buf.as_mut_slice(i).unwrap();
            let s = src.next().unwrap();
            let c = f_iter.next().unwrap();
            copy_plane(
                d,
                d_linesize,
                s,
                s_linesize,
                c.unwrap().get_width(w),
                c.unwrap().get_height(h),
            );
        }
    } else {
        unimplemented!();
    }
}

use std::mem;
use std::slice;

// TODO make it a separate trait
impl Frame {
    pub fn copy_from_slice<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = &'a [u8]>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let s = src.next().unwrap();
                let c = f_iter.next().unwrap();
                copy_plane(
                    d,
                    d_linesize,
                    s,
                    s_linesize,
                    c.unwrap().get_width(w),
                    c.unwrap().get_height(h),
                );
            }
        } else {
            unimplemented!();
        }
    }

    pub fn copy_from_raw_parts<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = *const u8>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let c = f_iter.next().unwrap();
                let r = src.next().unwrap();
                let hb = c.unwrap().get_height(h);
                let s = unsafe { slice::from_raw_parts(r, hb * s_linesize) };
                copy_plane(d, d_linesize, s, s_linesize, c.unwrap().get_width(w), hb);
                mem::forget(s);
            }
        } else {
            unimplemented!();
        }
    }
}

<commit_msg>data: Update to the new alloc::heap API<commit_after>#![allow(dead_code, unused_variables)]
use alloc::heap::{Global, Alloc, Layout};
use bytes::BytesMut;

use std::sync::Arc;

use audiosample::*;
use pixel::*;
use timeinfo::*;

use byte_slice_cast::*;

#[derive(Fail, Debug)]
pub enum FrameError {
    #[fail(display = "Invalid Index")]
    InvalidIndex,
    #[fail(display = "Invalid Conversion")]
    InvalidConversion,
}

use self::FrameError::*;

// TODO: Document
// TODO: Change it to provide Droppable/Seekable information or use a separate enum?
#[derive(Clone, Debug, PartialEq)]
pub enum PictureType {
    UNKNOWN,
    I,
    P,
    B,
    S,
    SI,
    SP,
    SB,
    BI,
}

#[derive(Clone, Debug, PartialEq)]
pub struct VideoInfo {
    pub pic_type: PictureType,
    pub width: usize,
    pub height: usize,
    pub format: Arc<Formaton>,
}

impl VideoInfo {
    fn size(&self, align: usize) -> usize {
        let mut size = 0;
        for &component in self.format.into_iter() {
            if let Some(c) = component {
                size += c.get_data_size(self.width, self.height, align);
            }
        }
        size
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct AudioInfo {
    pub samples: usize,
    pub rate: usize,
    pub map: ChannelMap,
    pub format: Arc<Soniton>,
}

impl AudioInfo {
    fn size(&self, align: usize) -> usize {
        self.format.get_audio_size(self.samples, align) * self.map.len()
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum MediaKind {
    Video(VideoInfo),
    Audio(AudioInfo),
}

use std::convert::From;

impl From<VideoInfo> for MediaKind {
    fn from(v: VideoInfo) -> Self {
        MediaKind::Video(v)
    }
}

impl From<AudioInfo> for MediaKind {
    fn from(a: AudioInfo) -> Self {
        MediaKind::Audio(a)
    }
}

use self::MediaKind::*;

pub trait FrameBuffer : Send + Sync {
    fn linesize(&self, idx: usize) -> Result<usize, FrameError>;
    fn count(&self) -> usize;
    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8], FrameError>;
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8], FrameError>;
}

mod private {
    use byte_slice_cast::*;

    pub trait Supported: FromByteSlice {}
    impl Supported for u8 {}
    impl Supported for i16 {}
    impl Supported for f32 {}
}

pub trait FrameBufferConv<T: private::Supported> : FrameBuffer {
    fn as_slice<'a>(&'a self, idx: usize) -> Result<&'a [T], FrameError> {
        self.as_slice_inner(idx)?.as_slice_of::<T>().map_err(|e| InvalidConversion)
    }
    fn as_mut_slice<'a>(&'a mut self, idx: usize) -> Result<&'a mut [T], FrameError> {
        self.as_mut_slice_inner(idx)?.as_mut_slice_of::<T>().map_err(|e| InvalidConversion)
    }
}

impl FrameBufferConv<u8> for FrameBuffer {}
impl FrameBufferConv<i16> for FrameBuffer {}
impl FrameBufferConv<f32> for FrameBuffer {}

use std::fmt;

impl fmt::Debug for FrameBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "FrameBuffer")
    }
}

#[derive(Debug)]
pub struct Frame {
    pub kind: MediaKind,
    pub buf: Box<FrameBuffer>,
    pub t: TimeInfo,
}

const ALIGNMENT: usize = 32;

struct Plane {
    buf: BytesMut,
    linesize: usize,
}

struct DefaultFrameBuffer {
    buf: BytesMut,
    planes: Vec<Plane>,
}

impl FrameBuffer for DefaultFrameBuffer {
    fn linesize(&self, idx: usize) -> Result<usize, FrameError> {
        match self.planes.get(idx) {
            None => Err(InvalidIndex),
            Some(plane) => Ok(plane.linesize),
        }
    }
    fn count(&self) -> usize {
        self.planes.len()
    }

    fn as_slice_inner<'a>(&'a self, idx: usize) -> Result<&'a [u8], FrameError> {
        match self.planes.get(idx) {
            None => Err(InvalidIndex),
            Some(plane) => Ok(&plane.buf),
        }
    }
    fn as_mut_slice_inner<'a>(&'a mut self, idx: usize) -> Result<&'a mut [u8], FrameError> {
        match self.planes.get_mut(idx) {
            None => Err(InvalidIndex),
            Some(plane) => Ok(&mut plane.buf),
        }
    }
}

impl DefaultFrameBuffer {
    pub fn new<'a>(kind: &'a MediaKind) -> DefaultFrameBuffer {
        match kind {
            &Video(ref video) => {
                let size = video.size(ALIGNMENT);
                let data = unsafe {
                    Global.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                let data = data.as_ptr() as *mut u8;
                //let data = unsafe { Heap.alloc_zeroed(Layout::from_size_align(size, ALIGNMENT)) };
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for &component in video.format.iter() {
                    if let Some(c) = component {
                        let planesize = c.get_data_size(video.width, video.height, ALIGNMENT);
                        let linesize = c.get_linesize(video.width, ALIGNMENT);
                        buffer.planes.push(Plane {
                            buf: buffer.buf.split_to(planesize),
                            linesize: linesize,
                        });
                    }
                }
                buffer
            },
            &Audio(ref audio) => {
                let size = audio.size(ALIGNMENT);
                let data = unsafe {
                    Global.alloc(Layout::from_size_align(size, ALIGNMENT).unwrap())
                        .unwrap()
                };
                let data = data.as_ptr() as *mut u8;
                let buf = BytesMut::from(unsafe { Vec::from_raw_parts(data, size, size) });
                let mut buffer = DefaultFrameBuffer {
                    buf: buf,
                    planes: Vec::new(),
                };
                for _ in 0..audio.map.len() {
                    let size = audio.format.get_audio_size(audio.samples, ALIGNMENT);
                    buffer.planes.push(Plane {
                        buf: buffer.buf.split_to(size),
                        linesize: size,
                    });
                }
                buffer
            },
        }
    }
}

pub type ArcFrame = Arc<Frame>;

pub fn new_default_frame<T>(kind: T, t: Option<TimeInfo>) -> Frame
where T: Into<MediaKind> + Clone
{
    let k = kind.into();
    let buf = DefaultFrameBuffer::new(&k);

    Frame {
        kind: k,
        buf: box buf,
        t: t.unwrap_or_default(),
    }
}

use std::ptr::copy_nonoverlapping;

fn copy_plane(
    dst: &mut [u8],
    dst_linesize: usize,
    src: &[u8],
    src_linesize: usize,
    w: usize,
    h: usize,
) {
    let dst_chunks = dst.chunks_mut(dst_linesize);
    let src_chunks = src.chunks(src_linesize);

    for (d, s) in dst_chunks.zip(src_chunks).take(h) {
        unsafe {
            copy_nonoverlapping(s.as_ptr(), d.as_mut_ptr(), w);
        }
    }
}

fn copy_image<'a, IM, IU, I>(
    dst: IM,
    dst_linesizes: IU,
    src: I,
    src_linesizes: IU,
    w: usize,
    h: usize,
    fmt: &Formaton,
) where
    IM: Iterator<Item = &'a mut [u8]>,
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    let dst_iter = dst.zip(dst_linesizes);
    let src_iter = src.zip(src_linesizes);
    let iter = dst_iter.zip(src_iter).zip(fmt.iter());

    for (((d, d_linesize), (s, s_linesize)), c) in iter {
        copy_plane(
            d,
            d_linesize,
            s,
            s_linesize,
            c.unwrap().get_width(w),
            c.unwrap().get_height(h),
        );
    }
}

// TODO: Add proper tests
fn copy_to_frame<'a, I, IU>(dst: &mut Frame, mut src: I, mut src_linesize: IU, w: usize, h: usize)
where
    I: Iterator<Item = &'a [u8]>,
    IU: Iterator<Item = usize>,
{
    if let MediaKind::Video(ref fmt) = dst.kind {
        let mut f_iter = fmt.format.iter();
        let w = fmt.width;
        let h = fmt.height;
        for i in 0..dst.buf.count() {
            let d_linesize = dst.buf.linesize(i).unwrap();
            let s_linesize = src_linesize.next().unwrap();
            let d = dst.buf.as_mut_slice(i).unwrap();
            let s = src.next().unwrap();
            let c = f_iter.next().unwrap();
            copy_plane(
                d,
                d_linesize,
                s,
                s_linesize,
                c.unwrap().get_width(w),
                c.unwrap().get_height(h),
            );
        }
    } else {
        unimplemented!();
    }
}

use std::mem;
use std::slice;

// TODO make it a separate trait
impl Frame {
    pub fn copy_from_slice<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = &'a [u8]>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let s = src.next().unwrap();
                let c = f_iter.next().unwrap();
                copy_plane(
                    d,
                    d_linesize,
                    s,
                    s_linesize,
                    c.unwrap().get_width(w),
                    c.unwrap().get_height(h),
                );
            }
        } else {
            unimplemented!();
        }
    }

    pub fn copy_from_raw_parts<'a, I, IU>(&mut self, mut src: I, mut src_linesize: IU)
    where
        I: Iterator<Item = *const u8>,
        IU: Iterator<Item = usize>,
    {
        if let MediaKind::Video(ref fmt) = self.kind {
            let mut f_iter = fmt.format.iter();
            let w = fmt.width;
            let h = fmt.height;
            for i in 0..self.buf.count() {
                let d_linesize = self.buf.linesize(i).unwrap();
                let s_linesize = src_linesize.next().unwrap();
                let d = self.buf.as_mut_slice(i).unwrap();
                let c = f_iter.next().unwrap();
                let r = src.next().unwrap();
                let hb = c.unwrap().get_height(h);
                let s = unsafe { slice::from_raw_parts(r, hb * s_linesize) };
                copy_plane(d, d_linesize, s, s_linesize, c.unwrap().get_width(w), hb);
                mem::forget(s);
            }
        } else {
            unimplemented!();
        }
    }
}

<|endoftext|>


<commit_before>use std::collections;

use num::traits::ToPrimitive;
use num::rational;
use itertools::Itertools;
use bio::stats::logprobs;

use model;

pub type CV = f64;

#[allow(unused_parens)]
pub fn pmf(pmfs: &[model::expressionset::PMF]) -> model::diffexp::PMF {
    let mut pmf = collections::HashMap::new();
    let combinations = iproduct!(pmfs);
    let n = pmfs.len() as f64;

    for groups in combinations {
        let prob = groups.iter().map(|group| group.prob).fold(0.0, |s, p| s + p);
        if prob >= model::MIN_PROB {
            // sample mean
            let mean = groups.iter().map(|group| {
                *group.value.numer() as f64 / *group.value.denom() as f64
            }).fold(0.0, |s, e| s + e) / n;
            // sample standard deviation
            let std = (groups.iter().map(|group| {
                    (*group.value.numer() as f64 / *group.value.denom() as f64 - mean).powi(2)
            }).fold(0.0, |s, e| s + e) / n).sqrt();

            let cv = rational::Ratio::from_float(std / mean).unwrap();

            let mut p = pmf.entry(cv).or_insert(0.0);
            *p = logprobs::add(*p, prob);
        }
    }

    let pmf = pmf.iter().map(|(cv, p)| {
        model::pmf::Entry {
            value: cv.numer().to_f64().unwrap().log2() - cv.denom().to_f64().unwrap().log2(),
            prob: *p
        }
    }).collect_vec();

    model::diffexp::PMF::new(pmf)
}
<commit_msg>Fixes.<commit_after>use std::collections;
use std::f64;

use num::traits::ToPrimitive;
use num::rational;
use itertools::Itertools;
use bio::stats::logprobs;

use model;

pub type CV = f64;

#[allow(unused_parens)]
pub fn pmf(pmfs: &[model::expressionset::PMF]) -> model::diffexp::PMF {
    let mut pmf = collections::HashMap::new();
    let combinations = iproduct!(pmfs);
    let n = pmfs.len() as f64;

    for groups in combinations {
        let prob = groups.iter().map(|group| group.prob).fold(0.0, |s, p| s + p);
        if true || prob >= model::MIN_PROB {
            // sample mean
            let mean = groups.iter().map(|group| {
                *group.value.numer() as f64 / *group.value.denom() as f64
            }).fold(0.0, |s, e| s + e) / n;
            // sample standard deviation
            let std = (groups.iter().map(|group| {
                    (*group.value.numer() as f64 / *group.value.denom() as f64 - mean).powi(2)
            }).fold(0.0, |s, e| s + e) / n).sqrt();

            let cv = rational::Ratio::from_float(std / mean).unwrap();

            let mut p = pmf.entry(cv).or_insert(f64::NEG_INFINITY);
            *p = logprobs::add(*p, prob);
        }
    }

    let pmf = pmf.iter().map(|(cv, p)| {
        model::pmf::Entry {
            value: cv.numer().to_f64().unwrap().log2() - cv.denom().to_f64().unwrap().log2(),
            prob: *p
        }
    }).collect_vec();

    model::diffexp::PMF::new(pmf)
}
<|endoftext|>