<commit_before>use super::http::Log;
use ssz::Decode;
use ssz_derive::{Decode, Encode};
use state_processing::per_block_processing::signature_sets::{
    deposit_pubkey_signature_message, deposit_signature_set,
};
use types::{ChainSpec, DepositData, Hash256, PublicKeyBytes, SignatureBytes};

/// The following constants define the layout of bytes in the deposit contract `DepositEvent`. The
/// event bytes are formatted according to the  Ethereum ABI.
const PUBKEY_START: usize = 192;
const PUBKEY_LEN: usize = 48;
const CREDS_START: usize = PUBKEY_START + 64 + 32;
const CREDS_LEN: usize = 32;
const AMOUNT_START: usize = CREDS_START + 32 + 32;
const AMOUNT_LEN: usize = 8;
const SIG_START: usize = AMOUNT_START + 32 + 32;
const SIG_LEN: usize = 96;
const INDEX_START: usize = SIG_START + 96 + 32;
const INDEX_LEN: usize = 8;

/// A fully parsed eth1 deposit contract log.
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
pub struct DepositLog {
    pub deposit_data: DepositData,
    /// The block number of the log that included this `DepositData`.
    pub block_number: u64,
    /// The index included with the deposit log.
    pub index: u64,
    /// True if the signature is valid.
    pub signature_is_valid: bool,
}

impl DepositLog {
    /// Attempts to parse a raw `Log` from the deposit contract into a `DepositLog`.
    pub fn from_log(log: &Log, spec: &ChainSpec) -> Result<Self, String> {
        let bytes = &log.data;

        let pubkey = bytes
            .get(PUBKEY_START..PUBKEY_START + PUBKEY_LEN)
            .ok_or_else(|| "Insufficient bytes for pubkey".to_string())?;
        let withdrawal_credentials = bytes
            .get(CREDS_START..CREDS_START + CREDS_LEN)
            .ok_or_else(|| "Insufficient bytes for withdrawal credential".to_string())?;
        let amount = bytes
            .get(AMOUNT_START..AMOUNT_START + AMOUNT_LEN)
            .ok_or_else(|| "Insufficient bytes for amount".to_string())?;
        let signature = bytes
            .get(SIG_START..SIG_START + SIG_LEN)
            .ok_or_else(|| "Insufficient bytes for signature".to_string())?;
        let index = bytes
            .get(INDEX_START..INDEX_START + INDEX_LEN)
            .ok_or_else(|| "Insufficient bytes for index".to_string())?;

        let deposit_data = DepositData {
            pubkey: PublicKeyBytes::from_ssz_bytes(pubkey)
                .map_err(|e| format!("Invalid pubkey ssz: {:?}", e))?,
            withdrawal_credentials: Hash256::from_ssz_bytes(withdrawal_credentials)
                .map_err(|e| format!("Invalid withdrawal_credentials ssz: {:?}", e))?,
            amount: u64::from_ssz_bytes(amount)
                .map_err(|e| format!("Invalid amount ssz: {:?}", e))?,
            signature: SignatureBytes::from_ssz_bytes(signature)
                .map_err(|e| format!("Invalid signature ssz: {:?}", e))?,
        };

        let deposit_signature_message = deposit_pubkey_signature_message(&deposit_data, spec)
            .ok_or_else(|| "Unable to prepare deposit signature verification".to_string())?;
        let signature_is_valid = deposit_signature_set(&deposit_signature_message).is_valid();

        Ok(DepositLog {
            deposit_data,
            block_number: log.block_number,
            index: u64::from_ssz_bytes(index).map_err(|e| format!("Invalid index ssz: {:?}", e))?,
            signature_is_valid,
        })
    }
}

#[cfg(test)]
pub mod tests {
    use super::*;
    use crate::http::Log;
    use types::{EthSpec, MainnetEthSpec};

    /// The data from a deposit event, using the v0.8.3 version of the deposit contract.
    pub const EXAMPLE_LOG: &[u8] = &[
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 167, 108, 6, 69, 88, 17, 3, 51, 6, 4, 158, 232, 82,
        248, 218, 2, 71, 219, 55, 102, 86, 125, 136, 203, 36, 77, 64, 213, 43, 52, 175, 154, 239,
        50, 142, 52, 201, 77, 54, 239, 0, 229, 22, 46, 139, 120, 62, 240, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 64, 89, 115, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 140, 74, 175, 158, 209, 20, 206,
        30, 63, 215, 238, 113, 60, 132, 216, 211, 100, 186, 202, 71, 34, 200, 160, 225, 212, 213,
        119, 88, 51, 80, 101, 74, 2, 45, 78, 153, 12, 192, 44, 51, 77, 40, 10, 72, 246, 34, 193,
        187, 22, 95, 4, 211, 245, 224, 13, 162, 21, 163, 54, 225, 22, 124, 3, 56, 14, 81, 122, 189,
        149, 250, 251, 159, 22, 77, 94, 157, 197, 196, 253, 110, 201, 88, 193, 246, 136, 226, 221,
        18, 113, 232, 105, 100, 114, 103, 237, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    ];

    #[test]
    fn can_parse_example_log() {
        let log = Log {
            block_number: 42,
            data: EXAMPLE_LOG.to_vec(),
        };
        DepositLog::from_log(&log, &MainnetEthSpec::default_spec()).expect("should decode log");
    }
}
<commit_msg>Fix early return from DepositLog parsing (#1382)<commit_after>use super::http::Log;
use ssz::Decode;
use ssz_derive::{Decode, Encode};
use state_processing::per_block_processing::signature_sets::{
    deposit_pubkey_signature_message, deposit_signature_set,
};
use types::{ChainSpec, DepositData, Hash256, PublicKeyBytes, SignatureBytes};

/// The following constants define the layout of bytes in the deposit contract `DepositEvent`. The
/// event bytes are formatted according to the  Ethereum ABI.
const PUBKEY_START: usize = 192;
const PUBKEY_LEN: usize = 48;
const CREDS_START: usize = PUBKEY_START + 64 + 32;
const CREDS_LEN: usize = 32;
const AMOUNT_START: usize = CREDS_START + 32 + 32;
const AMOUNT_LEN: usize = 8;
const SIG_START: usize = AMOUNT_START + 32 + 32;
const SIG_LEN: usize = 96;
const INDEX_START: usize = SIG_START + 96 + 32;
const INDEX_LEN: usize = 8;

/// A fully parsed eth1 deposit contract log.
#[derive(Debug, PartialEq, Clone, Encode, Decode)]
pub struct DepositLog {
    pub deposit_data: DepositData,
    /// The block number of the log that included this `DepositData`.
    pub block_number: u64,
    /// The index included with the deposit log.
    pub index: u64,
    /// True if the signature is valid.
    pub signature_is_valid: bool,
}

impl DepositLog {
    /// Attempts to parse a raw `Log` from the deposit contract into a `DepositLog`.
    pub fn from_log(log: &Log, spec: &ChainSpec) -> Result<Self, String> {
        let bytes = &log.data;

        let pubkey = bytes
            .get(PUBKEY_START..PUBKEY_START + PUBKEY_LEN)
            .ok_or_else(|| "Insufficient bytes for pubkey".to_string())?;
        let withdrawal_credentials = bytes
            .get(CREDS_START..CREDS_START + CREDS_LEN)
            .ok_or_else(|| "Insufficient bytes for withdrawal credential".to_string())?;
        let amount = bytes
            .get(AMOUNT_START..AMOUNT_START + AMOUNT_LEN)
            .ok_or_else(|| "Insufficient bytes for amount".to_string())?;
        let signature = bytes
            .get(SIG_START..SIG_START + SIG_LEN)
            .ok_or_else(|| "Insufficient bytes for signature".to_string())?;
        let index = bytes
            .get(INDEX_START..INDEX_START + INDEX_LEN)
            .ok_or_else(|| "Insufficient bytes for index".to_string())?;

        let deposit_data = DepositData {
            pubkey: PublicKeyBytes::from_ssz_bytes(pubkey)
                .map_err(|e| format!("Invalid pubkey ssz: {:?}", e))?,
            withdrawal_credentials: Hash256::from_ssz_bytes(withdrawal_credentials)
                .map_err(|e| format!("Invalid withdrawal_credentials ssz: {:?}", e))?,
            amount: u64::from_ssz_bytes(amount)
                .map_err(|e| format!("Invalid amount ssz: {:?}", e))?,
            signature: SignatureBytes::from_ssz_bytes(signature)
                .map_err(|e| format!("Invalid signature ssz: {:?}", e))?,
        };

        let signature_is_valid = deposit_pubkey_signature_message(&deposit_data, spec)
            .map_or(false, |msg| deposit_signature_set(&msg).is_valid());

        Ok(DepositLog {
            deposit_data,
            block_number: log.block_number,
            index: u64::from_ssz_bytes(index).map_err(|e| format!("Invalid index ssz: {:?}", e))?,
            signature_is_valid,
        })
    }
}

#[cfg(test)]
pub mod tests {
    use super::*;
    use crate::http::Log;
    use types::{EthSpec, MainnetEthSpec};

    /// The data from a deposit event, using the v0.8.3 version of the deposit contract.
    pub const EXAMPLE_LOG: &[u8] = &[
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 1, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 167, 108, 6, 69, 88, 17, 3, 51, 6, 4, 158, 232, 82,
        248, 218, 2, 71, 219, 55, 102, 86, 125, 136, 203, 36, 77, 64, 213, 43, 52, 175, 154, 239,
        50, 142, 52, 201, 77, 54, 239, 0, 229, 22, 46, 139, 120, 62, 240, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 64, 89, 115, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 140, 74, 175, 158, 209, 20, 206,
        30, 63, 215, 238, 113, 60, 132, 216, 211, 100, 186, 202, 71, 34, 200, 160, 225, 212, 213,
        119, 88, 51, 80, 101, 74, 2, 45, 78, 153, 12, 192, 44, 51, 77, 40, 10, 72, 246, 34, 193,
        187, 22, 95, 4, 211, 245, 224, 13, 162, 21, 163, 54, 225, 22, 124, 3, 56, 14, 81, 122, 189,
        149, 250, 251, 159, 22, 77, 94, 157, 197, 196, 253, 110, 201, 88, 193, 246, 136, 226, 221,
        18, 113, 232, 105, 100, 114, 103, 237, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    ];

    #[test]
    fn can_parse_example_log() {
        let log = Log {
            block_number: 42,
            data: EXAMPLE_LOG.to_vec(),
        };
        DepositLog::from_log(&log, &MainnetEthSpec::default_spec()).expect("should decode log");
    }
}
<|endoftext|>


<commit_before>use bt_messages::Message;
use buffered_reader::BufferedReader;
use std::net::TcpStream;
use std::sync::mpsc::Sender;
use std::io::Write;
use std::cmp::Ordering;
const BLOCK_LENGTH:usize = 16384; //block length in bytes

#[derive(PartialEq, Debug)]
pub struct Position {
    index: usize,
    offset: usize
}

impl Position {
    pub fn new (index: usize, offset: usize) -> Position {
        Position {
            index: index,
            offset: offset
        }
    }
}

impl PartialOrd for Position {
    fn partial_cmp (&self, rhs: &Position) -> Option<Ordering> {
         if self.index < rhs.index {
            Some(Ordering::Less)
         } else if self.index < rhs.index {
            Some(Ordering::Greater)
         } else {
            if self.offset < rhs.offset {
                Some(Ordering::Less)
            } else if self.offset > rhs.offset {
                Some(Ordering::Greater)
            } else {
                Some(Ordering::Equal)
            }
         }
    }
}

#[derive(PartialEq, Debug)]
pub struct Block {
    start: Position,
    end: Position
}

impl Block {
    pub fn new (start: Position, end: Position) -> Block {
        Block {
            start: start,
            end: end
        }
    }
}

/// Handles messages. This is a cheap way to force reactive style
pub trait Handler {
    type MessageType;
    fn handle(&mut self, message: Self::MessageType, peer: &mut Peer);
}

//TODO: state probably shouldn't be stored here in the handler... eventually move it back in main. for each
//torrent
pub struct DefaultHandler {
    //the global piece count
    gpc: Vec<u16>,
    //pieces owned by self. (as a bitfield)
    pub owned: Vec<u8>,
    //outgoing requests
    pub request_map: Vec<u8>,

    s_request_map: Vec<Block>,
    piece_length: usize
}

impl DefaultHandler {
    pub fn new (piece_length: usize) -> DefaultHandler {
        DefaultHandler {
            gpc: vec![],
            owned: vec![],
            request_map: vec![],
            s_request_map: vec![],
            piece_length: piece_length
        }
    }

    /*
    pub fn get_block_boundaries (piece_length: usize, index: usize, offset: usize, bytes: usize) -> Block {
        assert!(bytes > 0);
        let residue_blocks = (bytes-1) % piece_length;

        let whole_blocks_occupied = bytes/piece_length;
        let additional = bytes % piece_length;
        let nml_offset = (residue_blocks+offset) % piece_length;

        let index_offset =
            if additional == 0 {
                whole_blocks_occupied - 1
            } else {
                whole_blocks_occupied
        };

        let start = Position {
            index: index,
            offset: offset
        };

        let end = Position {
            index: index + index_offset,
            offset: nml_offset
        };

        Block{start: start, end: end}
    }*/

    pub fn get_block_boundaries (piece_length: usize, index: usize, offset: usize, bytes: usize) -> Block {
        let num_whole_pieces = bytes/piece_length;
        let rem_offset = (offset + bytes) % piece_length;

        let start = Position {
            index: index,
            offset: offset
        };
        let end = Position {
            index: index + num_whole_pieces,
            offset: rem_offset
        };

        Block{start: start, end: end}
    }

    pub fn add_request(arr: &mut Vec<Block>, index: usize, offset: usize, bytes: usize, piece_length: usize) {
        if arr.len() == 0 {
            arr.push(DefaultHandler::get_block_boundaries(piece_length, index, offset, bytes));
        } else {
            let (mut win_left, mut win_right) = (0, arr.len());
            let position = Position {index: index, offset: offset};
            loop {
                let arr_index = (win_left+win_right)/2;
                let block = &arr[arr_index];
                if position > block.end {
                    win_left = arr_index;
                } else if position < block.start {
                    win_right = arr_index;
                } else {
                    //we have a bingo
                    break;
                }
            }
        }
    }
    /// Increases the value of gpc[piece_index] by n
    #[inline]
    pub fn gpc_incr (&mut self, piece_index: usize, n: u16) {
        //starting to regret making the bitfield variable in size... maybe i can preallocate. will come back and re-eval
        let len = self.gpc.len();
        if piece_index >= len {
            self.gpc.extend((0..piece_index+1 - len).map(|_| 0));
        }
        self.gpc[piece_index] += n;
    }

    /// Returns the index of the rarest piece that isn't owned or currently being requested.
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest (&self) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        for (index, byte) in self.unclaimed_fields().iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// Returns the index of the rarest piece that is owned by the peer and isn't both owned
    /// and currently being requested
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest_wrt_peer (&self, peer_bitfield: &Vec<u8>) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        let eligible = and_slice_vbr_len(&self.unclaimed_fields(), &peer_bitfield);
        for (index, byte) in eligible.iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                //println!("n: {}", n);
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// returns a complete bitfield of pieces that aren't owned or being requested
    /// this is done almost as strictly as possible - and might be a little of a waste as it isn't
    /// really necessary to get a complete picture to get a request chunk
    /// additionally the definitions of owned and request_map are not strict yet - currently they
    /// are growable, and impelementers should take note of that
    #[inline]
    pub fn unclaimed_fields (&self) -> Vec<u8> {
        nand_slice_vbr_len(&self.owned, &self.request_map)
    }

    #[inline]
    pub fn req (&mut self, peer_bitfield: &Vec<u8>) {
        let index = self.rarest_wrt_peer(peer_bitfield);
        println!("REQ: {:?}", index);
    }
}

/// The default algorithm
impl Handler for DefaultHandler {
    type MessageType = Message;
    #[inline]
    fn handle (&mut self, message: Message, peer: &mut Peer) {
        println!("{:?}", message);
        match message {
            Message::Have{piece_index: index} => {
                let i = index as usize;
                self.gpc_incr(i, 1);
                peer.state.set_have(i);
                self.req(&peer.state.bitfield);
            },
            Message::Choke => {
                peer.state.set_us_choked(true);
            },
            Message::Unchoke => {
                peer.state.set_us_choked(false);
            },
            Message::Interested => {
                peer.state.set_us_interested(true);
            },
            Message::Bitfield(bitfield) => {
                for (index, byte) in bitfield.iter().enumerate() {
                    for i in 0..8 { //cast up so i don't have to deal with overflows
                        let n = 1 & (((*byte as u16) << i) >> (8-i));
                        self.gpc_incr(index*8+i, n);
                    }
                }
                peer.state.set_bitfield(bitfield);

                /*
                let candidates = self.unclaimed_fields();
                let request = peer.get_request(&candidates);
                */

                self.req(&peer.state.bitfield);
            },
            _ => {
            }
        };
    }
}

pub struct Peer {
    pub id: String,
    stream: TcpStream,
    pub state: State
}

impl Peer {
    pub fn new (id:String, stream: TcpStream) -> Peer {
        Peer {
            id: id,
            stream: stream,
            state: State::new()
        }
    }

    pub fn send_message (&mut self, message: Message) {
        let as_bytes = message.to_byte_array();
        let _ = self.stream.write_all(&as_bytes);
    }
}

#[derive(Debug)]
pub struct State {
    //are we choked by them?
    pub us_choked: bool,
    //are we interested in them?
    pub us_interested: bool,
    //are they choked by us?
    pub is_choked: bool,
    //are they interested in us?
    pub is_interested: bool,
    //the intention is that eventually we will support growable files. so going with vector
    pub bitfield: Vec<u8>
}

impl State {
    pub fn new () -> State {
        State {
            us_choked: true,
            us_interested: false,
            is_choked: true,
            is_interested: false,
            bitfield: vec![]
        }
    }

    pub fn set_us_interested (&mut self, us_interested: bool) {
        self.us_interested = us_interested;
    }

    pub fn set_bitfield (&mut self, bitfield: Vec<u8>) {
        self.bitfield = bitfield;
    }

    pub fn set_have (&mut self, index: usize) {
        set_have_bitfield(&mut self.bitfield, index);
    }

    pub fn set_us_choked (&mut self, us_choked: bool) {
        self.us_choked = us_choked;
    }
}

#[inline]
fn set_have_bitfield (bitfield: &mut Vec<u8>, index: usize) {
    let chunk_index = index/8;
    let chunk_posit = index % 8;
    let chunk_mask = 128 >> chunk_posit;

    //bounds check needs to be here because the bitfield is a variable size - which we want in
    //the future
    if chunk_index+1 > bitfield.len() {
        bitfield.extend((0..chunk_index).map(|_| 0));
    }

    bitfield[chunk_index] = bitfield[chunk_index] | chunk_mask;
}

/// Zip-maps a generic func over two byte slices with variable lengths
#[inline]
pub fn apply_bitwise_slice_vbr_len <F, T:Clone> (lhs: &[T], rhs: &[T], default: T, func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    if lhs.len() == rhs.len() {
        bitwise_byte_slice(lhs, rhs, func)
    } else {
        if lhs.len() < rhs.len() {
            //let mut a = (&rhs[..lhs.len()]).to_owned();
            let mut a = lhs.to_owned();
            a.extend((0..rhs.len()-lhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(&a, rhs, func)
        } else {
            let mut b = rhs.to_owned();
            b.extend((0..lhs.len()-rhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(lhs, &b, func)
        }
    }
}

/// Zip-maps a generic func (intended bitwise) over two byte slices
#[inline]
pub fn bitwise_byte_slice <F, T> (lhs: &[T], rhs: &[T], func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    println!("llen: {}, rlen: {}", lhs.len(), rhs.len());
    assert!(lhs.len() == rhs.len());
    lhs.iter().zip(rhs)
              .map(func)
              .collect::<Vec<T>>()
}

#[inline]
pub fn nand_slice_vbr_len (lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 0, |(a, b)| !a & !b)
}

#[inline]
pub fn and_slice_vbr_len(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    println!("lhs: {:?}", lhs);
    println!("rhs: {:?}", rhs);
    apply_bitwise_slice_vbr_len(lhs, rhs, 255, |(a, b)| a & b)
}
<commit_msg>added inclusive mode for get_block_boundariesg<commit_after>use bt_messages::Message;
use buffered_reader::BufferedReader;
use std::net::TcpStream;
use std::sync::mpsc::Sender;
use std::io::Write;
use std::cmp::Ordering;
const BLOCK_LENGTH:usize = 16384; //block length in bytes

#[derive(PartialEq, Debug)]
pub struct Position {
    index: usize,
    offset: usize
}

impl Position {
    pub fn new (index: usize, offset: usize) -> Position {
        Position {
            index: index,
            offset: offset
        }
    }
}

impl PartialOrd for Position {
    fn partial_cmp (&self, rhs: &Position) -> Option<Ordering> {
         if self.index < rhs.index {
            Some(Ordering::Less)
         } else if self.index < rhs.index {
            Some(Ordering::Greater)
         } else {
            if self.offset < rhs.offset {
                Some(Ordering::Less)
            } else if self.offset > rhs.offset {
                Some(Ordering::Greater)
            } else {
                Some(Ordering::Equal)
            }
         }
    }
}

#[derive(PartialEq, Debug)]
pub struct Block {
    start: Position,
    end: Position
}

impl Block {
    pub fn new (start: Position, end: Position) -> Block {
        Block {
            start: start,
            end: end
        }
    }
}

/// Handles messages. This is a cheap way to force reactive style
pub trait Handler {
    type MessageType;
    fn handle(&mut self, message: Self::MessageType, peer: &mut Peer);
}

//TODO: state probably shouldn't be stored here in the handler... eventually move it back in main. for each
//torrent
pub struct DefaultHandler {
    //the global piece count
    gpc: Vec<u16>,
    //pieces owned by self. (as a bitfield)
    pub owned: Vec<u8>,
    //outgoing requests
    pub request_map: Vec<u8>,

    s_request_map: Vec<Block>,
    piece_length: usize
}

impl DefaultHandler {
    pub fn new (piece_length: usize) -> DefaultHandler {
        DefaultHandler {
            gpc: vec![],
            owned: vec![],
            request_map: vec![],
            s_request_map: vec![],
            piece_length: piece_length
        }
    }

    //start is inclusive, end is exclusive
    pub fn get_block_boundaries (piece_length: usize, index: usize, offset: usize, bytes: usize) -> Block {
        let num_whole_pieces = bytes/piece_length;
        let rem_offset = (offset + bytes) % piece_length;

        let start = Position {
            index: index,
            offset: offset
        };
        let end = Position {
            index: index + num_whole_pieces,
            offset: rem_offset
        };

        Block{start: start, end: end}
    }

    //both start and end are inclusive
    pub fn get_block_boundaries_inclusive (piece_length: usize, index: usize, offset: usize, bytes: usize) -> Block {
        let num_whole_pieces = bytes/piece_length;
        let rem_offset = (offset + bytes) % piece_length;

        let start = Position {
            index: index,
            offset: offset
        };
        let end = Position {
            index: index + num_whole_pieces,
            offset: rem_offset
        };

        let n_offset = ((end.offset as i32  - 1 + piece_length as i32) % piece_length as i32) as usize;
        let n_index = end.index - if n_offset == piece_length-1 { 1 } else { 0 };

        let n_end = Position {
            index: n_index,
            offset: n_offset
        };

        Block{start: start, end: n_end}
    }

    pub fn add_request(arr: &mut Vec<Block>, index: usize, offset: usize, bytes: usize, piece_length: usize) {
        if arr.len() == 0 {
            arr.push(DefaultHandler::get_block_boundaries(piece_length, index, offset, bytes));
        } else {
            let (mut win_left, mut win_right) = (0, arr.len());
            let position = Position {index: index, offset: offset};
            loop {
                let arr_index = (win_left+win_right)/2;
                let block = &arr[arr_index];
                if position > block.end {
                    win_left = arr_index;
                } else if position < block.start {
                    win_right = arr_index;
                } else {
                    //we have a bingo
                    break;
                }
            }
        }
    }
    /// Increases the value of gpc[piece_index] by n
    #[inline]
    pub fn gpc_incr (&mut self, piece_index: usize, n: u16) {
        //starting to regret making the bitfield variable in size... maybe i can preallocate. will come back and re-eval
        let len = self.gpc.len();
        if piece_index >= len {
            self.gpc.extend((0..piece_index+1 - len).map(|_| 0));
        }
        self.gpc[piece_index] += n;
    }

    /// Returns the index of the rarest piece that isn't owned or currently being requested.
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest (&self) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        for (index, byte) in self.unclaimed_fields().iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// Returns the index of the rarest piece that is owned by the peer and isn't both owned
    /// and currently being requested
    /// TODO: Approximations may yield optimized results
    #[inline]
    pub fn rarest_wrt_peer (&self, peer_bitfield: &Vec<u8>) -> Option<usize> {
        //there's probably a faster way. doing this naively for the sake of forward progress
        let mut most_rare = (None, u16::max_value());
        let eligible = and_slice_vbr_len(&self.unclaimed_fields(), &peer_bitfield);
        for (index, byte) in eligible.iter().enumerate() {
            for i in 0..8 { //cast up so i don't have to deal with overflows
                let n = 1 & (((*byte as u16) << i) >> (8-i));
                //println!("n: {}", n);
                if n == 1 {
                    let true_index = index*8+1;
                    let population = self.gpc[true_index];
                    let (_, mr_pop) = most_rare;
                    if population < mr_pop {
                        most_rare = (Some(true_index), population)
                    }
                }
            }
        }
        let (index, _) = most_rare;
        index
    }

    /// returns a complete bitfield of pieces that aren't owned or being requested
    /// this is done almost as strictly as possible - and might be a little of a waste as it isn't
    /// really necessary to get a complete picture to get a request chunk
    /// additionally the definitions of owned and request_map are not strict yet - currently they
    /// are growable, and impelementers should take note of that
    #[inline]
    pub fn unclaimed_fields (&self) -> Vec<u8> {
        nand_slice_vbr_len(&self.owned, &self.request_map)
    }

    #[inline]
    pub fn req (&mut self, peer_bitfield: &Vec<u8>) {
        let index = self.rarest_wrt_peer(peer_bitfield);
        println!("REQ: {:?}", index);
    }
}

/// The default algorithm
impl Handler for DefaultHandler {
    type MessageType = Message;
    #[inline]
    fn handle (&mut self, message: Message, peer: &mut Peer) {
        println!("{:?}", message);
        match message {
            Message::Have{piece_index: index} => {
                let i = index as usize;
                self.gpc_incr(i, 1);
                peer.state.set_have(i);
                self.req(&peer.state.bitfield);
            },
            Message::Choke => {
                peer.state.set_us_choked(true);
            },
            Message::Unchoke => {
                peer.state.set_us_choked(false);
            },
            Message::Interested => {
                peer.state.set_us_interested(true);
            },
            Message::Bitfield(bitfield) => {
                for (index, byte) in bitfield.iter().enumerate() {
                    for i in 0..8 { //cast up so i don't have to deal with overflows
                        let n = 1 & (((*byte as u16) << i) >> (8-i));
                        self.gpc_incr(index*8+i, n);
                    }
                }
                peer.state.set_bitfield(bitfield);

                /*
                let candidates = self.unclaimed_fields();
                let request = peer.get_request(&candidates);
                */

                self.req(&peer.state.bitfield);
            },
            _ => {
            }
        };
    }
}

pub struct Peer {
    pub id: String,
    stream: TcpStream,
    pub state: State
}

impl Peer {
    pub fn new (id:String, stream: TcpStream) -> Peer {
        Peer {
            id: id,
            stream: stream,
            state: State::new()
        }
    }

    pub fn send_message (&mut self, message: Message) {
        let as_bytes = message.to_byte_array();
        let _ = self.stream.write_all(&as_bytes);
    }
}

#[derive(Debug)]
pub struct State {
    //are we choked by them?
    pub us_choked: bool,
    //are we interested in them?
    pub us_interested: bool,
    //are they choked by us?
    pub is_choked: bool,
    //are they interested in us?
    pub is_interested: bool,
    //the intention is that eventually we will support growable files. so going with vector
    pub bitfield: Vec<u8>
}

impl State {
    pub fn new () -> State {
        State {
            us_choked: true,
            us_interested: false,
            is_choked: true,
            is_interested: false,
            bitfield: vec![]
        }
    }

    pub fn set_us_interested (&mut self, us_interested: bool) {
        self.us_interested = us_interested;
    }

    pub fn set_bitfield (&mut self, bitfield: Vec<u8>) {
        self.bitfield = bitfield;
    }

    pub fn set_have (&mut self, index: usize) {
        set_have_bitfield(&mut self.bitfield, index);
    }

    pub fn set_us_choked (&mut self, us_choked: bool) {
        self.us_choked = us_choked;
    }
}

#[inline]
fn set_have_bitfield (bitfield: &mut Vec<u8>, index: usize) {
    let chunk_index = index/8;
    let chunk_posit = index % 8;
    let chunk_mask = 128 >> chunk_posit;

    //bounds check needs to be here because the bitfield is a variable size - which we want in
    //the future
    if chunk_index+1 > bitfield.len() {
        bitfield.extend((0..chunk_index).map(|_| 0));
    }

    bitfield[chunk_index] = bitfield[chunk_index] | chunk_mask;
}

/// Zip-maps a generic func over two byte slices with variable lengths
#[inline]
pub fn apply_bitwise_slice_vbr_len <F, T:Clone> (lhs: &[T], rhs: &[T], default: T, func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    if lhs.len() == rhs.len() {
        bitwise_byte_slice(lhs, rhs, func)
    } else {
        if lhs.len() < rhs.len() {
            //let mut a = (&rhs[..lhs.len()]).to_owned();
            let mut a = lhs.to_owned();
            a.extend((0..rhs.len()-lhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(&a, rhs, func)
        } else {
            let mut b = rhs.to_owned();
            b.extend((0..lhs.len()-rhs.len()).map(|_| default.clone()));
            bitwise_byte_slice(lhs, &b, func)
        }
    }
}

/// Zip-maps a generic func (intended bitwise) over two byte slices
#[inline]
pub fn bitwise_byte_slice <F, T> (lhs: &[T], rhs: &[T], func: F) -> Vec<T>
    where F: Fn((&T, &T)) -> T {
    println!("llen: {}, rlen: {}", lhs.len(), rhs.len());
    assert!(lhs.len() == rhs.len());
    lhs.iter().zip(rhs)
              .map(func)
              .collect::<Vec<T>>()
}

#[inline]
pub fn nand_slice_vbr_len (lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    apply_bitwise_slice_vbr_len(lhs, rhs, 0, |(a, b)| !a & !b)
}

#[inline]
pub fn and_slice_vbr_len(lhs: &[u8], rhs: &[u8]) -> Vec<u8> {
    println!("lhs: {:?}", lhs);
    println!("rhs: {:?}", rhs);
    apply_bitwise_slice_vbr_len(lhs, rhs, 255, |(a, b)| a & b)
}
<|endoftext|>


<commit_before>use curve::point::*;
use field::prime_field::PrimeField;
use std::ops::Add;
use std::ops::AddAssign;

pub trait EdwardsCurve : Copy {
    type Scalar : PrimeField + Copy;

    fn d_val() -> Self::Scalar;
}

/// Edwards curve point in homogeneous extended coordinates.
#[derive(Copy, Clone)]
pub struct EdwardsExtended<C : EdwardsCurve> {
    x : C::Scalar,
    y : C::Scalar,
    z : C::Scalar,
    t : C::Scalar
}

impl<'b, C : EdwardsCurve> AddAssign<&'b EdwardsExtended<C>>
    for EdwardsExtended<C> {
    fn add_assign(&mut self, rhs: &'b EdwardsExtended<C>) {
        let a = self.x * rhs.x;
        let b = self.y * rhs.y;
        let c = self.t * C::d_val() * rhs.t;
        let d = self.z * rhs.z;
        let e = ((self.x + self.y) * (rhs.x + rhs.y)) - a - b;
        let f = d - c;
        let g = d + c;
        let h = b - a;
        let x3 = e * f;
        let y3 = g * h;
        let z3 = f * g;
        let t3 = e * h;

        self.x = x3;
        self.y = y3;
        self.z = z3;
        self.t = t3;
    }
}

impl<C : EdwardsCurve> AddAssign<EdwardsExtended<C>>
    for EdwardsExtended<C> {
    fn add_assign(&mut self, rhs: EdwardsExtended<C>) {
        *self += &rhs;
    }
}

impl<'a, 'b, C : EdwardsCurve> Add<&'b EdwardsExtended<C>>
    for &'a EdwardsExtended<C> {
    type Output = EdwardsExtended<C>;

    fn add(self, rhs: &'b EdwardsExtended<C>) -> EdwardsExtended<C> {
        let mut out = self.clone();
        out += rhs;
        out
    }
}

impl<C : EdwardsCurve> Add<EdwardsExtended<C>> for EdwardsExtended<C> {
    type Output = EdwardsExtended<C>;

    fn add(self, rhs: EdwardsExtended<C>) -> EdwardsExtended<C> {
        &self + &rhs
    }
}

impl<C: EdwardsCurve> Point for EdwardsExtended<C> {
    type Scalar = C::Scalar;

    fn zero() -> Self {
        EdwardsExtended {
            x: C::Scalar::zero(),
            y: C::Scalar::one(),
            z: C::Scalar::one(),
            t: C::Scalar::one()
        }
    }

    fn init(&mut self, x: C::Scalar, y: C::Scalar) {
        self.x = x;
        self.y = y;
        self.z = C::Scalar::one();
        self.t = C::Scalar::one();
    }

    fn scalar_mult(&mut self, rhs: &mut Self::Scalar) {
        rhs.normalize();
        self.scalar_mult_normalized(rhs);
    }

    fn scalar_mult_normalized(&mut self, rhs: &Self::Scalar) {
        // This is a branchless variant of the classic Montgomery
        // ladder using bitwise operations in lieu of branches.  It
        // costs an additional doubling operation per step, but
        // eliminates all control-flow dependence on the data.

        let mut r0 = Self::zero();
        let mut r1 = self.clone();
        let nbits = C::Scalar::nbits();

        for i in 0..nbits {
            let idx = nbits - 1 - i;
            let bit = rhs.bit_normalized(idx);
            let tmask = C::Scalar::filled(bit);
            let fmask = C::Scalar::filled(!bit);
            let mut r0d = r0.doubled();
            let mut r1d = r1.doubled();

            r0 += r1;
            r0.x.normalize();
            r0.y.normalize();
            r0.z.normalize();
            r0.t.normalize();
            r1 = r0;

            r0.x.normalized_bitand(&fmask);
            r0.y.normalized_bitand(&fmask);
            r0.z.normalized_bitand(&fmask);
            r0.t.normalized_bitand(&fmask);

            r0d.x.normalize_self_bitand(&tmask);
            r0d.y.normalize_self_bitand(&tmask);
            r0d.z.normalize_self_bitand(&tmask);
            r0d.t.normalize_self_bitand(&tmask);

            r0.x.normalized_bitor(&r0d.x);
            r0.y.normalized_bitor(&r0d.y);
            r0.z.normalized_bitor(&r0d.z);
            r0.t.normalized_bitor(&r0d.t);

            r1.x.normalized_bitand(&tmask);
            r1.y.normalized_bitand(&tmask);
            r1.z.normalized_bitand(&tmask);
            r1.t.normalized_bitand(&tmask);

            r1d.x.normalize_self_bitand(&fmask);
            r1d.y.normalize_self_bitand(&fmask);
            r1d.z.normalize_self_bitand(&fmask);
            r1d.t.normalize_self_bitand(&fmask);

            r1.x.normalized_bitor(&r1d.x);
            r1.y.normalized_bitor(&r1d.y);
            r1.z.normalized_bitor(&r1d.z);
            r1.t.normalized_bitor(&r1d.t);
        }

        self.x = r0.x;
        self.y = r0.y;
        self.z = r0.z;
        self.t = r0.t;
    }

    fn double(&mut self) {
        let a = self.x.squared();
        let b = self.y.squared();
        let c = self.z.squared().small_mul(2);
        let d = a;
        let e = (self.x + self.y).squared() - a - b;
        let g = d + b;
        let f = g - c;
        let h = d - b;
        let x3 = e * f;
        let y3 = g * h;
        let z3 = f * g;
        let t3 = e * h;

        self.x = x3;
        self.y = y3;
        self.z = z3;
        self.t = t3;
    }

    fn doubled(&self) -> Self {
        let mut out = self.clone();
        out.double();
        out
    }

    fn triple(&mut self) {
        let yy = self.y.squared();
        let xx = self.x.squared();
        let ap = yy + xx;
        let b = (self.z.squared().small_mul(2) - ap).small_mul(2);
        let xb = xx * b;
        let yb = yy * b;
        let aa = ap * (yy - xx);
        let f = aa - yb;
        let g = aa - xb;
        let xe = self.x * (yb + aa);
        let yh = self.y * (xb - aa);
        let zf = self.z * f;
        let zg = self.z * g;
        let x3 = xe * zf;
        let y3 = yh * zg;
        let z3 = zf * zg;
        let t3 = xe * yh;

        self.x = x3;
        self.y = y3;
        self.z = z3;
        self.t = t3;
    }

    fn tripled(&self) -> Self {
        let mut out = self.clone();
        out.triple();
        out
    }
}
<commit_msg>Remove duplicate use of double, fix up implementation<commit_after>use curve::point::*;
use field::prime_field::PrimeField;
use std::ops::Add;
use std::ops::AddAssign;

pub trait EdwardsCurve : Copy {
    type Scalar : PrimeField + Copy;

    fn d_val() -> Self::Scalar;
}

/// Edwards curve point in homogeneous extended coordinates.
#[derive(Copy, Clone)]
pub struct EdwardsExtended<C : EdwardsCurve> {
    x : C::Scalar,
    y : C::Scalar,
    z : C::Scalar,
    t : C::Scalar
}

impl<'b, C : EdwardsCurve> AddAssign<&'b EdwardsExtended<C>>
    for EdwardsExtended<C> {
    fn add_assign(&mut self, rhs: &'b EdwardsExtended<C>) {
        let a = self.x * rhs.x;
        let b = self.y * rhs.y;
        let c = self.t * C::d_val() * rhs.t;
        let d = self.z * rhs.z;
        let e = ((self.x + self.y) * (rhs.x + rhs.y)) - a - b;
        let f = d - c;
        let g = d + c;
        let h = b - a;
        let x3 = e * f;
        let y3 = g * h;
        let z3 = f * g;
        let t3 = e * h;

        self.x = x3;
        self.y = y3;
        self.z = z3;
        self.t = t3;
    }
}

impl<C : EdwardsCurve> AddAssign<EdwardsExtended<C>>
    for EdwardsExtended<C> {
    fn add_assign(&mut self, rhs: EdwardsExtended<C>) {
        *self += &rhs;
    }
}

impl<'a, 'b, C : EdwardsCurve> Add<&'b EdwardsExtended<C>>
    for &'a EdwardsExtended<C> {
    type Output = EdwardsExtended<C>;

    fn add(self, rhs: &'b EdwardsExtended<C>) -> EdwardsExtended<C> {
        let mut out = self.clone();
        out += rhs;
        out
    }
}

impl<C : EdwardsCurve> Add<EdwardsExtended<C>> for EdwardsExtended<C> {
    type Output = EdwardsExtended<C>;

    fn add(self, rhs: EdwardsExtended<C>) -> EdwardsExtended<C> {
        &self + &rhs
    }
}

impl<C: EdwardsCurve> EdwardsExtended<C> {
    fn normalized_bitand(&mut self, mask: &C::Scalar) {
        self.x.normalized_bitand(mask);
        self.y.normalized_bitand(mask);
        self.z.normalized_bitand(mask);
        self.t.normalized_bitand(mask);
    }

    fn normalized_bitor(&mut self, rhs: &Self) {
        self.x.normalized_bitor(&rhs.x);
        self.y.normalized_bitor(&rhs.y);
        self.z.normalized_bitor(&rhs.z);
        self.t.normalized_bitor(&rhs.t);
    }
}

impl<C: EdwardsCurve> Point for EdwardsExtended<C> {
    type Scalar = C::Scalar;

    fn zero() -> Self {
        EdwardsExtended {
            x: C::Scalar::zero(),
            y: C::Scalar::one(),
            z: C::Scalar::one(),
            t: C::Scalar::one()
        }
    }

    fn init(&mut self, x: C::Scalar, y: C::Scalar) {
        self.x = x;
        self.y = y;
        self.z = C::Scalar::one();
        self.t = C::Scalar::one();
    }

    fn scalar_mult(&mut self, rhs: &mut Self::Scalar) {
        rhs.normalize();
        self.scalar_mult_normalized(rhs);
    }

    fn scalar_mult_normalized(&mut self, rhs: &Self::Scalar) {
        // This is a branchless variant of the classic Montgomery
        // ladder using bitwise operations in lieu of branches.

        let mut r0 = Self::zero();
        let mut r1 = self.clone();
        let nbits = C::Scalar::nbits();

        for i in 0..nbits {
            let idx = nbits - 1 - i;
            let bit = rhs.bit_normalized(idx);
            // Note that we fill everything with 0s or 1s.  This
            // allows us to skip normalization.
            let tmask = C::Scalar::filled(bit);
            let fmask = C::Scalar::filled(!bit);
            let mut d0 = r0;
            let mut d1 = r1;

            // r0 = r1 = r0 + r1
            r0 += r1;
            r1 = r0;

            // d0 = bit ? r0 : r1
            d0.normalized_bitand(&tmask);
            d1.normalized_bitand(&fmask);
            d0.normalized_bitor(&d1);

            // d0 *= 2
            d0.double();

            // d1 = d0
            d1 = d0;

            // r0 = bit ? d0 : r0
            r0.normalized_bitand(&fmask);
            d0.normalized_bitand(&tmask);
            r0.normalized_bitor(&d0);

            // r1 = bit ? r1 : d1
            r1.normalized_bitand(&tmask);
            d1.normalized_bitand(&fmask);
            r1.normalized_bitor(&d1);
        }

        self.x = r0.x;
        self.y = r0.y;
        self.z = r0.z;
        self.t = r0.t;
    }

    fn double(&mut self) {
        let a = self.x.squared();
        let b = self.y.squared();
        let c = self.z.squared().small_mul(2);
        let d = a;
        let e = (self.x + self.y).squared() - a - b;
        let g = d + b;
        let f = g - c;
        let h = d - b;
        let x3 = e * f;
        let y3 = g * h;
        let z3 = f * g;
        let t3 = e * h;

        self.x = x3;
        self.y = y3;
        self.z = z3;
        self.t = t3;
    }

    fn doubled(&self) -> Self {
        let mut out = self.clone();
        out.double();
        out
    }

    fn triple(&mut self) {
        let yy = self.y.squared();
        let xx = self.x.squared();
        let ap = yy + xx;
        let b = (self.z.squared().small_mul(2) - ap).small_mul(2);
        let xb = xx * b;
        let yb = yy * b;
        let aa = ap * (yy - xx);
        let f = aa - yb;
        let g = aa - xb;
        let xe = self.x * (yb + aa);
        let yh = self.y * (xb - aa);
        let zf = self.z * f;
        let zg = self.z * g;
        let x3 = xe * zf;
        let y3 = yh * zg;
        let z3 = zf * zg;
        let t3 = xe * yh;

        self.x = x3;
        self.y = y3;
        self.z = z3;
        self.t = t3;
    }

    fn tripled(&self) -> Self {
        let mut out = self.clone();
        out.triple();
        out
    }
}
<|endoftext|>


<commit_before>use std::fs::{self, File};
use std::io::{self, Write, Read, BufWriter};
use std::mem;
use std::path::Path;
use std::sync::mpsc::Receiver;
use std::thread;
use std::time::Duration;
use arguments::Args;
use filepaths;
use misc::Digits;
use super::job_log::{self, JobLog};
use super::pipe::disk::State;
use smallvec::SmallVec;

/// Reads the standard output and error files of the current unit, writing them to the standard output/error.
macro_rules! read_outputs {
    ($stdout:ident, $stderr:ident, $buffer:ident, $stdout_out:ident, $stderr_out:ident) => {
        let mut bytes_read = $stdout.read(&mut $buffer).unwrap_or(0);
        while bytes_read != 0 {
            if let Err(why) = $stdout_out.write(&$buffer[0..bytes_read]) {
                let _ = write!($stderr_out, "parallel: I/O error: unable to write to standard output: {}\n", why);
            }
            bytes_read = $stdout.read(&mut $buffer).unwrap_or(0);
        }

        bytes_read = $stderr.read(&mut $buffer).unwrap_or(0);
        while bytes_read != 0 {
            if let Err(why) = $stderr_out.write(&$buffer[0..bytes_read]) {
                let _ = write!($stderr_out, "parallel: I/O error: unable to write to standard error: {}\n", why);
            }
            bytes_read = $stderr.read(&mut $buffer).unwrap_or(0);
        }
    }
}

/// Removes both the standard output and error file of the current job
macro_rules! remove_job_files {
    ($stdout_path:ident, $stderr_path:ident, $stderr:ident) => {{
        if let Err(why) = fs::remove_file(&$stdout_path).and_then(|_| fs::remove_file(&$stderr_path)) {
            let _ = write!($stderr, "parallel: I/O error: unable to remove job files: {}\n", why);
        }
    }}
}

/// Opens the standard output and error files of the next job, attempting repeatedly until a success.
macro_rules! open_job_files {
    ($stdout_path:ident, $stderr_path:ident) => {{
        let stdout_file = loop {
            if let Ok(file) = File::open(&$stdout_path) { break file }
            thread::sleep(Duration::from_millis(1));
        };

        let stderr_file = loop {
            if let Ok(file) = File::open(&$stderr_path) { break file }
            thread::sleep(Duration::from_millis(1));
        };

        (stdout_file, stderr_file)
    }}
}

/// Append the current job to the processed file
macro_rules! append_to_processed {
    ($processed:ident, $input:ident, $stderr:ident) => {{
        if let Err(why) = $processed.write($input.as_bytes()).and_then(|_| $processed.write(b"\n")) {
            let _ = write!($stderr, "parallel: I/O error: unable to append to processed: {}\n", why);
        }
    }}
}

#[allow(cyclomatic_complexity)]
/// Tail and print the standard output and error of each process in the correct order
pub fn receive_messages(input_rx: Receiver<State>, args: Args, processed_path: &Path, errors_path: &Path) {
    let stdout = io::stdout();
    let stderr = io::stderr();

    // Keeps track of which job is currently allowed to print to standard output/error.
    let mut counter = 0;
    // In the event that the joblog parameter was passed, a counter will be needed for jobs.
    let mut job_counter = args.ninputs;
    // The following `buffer` is used to store completed jobs that are awaiting processing.
    let mut buffer = SmallVec::<[State; 32]>::new();
    // Similar to the above, but for `JobLog` events.
    let mut job_buffer = SmallVec::<[JobLog; 32]>::new();
    // Store a list of indexes that we need to drop from `buffer` after a match has been found.
    let mut drop = SmallVec::<[usize; 32]>::new();
    // Similar to the above for for `JobLog` events.
    let mut job_drop = SmallVec::<[usize; 32]>::new();
    // An opened disk buffer pointing to the processed file.
    let processed_file = fs::OpenOptions::new().create(true).write(true).open(processed_path).unwrap();
    let mut processed_file = BufWriter::new(processed_file);
    // An opened disk buffer pointing to the error file.
    let error_file = fs::OpenOptions::new().create(true).write(true).open(errors_path).unwrap();
    let mut error_file = BufWriter::new(error_file);
    // Obtaining the number of digits in the total number of inputs is required for padding purposes.
    let mut id_pad_length = args.ninputs.digits();
    // A buffer for buffering the outputs of temporary files on disk.
    let mut read_buffer = [0u8; 8192];
    // A buffer for converting job ID's into a byte array representation of a string.
    let mut id_buffer = [0u8; 64];
    // Generates the stdout and stderr paths, along with a truncation value to truncate the job ID from the paths.
    let (truncate_size, mut stdout_path, mut stderr_path) = filepaths::new_job(counter);
    // If the joblog parameter was passed, open the file for writing.
    let mut joblog = match args.joblog {
        Some(path) => {
            job_counter = 0;
            if id_pad_length < 10 { id_pad_length = 10; }
            let _ = fs::remove_file(&path);
            let mut file = fs::OpenOptions::new().create(true).write(true).open(path).unwrap();
            job_log::create(&mut file, id_pad_length);
            file
        },
        /// This is OK because the `joblog` variable will never be used unless `joblog` was set.
        None => unsafe { mem::uninitialized::<File>() }
    };

    // The loop will only quit once all inputs have been processed
    while counter < args.ninputs || job_counter < args.ninputs {
        let mut tail_next = false;

        match input_rx.recv().unwrap() {
            State::Completed(id, ref name) if id == counter => {
                let mut stdout = stdout.lock();
                let mut stderr = stderr.lock();
                filepaths::next_job_path(counter, truncate_size, &mut id_buffer, &mut stdout_path, &mut stderr_path);
                let (mut stdout_file, mut stderr_file) = open_job_files!(stdout_path, stderr_path);
                append_to_processed!(processed_file, name, stderr);
                read_outputs!(stdout_file, stderr_file, read_buffer, stdout, stderr);
                remove_job_files!(stdout_path, stderr_path, stderr);
                counter += 1;
            },
            State::Completed(id, name) => {
                buffer.push(State::Completed(id, name));
                tail_next = true;
            },
            State::Error(id, ref message) if id == counter => {
                counter += 1;
                if let Err(why) = error_file.write(message.as_bytes()) {
                    let mut stderr = stderr.lock();
                    let _ = write!(stderr, "parallel: I/O error: {}", why);
                }
            },
            State::Error(id, message) => buffer.push(State::Error(id, message)),
            State::JobLog(ref data) if data.job_id == job_counter => {
                job_counter += 1;
                data.write_entry(&mut joblog, &mut id_buffer, id_pad_length);
            },
            State::JobLog(data) => job_buffer.push(data),
        }

        if tail_next {
            filepaths::next_job_path(counter, truncate_size, &mut id_buffer, &mut stdout_path, &mut stderr_path);
            let (mut stdout_file, mut stderr_file) = open_job_files!(stdout_path, stderr_path);

            loop {
                match input_rx.try_recv() {
                    Ok(State::Completed(id, ref name)) if id == counter => {
                        let mut stdout = stdout.lock();
                        let mut stderr = stderr.lock();
                        append_to_processed!(processed_file, name, stderr);
                        read_outputs!(stdout_file, stderr_file, read_buffer, stdout, stderr);
                        remove_job_files!(stdout_path, stderr_path, stderr);
                        counter += 1;
                        break
                    },
                    Ok(State::Completed(id, name)) => buffer.push(State::Completed(id, name)),
                    Ok(State::Error(id, ref message)) if id == counter => {
                        counter += 1;
                        if let Err(why) = error_file.write(message.as_bytes()) {
                            let mut stderr = stderr.lock();
                            let _ = write!(stderr, "parallel: I/O error: {}", why);
                        }
                    },
                    Ok(State::Error(id, message)) => buffer.push(State::Error(id, message)),
                    Ok(State::JobLog(ref data)) if data.job_id == job_counter => {
                        job_counter += 1;
                        data.write_entry(&mut joblog, &mut id_buffer, id_pad_length);
                    },
                    Ok(State::JobLog(data)) => job_buffer.push(data),
                    _ => {
                        let mut stdout = stdout.lock();
                        let mut stderr = stderr.lock();
                        let mut bytes_read = stdout_file.read(&mut read_buffer).unwrap();
                        if bytes_read != 0 { stdout.write(&read_buffer[0..bytes_read]).unwrap(); }

                        bytes_read = stderr_file.read(&mut read_buffer).unwrap();
                        if bytes_read != 0 { stderr.write(&read_buffer[0..bytes_read]).unwrap(); }
                        thread::sleep(Duration::from_millis(1));
                    }
                }
            }
        }

        let mut changed = true;
        while changed {
            changed = false;
            for (index, state) in buffer.iter().enumerate() {
                match *state {
                    State::Completed(id, ref name) if id == counter => {
                        let mut stdout = stdout.lock();
                        let mut stderr = stderr.lock();
                        filepaths::next_job_path(counter, truncate_size, &mut id_buffer, &mut stdout_path, &mut stderr_path);
                        let (mut stdout_file, mut stderr_file) = open_job_files!(stdout_path, stderr_path);
                        append_to_processed!(processed_file, name, stderr);
                        read_outputs!(stdout_file, stderr_file, read_buffer, stdout, stderr);
                        remove_job_files!(stdout_path, stderr_path, stderr);
                        counter += 1;
                        changed = true;
                        drop.push(index);
                    },
                    State::Error(id, ref message) if id == counter => {
                        counter += 1;
                        if let Err(why) = error_file.write(message.as_bytes()) {
                            let mut stderr = stderr.lock();
                            let _ = write!(stderr, "parallel: I/O error: {}", why);
                        }
                    },
                    _ => ()
                }
            }
        }

        changed = true;
        while changed {
            changed = false;
            for (index, log) in job_buffer.iter().enumerate() {
                if log.job_id == job_counter {
                    job_counter += 1;
                    job_drop.push(index);
                    changed = true;
                    log.write_entry(&mut joblog, &mut id_buffer, id_pad_length);
                }
            }
        }

        drop_used_states(&mut buffer, &mut drop);
        drop_used_logs(&mut job_buffer, &mut job_drop);
    }

    if let Err(why) = joblog.flush() {
        let mut stderr = stderr.lock();
        let _ = write!(stderr, "parallel: I/O error: {}", why);
    }

    if let Err(why) = processed_file.flush() {
        let mut stderr = stderr.lock();
        let _ = write!(stderr, "parallel: I/O error: {}", why);
    }

    if let Err(why) = error_file.flush() {
        let mut stderr = stderr.lock();
        let _ = write!(stderr, "parallel: I/O error: {}", why);
    }
}

fn drop_used_states(buffer: &mut SmallVec<[State; 32]>, drop: &mut SmallVec<[usize; 32]>) {
    drop.sort();
    for id in drop.drain().rev() {
        let _ = buffer.remove(id);
    }
}

fn drop_used_logs(buffer: &mut SmallVec<[JobLog; 32]>, drop: &mut SmallVec<[usize; 32]>) {
    drop.sort();
    for id in drop.drain().rev() {
        let _ = buffer.remove(id);
    }
}
<commit_msg>execute::receive: Eliminate Unsafe - Eliminates the need to create an uninitialized variable<commit_after>use std::fs::{self, File};
use std::io::{self, Write, Read, BufWriter};
use std::path::Path;
use std::sync::mpsc::Receiver;
use std::thread;
use std::time::Duration;
use arguments::Args;
use filepaths;
use misc::Digits;
use super::job_log::{self, JobLog};
use super::pipe::disk::State;
use smallvec::SmallVec;

/// Reads the standard output and error files of the current unit, writing them to the standard output/error.
macro_rules! read_outputs {
    ($stdout:ident, $stderr:ident, $buffer:ident, $stdout_out:ident, $stderr_out:ident) => {
        let mut bytes_read = $stdout.read(&mut $buffer).unwrap_or(0);
        while bytes_read != 0 {
            if let Err(why) = $stdout_out.write(&$buffer[0..bytes_read]) {
                let _ = write!($stderr_out, "parallel: I/O error: unable to write to standard output: {}\n", why);
            }
            bytes_read = $stdout.read(&mut $buffer).unwrap_or(0);
        }

        bytes_read = $stderr.read(&mut $buffer).unwrap_or(0);
        while bytes_read != 0 {
            if let Err(why) = $stderr_out.write(&$buffer[0..bytes_read]) {
                let _ = write!($stderr_out, "parallel: I/O error: unable to write to standard error: {}\n", why);
            }
            bytes_read = $stderr.read(&mut $buffer).unwrap_or(0);
        }
    }
}

/// Removes both the standard output and error file of the current job
macro_rules! remove_job_files {
    ($stdout_path:ident, $stderr_path:ident, $stderr:ident) => {{
        if let Err(why) = fs::remove_file(&$stdout_path).and_then(|_| fs::remove_file(&$stderr_path)) {
            let _ = write!($stderr, "parallel: I/O error: unable to remove job files: {}\n", why);
        }
    }}
}

/// Opens the standard output and error files of the next job, attempting repeatedly until a success.
macro_rules! open_job_files {
    ($stdout_path:ident, $stderr_path:ident) => {{
        let stdout_file = loop {
            if let Ok(file) = File::open(&$stdout_path) { break file }
            thread::sleep(Duration::from_millis(1));
        };

        let stderr_file = loop {
            if let Ok(file) = File::open(&$stderr_path) { break file }
            thread::sleep(Duration::from_millis(1));
        };

        (stdout_file, stderr_file)
    }}
}

/// Append the current job to the processed file
macro_rules! append_to_processed {
    ($processed:ident, $input:ident, $stderr:ident) => {{
        if let Err(why) = $processed.write($input.as_bytes()).and_then(|_| $processed.write(b"\n")) {
            let _ = write!($stderr, "parallel: I/O error: unable to append to processed: {}\n", why);
        }
    }}
}

#[allow(cyclomatic_complexity)]
/// Tail and print the standard output and error of each process in the correct order
pub fn receive_messages(input_rx: Receiver<State>, args: Args, processed_path: &Path, errors_path: &Path) {
    let stdout = io::stdout();
    let stderr = io::stderr();

    // Keeps track of which job is currently allowed to print to standard output/error.
    let mut counter = 0;
    // In the event that the joblog parameter was passed, a counter will be needed for jobs.
    let mut job_counter = args.ninputs;
    // The following `buffer` is used to store completed jobs that are awaiting processing.
    let mut buffer = SmallVec::<[State; 32]>::new();
    // Similar to the above, but for `JobLog` events.
    let mut job_buffer = SmallVec::<[JobLog; 32]>::new();
    // Store a list of indexes that we need to drop from `buffer` after a match has been found.
    let mut drop = SmallVec::<[usize; 32]>::new();
    // Similar to the above for for `JobLog` events.
    let mut job_drop = SmallVec::<[usize; 32]>::new();
    // An opened disk buffer pointing to the processed file.
    let processed_file = fs::OpenOptions::new().create(true).write(true).open(processed_path).unwrap();
    let mut processed_file = BufWriter::new(processed_file);
    // An opened disk buffer pointing to the error file.
    let error_file = fs::OpenOptions::new().create(true).write(true).open(errors_path).unwrap();
    let mut error_file = BufWriter::new(error_file);
    // Obtaining the number of digits in the total number of inputs is required for padding purposes.
    let mut id_pad_length = args.ninputs.digits();
    // A buffer for buffering the outputs of temporary files on disk.
    let mut read_buffer = [0u8; 8192];
    // A buffer for converting job ID's into a byte array representation of a string.
    let mut id_buffer = [0u8; 64];
    // Generates the stdout and stderr paths, along with a truncation value to truncate the job ID from the paths.
    let (truncate_size, mut stdout_path, mut stderr_path) = filepaths::new_job(counter);
    // If the joblog parameter was passed, open the file for writing.
    let mut joblog = args.joblog.map(|path| {
        job_counter = 0;
        if id_pad_length < 10 { id_pad_length = 10; }
        let _ = fs::remove_file(&path);
        let mut file = fs::OpenOptions::new().create(true).write(true).open(path).unwrap();
        job_log::create(&mut file, id_pad_length);
        file
    });

    // The loop will only quit once all inputs have been processed
    while counter < args.ninputs || job_counter < args.ninputs {
        let mut tail_next = false;

        match input_rx.recv().unwrap() {
            State::Completed(id, ref name) if id == counter => {
                let mut stdout = stdout.lock();
                let mut stderr = stderr.lock();
                filepaths::next_job_path(counter, truncate_size, &mut id_buffer, &mut stdout_path, &mut stderr_path);
                let (mut stdout_file, mut stderr_file) = open_job_files!(stdout_path, stderr_path);
                append_to_processed!(processed_file, name, stderr);
                read_outputs!(stdout_file, stderr_file, read_buffer, stdout, stderr);
                remove_job_files!(stdout_path, stderr_path, stderr);
                counter += 1;
            },
            State::Completed(id, name) => {
                buffer.push(State::Completed(id, name));
                tail_next = true;
            },
            State::Error(id, ref message) if id == counter => {
                counter += 1;
                if let Err(why) = error_file.write(message.as_bytes()) {
                    let mut stderr = stderr.lock();
                    let _ = write!(stderr, "parallel: I/O error: {}", why);
                }
            },
            State::Error(id, message) => buffer.push(State::Error(id, message)),
            State::JobLog(ref data) if data.job_id == job_counter => {
                job_counter += 1;
                let mut joblog = joblog.as_mut().unwrap();
                data.write_entry(&mut joblog, &mut id_buffer, id_pad_length);
            },
            State::JobLog(data) => job_buffer.push(data),
        }

        if tail_next {
            filepaths::next_job_path(counter, truncate_size, &mut id_buffer, &mut stdout_path, &mut stderr_path);
            let (mut stdout_file, mut stderr_file) = open_job_files!(stdout_path, stderr_path);

            loop {
                match input_rx.try_recv() {
                    Ok(State::Completed(id, ref name)) if id == counter => {
                        let mut stdout = stdout.lock();
                        let mut stderr = stderr.lock();
                        append_to_processed!(processed_file, name, stderr);
                        read_outputs!(stdout_file, stderr_file, read_buffer, stdout, stderr);
                        remove_job_files!(stdout_path, stderr_path, stderr);
                        counter += 1;
                        break
                    },
                    Ok(State::Completed(id, name)) => buffer.push(State::Completed(id, name)),
                    Ok(State::Error(id, ref message)) if id == counter => {
                        counter += 1;
                        if let Err(why) = error_file.write(message.as_bytes()) {
                            let mut stderr = stderr.lock();
                            let _ = write!(stderr, "parallel: I/O error: {}", why);
                        }
                    },
                    Ok(State::Error(id, message)) => buffer.push(State::Error(id, message)),
                    Ok(State::JobLog(ref data)) if data.job_id == job_counter => {
                        job_counter += 1;
                        let mut joblog = joblog.as_mut().unwrap();
                        data.write_entry(&mut joblog, &mut id_buffer, id_pad_length);
                    },
                    Ok(State::JobLog(data)) => job_buffer.push(data),
                    _ => {
                        let mut stdout = stdout.lock();
                        let mut stderr = stderr.lock();
                        let mut bytes_read = stdout_file.read(&mut read_buffer).unwrap();
                        if bytes_read != 0 { stdout.write(&read_buffer[0..bytes_read]).unwrap(); }

                        bytes_read = stderr_file.read(&mut read_buffer).unwrap();
                        if bytes_read != 0 { stderr.write(&read_buffer[0..bytes_read]).unwrap(); }
                        thread::sleep(Duration::from_millis(1));
                    }
                }
            }
        }

        let mut changed = true;
        while changed {
            changed = false;
            for (index, state) in buffer.iter().enumerate() {
                match *state {
                    State::Completed(id, ref name) if id == counter => {
                        let mut stdout = stdout.lock();
                        let mut stderr = stderr.lock();
                        filepaths::next_job_path(counter, truncate_size, &mut id_buffer, &mut stdout_path, &mut stderr_path);
                        let (mut stdout_file, mut stderr_file) = open_job_files!(stdout_path, stderr_path);
                        append_to_processed!(processed_file, name, stderr);
                        read_outputs!(stdout_file, stderr_file, read_buffer, stdout, stderr);
                        remove_job_files!(stdout_path, stderr_path, stderr);
                        counter += 1;
                        changed = true;
                        drop.push(index);
                    },
                    State::Error(id, ref message) if id == counter => {
                        counter += 1;
                        if let Err(why) = error_file.write(message.as_bytes()) {
                            let mut stderr = stderr.lock();
                            let _ = write!(stderr, "parallel: I/O error: {}", why);
                        }
                    },
                    _ => ()
                }
            }
        }

        if let Some(ref mut joblog) = joblog {
            changed = true;
            while changed {
                changed = false;
                for (index, log) in job_buffer.iter().enumerate() {
                    if log.job_id == job_counter {
                        job_counter += 1;
                        job_drop.push(index);
                        changed = true;
                        log.write_entry(joblog, &mut id_buffer, id_pad_length);
                    }
                }
            }
        }

        drop_used_states(&mut buffer, &mut drop);
        drop_used_logs(&mut job_buffer, &mut job_drop);
    }

    if let Some(mut joblog) = joblog {
        if let Err(why) = joblog.flush() {
            let mut stderr = stderr.lock();
            let _ = write!(stderr, "parallel: I/O error: {}", why);
        }
    }

    if let Err(why) = processed_file.flush() {
        let mut stderr = stderr.lock();
        let _ = write!(stderr, "parallel: I/O error: {}", why);
    }

    if let Err(why) = error_file.flush() {
        let mut stderr = stderr.lock();
        let _ = write!(stderr, "parallel: I/O error: {}", why);
    }
}

fn drop_used_states(buffer: &mut SmallVec<[State; 32]>, drop: &mut SmallVec<[usize; 32]>) {
    drop.sort();
    for id in drop.drain().rev() {
        let _ = buffer.remove(id);
    }
}

fn drop_used_logs(buffer: &mut SmallVec<[JobLog; 32]>, drop: &mut SmallVec<[usize; 32]>) {
    drop.sort();
    for id in drop.drain().rev() {
        let _ = buffer.remove(id);
    }
}
<|endoftext|>


<commit_before>//! Unimplemented.
<commit_msg>Finish R_ext/Linpack.h as ext/linpack<commit_after>// automatically generated by rust-bindgen

#[link(name = "R")]
extern {
    pub fn dpbfa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int)
                  -> ();
    pub fn dpbsl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double)
                  -> ();
    pub fn dpoco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int)
                  -> ();
    pub fn dpodi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_int)
                  -> ();
    pub fn dpofa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int)
                  -> ();
    pub fn dposl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double)
                  -> ();
    pub fn dqrdc_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_double,
                  arg8: *mut ::libc::c_int)
                  -> ();
    pub fn dqrsl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_double,
                  arg7: *mut ::libc::c_double,
                  arg8: *mut ::libc::c_double,
                  arg9: *mut ::libc::c_double,
                  arg10: *mut ::libc::c_double,
                  arg11: *mut ::libc::c_double,
                  arg12: *mut ::libc::c_int,
                  arg13: *mut ::libc::c_int)
                  -> ();
    pub fn dsvdc_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_double,
                  arg7: *mut ::libc::c_double,
                  arg8: *mut ::libc::c_int,
                  arg9: *mut ::libc::c_double,
                  arg10: *mut ::libc::c_int,
                  arg11: *mut ::libc::c_double,
                  arg12: *mut ::libc::c_int,
                  arg13: *mut ::libc::c_int)
                  -> ();
    pub fn dtrco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int)
                  -> ();
    pub fn dtrsl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_int)
                  -> ();
    pub fn dchdc_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_int)
                  -> ();
    pub fn dchdd_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_int,
                  arg8: *mut ::libc::c_double,
                  arg9: *mut ::libc::c_double,
                  arg10: *mut ::libc::c_double,
                  arg11: *mut ::libc::c_double,
                  arg12: *mut ::libc::c_int)
                  -> ();
    pub fn dchex_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_double,
                  arg7: *mut ::libc::c_int,
                  arg8: *mut ::libc::c_int,
                  arg9: *mut ::libc::c_double,
                  arg10: *mut ::libc::c_double,
                  arg11: *mut ::libc::c_int)
                  -> ();
    pub fn dchud_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_int,
                  arg8: *mut ::libc::c_double,
                  arg9: *mut ::libc::c_double,
                  arg10: *mut ::libc::c_double,
                  arg11: *mut ::libc::c_double)
                  -> ();
    pub fn dgbco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_double,
                  arg8: *mut ::libc::c_double)
                  -> ();
    pub fn dgbdi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_double)
                  -> ();
    pub fn dgbfa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_int)
                  -> ();
    pub fn dgbsl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_double,
                  arg8: *mut ::libc::c_int)
                  -> ();
    pub fn dgeco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_double)
                  -> ();
    pub fn dgedi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_double,
                  arg7: *mut ::libc::c_int)
                  -> ();
    pub fn dgefa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int)
                  -> ();
    pub fn dgesl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int)
                  -> ();
    pub fn dgtsl_(arg1: *mut ::libc::c_int,
                  arg2: *mut ::libc::c_double,
                  arg3: *mut ::libc::c_double,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int)
                  -> ();
    pub fn dpbco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_double,
                  arg7: *mut ::libc::c_int)
                  -> ();
    pub fn dpbdi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double)
                  -> ();
    pub fn dppco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_double,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_int)
                  -> ();
    pub fn dppdi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_double,
                  arg4: *mut ::libc::c_int)
                  -> ();
    pub fn dppfa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int)
                  -> ();
    pub fn dppsl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_double)
                  -> ();
    pub fn dptsl_(arg1: *mut ::libc::c_int,
                  arg2: *mut ::libc::c_double,
                  arg3: *mut ::libc::c_double,
                  arg4: *mut ::libc::c_double)
                  -> ();
    pub fn dsico_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_double)
                  -> ();
    pub fn dsidi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double,
                  arg6: *mut ::libc::c_int,
                  arg7: *mut ::libc::c_double,
                  arg8: *mut ::libc::c_int)
                  -> ();
    pub fn dsifa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_int)
                  -> ();
    pub fn dsisl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int,
                  arg5: *mut ::libc::c_double)
                  -> ();
    pub fn dspco_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_double)
                  -> ();
    pub fn dspdi_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double,
                  arg5: *mut ::libc::c_int,
                  arg6: *mut ::libc::c_double,
                  arg7: *mut ::libc::c_int)
                  -> ();
    pub fn dspfa_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_int)
                  -> ();
    pub fn dspsl_(arg1: *mut ::libc::c_double,
                  arg2: *mut ::libc::c_int,
                  arg3: *mut ::libc::c_int,
                  arg4: *mut ::libc::c_double)
                  -> ();
}
<|endoftext|>