<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

use nist384::big::NLEN;
use arch::Chunk;

// Base Bits= 60
// nist521 Modulus
pub const MODULUS:[Chunk;NLEN]=[0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0x1FFFFFFFFFF];
pub const R2MODP:[Chunk;NLEN]=[0x4000000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0];
pub const MCONST:Chunk=0x1;

// nist521 Curve
pub const CURVE_COF_I:isize = 1;
pub const CURVE_A:isize = -3;
pub const CURVE_B_I:isize = 0;
pub const CURVE_COF:[Chunk;NLEN]=[0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0];
pub const CURVE_B:[Chunk;NLEN]=[0xF451FD46B503F00,0x73DF883D2C34F1E,0x2C0BD3BB1BF0735,0x3951EC7E937B165,0x9918EF109E15619,0x5B99B315F3B8B48,0xB68540EEA2DA72,0x8E1C9A1F929A21A,0x51953EB961];
pub const CURVE_ORDER:[Chunk;NLEN]=[0xB6FB71E91386409,0xB5C9B8899C47AEB,0xC0148F709A5D03B,0x8783BF2F966B7FC,0xFFFFFFFFFFA5186,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0x1FFFFFFFFFF];
pub const CURVE_GX:[Chunk;NLEN]=[0x97E7E31C2E5BD66,0x48B3C1856A429BF,0xDC127A2FFA8DE33,0x5E77EFE75928FE1,0xF606B4D3DBAA14B,0x39053FB521F828A,0x62395B4429C6481,0x404E9CD9E3ECB6,0xC6858E06B7];
pub const CURVE_GY:[Chunk;NLEN]=[0x8BE94769FD16650,0x3C7086A272C2408,0xB9013FAD076135,0x72995EF42640C55,0xD17273E662C97EE,0x49579B446817AFB,0x42C7D1BD998F544,0x9A3BC0045C8A5FB,0x11839296A78];

<commit_msg>bug in rust rom file<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

use nist521::big::NLEN;
use arch::Chunk;

// Base Bits= 60
// nist521 Modulus
pub const MODULUS:[Chunk;NLEN]=[0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0x1FFFFFFFFFF];
pub const R2MODP:[Chunk;NLEN]=[0x4000000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0];
pub const MCONST:Chunk=0x1;

// nist521 Curve
pub const CURVE_COF_I:isize = 1;
pub const CURVE_A:isize = -3;
pub const CURVE_B_I:isize = 0;
pub const CURVE_COF:[Chunk;NLEN]=[0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0];
pub const CURVE_B:[Chunk;NLEN]=[0xF451FD46B503F00,0x73DF883D2C34F1E,0x2C0BD3BB1BF0735,0x3951EC7E937B165,0x9918EF109E15619,0x5B99B315F3B8B48,0xB68540EEA2DA72,0x8E1C9A1F929A21A,0x51953EB961];
pub const CURVE_ORDER:[Chunk;NLEN]=[0xB6FB71E91386409,0xB5C9B8899C47AEB,0xC0148F709A5D03B,0x8783BF2F966B7FC,0xFFFFFFFFFFA5186,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFF,0x1FFFFFFFFFF];
pub const CURVE_GX:[Chunk;NLEN]=[0x97E7E31C2E5BD66,0x48B3C1856A429BF,0xDC127A2FFA8DE33,0x5E77EFE75928FE1,0xF606B4D3DBAA14B,0x39053FB521F828A,0x62395B4429C6481,0x404E9CD9E3ECB6,0xC6858E06B7];
pub const CURVE_GY:[Chunk;NLEN]=[0x8BE94769FD16650,0x3C7086A272C2408,0xB9013FAD076135,0x72995EF42640C55,0xD17273E662C97EE,0x49579B446817AFB,0x42C7D1BD998F544,0x9A3BC0045C8A5FB,0x11839296A78];

<|endoftext|>


<commit_before>use std::{
    io::Write,
    net::{Ipv4Addr, SocketAddrV4, TcpListener, TcpStream},
};

use clap::Parser;
use dicom::{
    core::{DataElement, PrimitiveValue, VR},
    dicom_value,
    dictionary_std::tags,
    encoding::transfer_syntax::TransferSyntaxIndex,
    object::{FileMetaTableBuilder, InMemDicomObject, StandardDataDictionary},
};
use dicom::{
    transfer_syntax::TransferSyntaxRegistry,
    ul::{
        pdu::reader::read_pdu,
        pdu::{
            writer::write_pdu, PDataValueType, PresentationContextProposed,
            PresentationContextResult,
        },
    },
};
use tracing::{debug, error, info, Level};

/// DICOM C-STORE SCP
#[derive(Debug, Parser)]
struct App {
    /// verbose mode
    #[clap(short = 'v', long = "verbose")]
    verbose: bool,
    /// enforce max pdu length
    #[clap(short = 's', long = "strict")]
    strict: bool,
    /// max pdu length
    #[clap(short = 'm', long = "max-pdu-length", default_value = "16384")]
    max_pdu_length: u32,

    /// Which port to listen on
    #[clap(short, default_value = "11111")]
    port: u16,
}

fn run(
    scu_stream: &mut TcpStream,
    strict: bool,
    verbose: bool,
    max_pdu_length: u32,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut buffer: Vec<u8> = Vec::with_capacity(max_pdu_length as usize);
    let mut instance_buffer: Vec<u8> = Vec::with_capacity(1024 * 1024);
    let mut msgid = 1;
    let mut sop_class_uid = "".to_string();
    let mut sop_instance_uid = "".to_string();

    let mut presentation_context_results: Vec<PresentationContextResult> = vec![];

    loop {
        match read_pdu(scu_stream, max_pdu_length, strict) {
            Ok(mut pdu) => {
                if verbose {
                    debug!("scu ----> scp: {}", pdu.short_description());
                }
                match pdu {
                    dicom::ul::Pdu::AssociationRQ {
                        protocol_version,
                        calling_ae_title,
                        called_ae_title,
                        application_context_name,
                        presentation_contexts,
                        user_variables,
                    } => {
                        buffer.clear();
                        presentation_context_results = presentation_contexts
                            .iter()
                            .map(|pc| {
                                let PresentationContextProposed {
                                    id,
                                    abstract_syntax: _,
                                    transfer_syntaxes,
                                } = &pc;
                                PresentationContextResult {
                                    id: *id,
                                    reason:
                                        dicom::ul::pdu::PresentationContextResultReason::Acceptance,
                                    // accept the first proposed transfer syntax
                                    transfer_syntax: transfer_syntaxes[0].clone(),
                                }
                            })
                            .collect();

                        // copying most variables for now, should be set to application specific values
                        let response = dicom::ul::Pdu::AssociationAC {
                            protocol_version,
                            calling_ae_title,
                            called_ae_title,
                            application_context_name,
                            user_variables,
                            presentation_contexts: presentation_context_results.clone(),
                        };
                        write_pdu(&mut buffer, &response).unwrap();
                        if verbose {
                            debug!("scu <---- scp: {}", response.short_description());
                        }
                        scu_stream.write_all(&buffer).unwrap();
                    }
                    dicom::ul::Pdu::PData { ref mut data } => {
                        if data[0].value_type == PDataValueType::Data && !data[0].is_last {
                            instance_buffer.append(&mut data[0].data);
                        } else if data[0].value_type == PDataValueType::Command && data[0].is_last {
                            // commands are always in implict VR LE
                            let ts =
                                dicom::transfer_syntax::entries::IMPLICIT_VR_LITTLE_ENDIAN.erased();
                            let data_value = &data[0];
                            let v = &data_value.data;

                            let obj = InMemDicomObject::read_dataset_with_ts(v.as_slice(), &ts)?;
                            msgid = obj.element(tags::MESSAGE_ID)?.to_int()?;
                            sop_class_uid = obj
                                .element(tags::AFFECTED_SOP_CLASS_UID)?
                                .to_str()?
                                .to_string();
                            sop_instance_uid = obj
                                .element(tags::AFFECTED_SOP_INSTANCE_UID)?
                                .to_str()?
                                .to_string();
                            instance_buffer.clear();
                        } else if data[0].value_type == PDataValueType::Data && data[0].is_last {
                            instance_buffer.append(&mut data[0].data);

                            let presentation_context = presentation_context_results
                                .iter()
                                .filter(|pc| pc.id == data[0].presentation_context_id)
                                .next()
                                .unwrap();
                            let ts = &presentation_context.transfer_syntax;

                            let obj = InMemDicomObject::read_dataset_with_ts(
                                instance_buffer.as_slice(),
                                TransferSyntaxRegistry.get(ts).unwrap(),
                            )?;
                            let file_meta = FileMetaTableBuilder::new()
                                .media_storage_sop_class_uid(
                                    obj.element_by_name("SOPClassUID")?.to_str()?,
                                )
                                .media_storage_sop_instance_uid(
                                    obj.element_by_name("SOPInstanceUID")?.to_str()?,
                                )
                                .transfer_syntax(ts)
                                .build()?;
                            let file_obj = obj.with_exact_meta(file_meta);

                            // write the files to the current directory with their SOPInstanceUID as filenames
                            file_obj.write_to_file(sop_instance_uid.trim_end_matches('\0'))?;

                            // send C-STORE-RSP object
                            // commands are always in implict VR LE
                            let ts =
                                dicom::transfer_syntax::entries::IMPLICIT_VR_LITTLE_ENDIAN.erased();

                            let obj =
                                create_cstore_response(msgid, &sop_class_uid, &sop_instance_uid);

                            let mut obj_data = Vec::new();

                            obj.write_dataset_with_ts(&mut obj_data, &ts)?;

                            let pdu_response = dicom::ul::Pdu::PData {
                                data: vec![dicom::ul::pdu::PDataValue {
                                    presentation_context_id: data[0].presentation_context_id,
                                    value_type: PDataValueType::Command,
                                    is_last: true,
                                    data: obj_data,
                                }],
                            };
                            buffer.clear();
                            write_pdu(&mut buffer, &pdu_response).unwrap();
                            scu_stream.write_all(&buffer).unwrap();
                        }
                    }
                    dicom::ul::Pdu::ReleaseRQ => {
                        buffer.clear();
                        write_pdu(&mut buffer, &dicom::ul::Pdu::ReleaseRP).unwrap();
                        scu_stream.write_all(&buffer).unwrap();
                    }
                    _ => {}
                }
            }
            Err(dicom::ul::pdu::reader::Error::NoPduAvailable { .. }) => {
                break;
            }
            Err(_err) => {
                break;
            }
        }
    }
    Ok(())
}

fn create_cstore_response(
    message_id: u16,
    sop_class_uid: &str,
    sop_instance_uid: &str,
) -> InMemDicomObject<StandardDataDictionary> {
    let mut obj = InMemDicomObject::new_empty();

    // group length
    obj.put(DataElement::new(
        tags::COMMAND_GROUP_LENGTH,
        VR::UL,
        PrimitiveValue::from(
            8 + sop_class_uid.len() as i32
                + 8
                + 2
                + 8
                + 2
                + 8
                + 2
                + 8
                + 2
                + sop_instance_uid.len() as i32,
        ),
    ));

    // service
    obj.put(DataElement::new(
        tags::AFFECTED_SOP_CLASS_UID,
        VR::UI,
        dicom_value!(Str, sop_class_uid),
    ));
    // command
    obj.put(DataElement::new(
        tags::COMMAND_FIELD,
        VR::US,
        dicom_value!(U16, [0x8001]),
    ));
    // message ID being responded to
    obj.put(DataElement::new(
        tags::MESSAGE_ID_BEING_RESPONDED_TO,
        VR::US,
        dicom_value!(U16, [message_id]),
    ));
    // data set type
    obj.put(DataElement::new(
        tags::COMMAND_DATA_SET_TYPE,
        VR::US,
        dicom_value!(U16, [0x0101]),
    ));
    // status https://dicom.nema.org/dicom/2013/output/chtml/part07/chapter_C.html
    obj.put(DataElement::new(
        tags::STATUS,
        VR::US,
        dicom_value!(U16, [0x0000]),
    ));
    // SOPInstanceUID
    obj.put(DataElement::new(
        tags::AFFECTED_SOP_INSTANCE_UID,
        VR::UI,
        dicom_value!(Str, sop_instance_uid),
    ));

    obj
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let App {
        verbose,
        strict,
        port,
        max_pdu_length,
    } = App::from_args();

    tracing::subscriber::set_global_default(
        tracing_subscriber::FmtSubscriber::builder()
            .with_max_level(if verbose { Level::DEBUG } else { Level::INFO })
            .finish(),
    )
    .unwrap_or_else(|e| {
        eprintln!("Could not set up global logger: {}", e);
    });

    let listen_addr = SocketAddrV4::new(Ipv4Addr::from(0), port);
    let listener = TcpListener::bind(&listen_addr).unwrap();
    if verbose {
        info!("listening on: tcp://0.0.0.0:{}", listen_addr);
    }

    for mut stream in listener.incoming() {
        match stream {
            Ok(ref mut scu_stream) => {
                if let Err(e) = run(scu_stream, strict, verbose, max_pdu_length) {
                    error!("[ERROR] {}", e);
                }
            }
            Err(e) => {
                error!("[ERROR] {}", e);
            }
        }
    }

    Ok(())
}
<commit_msg>[storescp] Add output directory option<commit_after>use std::{
    io::Write,
    net::{Ipv4Addr, SocketAddrV4, TcpListener, TcpStream}, path::PathBuf,
};

use clap::Parser;
use dicom::{
    core::{DataElement, PrimitiveValue, VR},
    dicom_value,
    dictionary_std::tags,
    encoding::transfer_syntax::TransferSyntaxIndex,
    object::{FileMetaTableBuilder, InMemDicomObject, StandardDataDictionary},
};
use dicom::{
    transfer_syntax::TransferSyntaxRegistry,
    ul::{
        pdu::reader::read_pdu,
        pdu::{
            writer::write_pdu, PDataValueType, PresentationContextProposed,
            PresentationContextResult,
        },
    },
};
use tracing::{debug, error, info, Level};

/// DICOM C-STORE SCP
#[derive(Debug, Parser)]
struct App {
    /// verbose mode
    #[clap(short = 'v', long = "verbose")]
    verbose: bool,
    /// enforce max pdu length
    #[clap(short = 's', long = "strict")]
    strict: bool,
    /// max pdu length
    #[clap(short = 'm', long = "max-pdu-length", default_value = "16384")]
    max_pdu_length: u32,
    /// output directory for incoming objects
    #[clap(short = 'o', default_value = ".")]
    out_dir: PathBuf,
    /// Which port to listen on
    #[clap(short, default_value = "11111")]
    port: u16,
}

fn run(
    scu_stream: &mut TcpStream,
    out_dir: PathBuf,
    strict: bool,
    verbose: bool,
    max_pdu_length: u32,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut buffer: Vec<u8> = Vec::with_capacity(max_pdu_length as usize);
    let mut instance_buffer: Vec<u8> = Vec::with_capacity(1024 * 1024);
    let mut msgid = 1;
    let mut sop_class_uid = "".to_string();
    let mut sop_instance_uid = "".to_string();

    let mut presentation_context_results: Vec<PresentationContextResult> = vec![];

    loop {
        match read_pdu(scu_stream, max_pdu_length, strict) {
            Ok(mut pdu) => {
                if verbose {
                    debug!("scu ----> scp: {}", pdu.short_description());
                }
                match pdu {
                    dicom::ul::Pdu::AssociationRQ {
                        protocol_version,
                        calling_ae_title,
                        called_ae_title,
                        application_context_name,
                        presentation_contexts,
                        user_variables,
                    } => {
                        buffer.clear();
                        presentation_context_results = presentation_contexts
                            .iter()
                            .map(|pc| {
                                let PresentationContextProposed {
                                    id,
                                    abstract_syntax: _,
                                    transfer_syntaxes,
                                } = &pc;
                                PresentationContextResult {
                                    id: *id,
                                    reason:
                                        dicom::ul::pdu::PresentationContextResultReason::Acceptance,
                                    // accept the first proposed transfer syntax
                                    transfer_syntax: transfer_syntaxes[0].clone(),
                                }
                            })
                            .collect();

                        // copying most variables for now, should be set to application specific values
                        let response = dicom::ul::Pdu::AssociationAC {
                            protocol_version,
                            calling_ae_title,
                            called_ae_title,
                            application_context_name,
                            user_variables,
                            presentation_contexts: presentation_context_results.clone(),
                        };
                        write_pdu(&mut buffer, &response).unwrap();
                        if verbose {
                            debug!("scu <---- scp: {}", response.short_description());
                        }
                        scu_stream.write_all(&buffer).unwrap();
                    }
                    dicom::ul::Pdu::PData { ref mut data } => {
                        if data[0].value_type == PDataValueType::Data && !data[0].is_last {
                            instance_buffer.append(&mut data[0].data);
                        } else if data[0].value_type == PDataValueType::Command && data[0].is_last {
                            // commands are always in implict VR LE
                            let ts =
                                dicom::transfer_syntax::entries::IMPLICIT_VR_LITTLE_ENDIAN.erased();
                            let data_value = &data[0];
                            let v = &data_value.data;

                            let obj = InMemDicomObject::read_dataset_with_ts(v.as_slice(), &ts)?;
                            msgid = obj.element(tags::MESSAGE_ID)?.to_int()?;
                            sop_class_uid = obj
                                .element(tags::AFFECTED_SOP_CLASS_UID)?
                                .to_str()?
                                .to_string();
                            sop_instance_uid = obj
                                .element(tags::AFFECTED_SOP_INSTANCE_UID)?
                                .to_str()?
                                .to_string();
                            instance_buffer.clear();
                        } else if data[0].value_type == PDataValueType::Data && data[0].is_last {
                            instance_buffer.append(&mut data[0].data);

                            let presentation_context = presentation_context_results
                                .iter()
                                .filter(|pc| pc.id == data[0].presentation_context_id)
                                .next()
                                .unwrap();
                            let ts = &presentation_context.transfer_syntax;

                            let obj = InMemDicomObject::read_dataset_with_ts(
                                instance_buffer.as_slice(),
                                TransferSyntaxRegistry.get(ts).unwrap(),
                            )?;
                            let file_meta = FileMetaTableBuilder::new()
                                .media_storage_sop_class_uid(
                                    obj.element_by_name("SOPClassUID")?.to_str()?,
                                )
                                .media_storage_sop_instance_uid(
                                    obj.element_by_name("SOPInstanceUID")?.to_str()?,
                                )
                                .transfer_syntax(ts)
                                .build()?;
                            let file_obj = obj.with_exact_meta(file_meta);

                            // write the files to the current directory with their SOPInstanceUID as filenames
                            let mut file_path = out_dir.clone();
                            file_path.push(sop_instance_uid.trim_end_matches('\0'));
                            file_obj.write_to_file(file_path)?;

                            // send C-STORE-RSP object
                            // commands are always in implict VR LE
                            let ts =
                                dicom::transfer_syntax::entries::IMPLICIT_VR_LITTLE_ENDIAN.erased();

                            let obj =
                                create_cstore_response(msgid, &sop_class_uid, &sop_instance_uid);

                            let mut obj_data = Vec::new();

                            obj.write_dataset_with_ts(&mut obj_data, &ts)?;

                            let pdu_response = dicom::ul::Pdu::PData {
                                data: vec![dicom::ul::pdu::PDataValue {
                                    presentation_context_id: data[0].presentation_context_id,
                                    value_type: PDataValueType::Command,
                                    is_last: true,
                                    data: obj_data,
                                }],
                            };
                            buffer.clear();
                            write_pdu(&mut buffer, &pdu_response).unwrap();
                            scu_stream.write_all(&buffer).unwrap();
                        }
                    }
                    dicom::ul::Pdu::ReleaseRQ => {
                        buffer.clear();
                        write_pdu(&mut buffer, &dicom::ul::Pdu::ReleaseRP).unwrap();
                        scu_stream.write_all(&buffer).unwrap();
                    }
                    _ => {}
                }
            }
            Err(dicom::ul::pdu::reader::Error::NoPduAvailable { .. }) => {
                break;
            }
            Err(_err) => {
                break;
            }
        }
    }
    Ok(())
}

fn create_cstore_response(
    message_id: u16,
    sop_class_uid: &str,
    sop_instance_uid: &str,
) -> InMemDicomObject<StandardDataDictionary> {
    let mut obj = InMemDicomObject::new_empty();

    // group length
    obj.put(DataElement::new(
        tags::COMMAND_GROUP_LENGTH,
        VR::UL,
        PrimitiveValue::from(
            8 + sop_class_uid.len() as i32
                + 8
                + 2
                + 8
                + 2
                + 8
                + 2
                + 8
                + 2
                + sop_instance_uid.len() as i32,
        ),
    ));

    // service
    obj.put(DataElement::new(
        tags::AFFECTED_SOP_CLASS_UID,
        VR::UI,
        dicom_value!(Str, sop_class_uid),
    ));
    // command
    obj.put(DataElement::new(
        tags::COMMAND_FIELD,
        VR::US,
        dicom_value!(U16, [0x8001]),
    ));
    // message ID being responded to
    obj.put(DataElement::new(
        tags::MESSAGE_ID_BEING_RESPONDED_TO,
        VR::US,
        dicom_value!(U16, [message_id]),
    ));
    // data set type
    obj.put(DataElement::new(
        tags::COMMAND_DATA_SET_TYPE,
        VR::US,
        dicom_value!(U16, [0x0101]),
    ));
    // status https://dicom.nema.org/dicom/2013/output/chtml/part07/chapter_C.html
    obj.put(DataElement::new(
        tags::STATUS,
        VR::US,
        dicom_value!(U16, [0x0000]),
    ));
    // SOPInstanceUID
    obj.put(DataElement::new(
        tags::AFFECTED_SOP_INSTANCE_UID,
        VR::UI,
        dicom_value!(Str, sop_instance_uid),
    ));

    obj
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let App {
        verbose,
        strict,
        port,
        max_pdu_length,
        out_dir,
    } = App::from_args();

    tracing::subscriber::set_global_default(
        tracing_subscriber::FmtSubscriber::builder()
            .with_max_level(if verbose { Level::DEBUG } else { Level::INFO })
            .finish(),
    )
    .unwrap_or_else(|e| {
        eprintln!("Could not set up global logger: {}", e);
    });

    std::fs::create_dir_all(&out_dir).unwrap_or_else(|e| {
        error!("Could not create output directory: {}", e);
        std::process::exit(-2);
    });

    let listen_addr = SocketAddrV4::new(Ipv4Addr::from(0), port);
    let listener = TcpListener::bind(&listen_addr).unwrap();
    if verbose {
        info!("listening on: tcp://{}", listen_addr);
    }

    for mut stream in listener.incoming() {
        match stream {
            Ok(ref mut scu_stream) => {
                if let Err(e) = run(scu_stream, out_dir.clone(), strict, verbose, max_pdu_length) {
                    error!("[ERROR] {}", e);
                }
            }
            Err(e) => {
                error!("[ERROR] {}", e);
            }
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate csv;
extern crate chrono;

use std::collections::{HashMap, VecDeque};
use std::path::Path;
use config::Config;
use feed::Feed;
use util::lerp;
use self::chrono::prelude::{Utc, Timelike};

const MOVING_AVG_SIZE: usize = 5;

error_chain! {}

#[derive(Debug)]
pub struct Average {
    pub current: f32,
    pub last:    f32,
    moving:      VecDeque<f32>,
}

impl Average {
    pub fn new(average: f32) -> Average {
        let mut moving = VecDeque::with_capacity(MOVING_AVG_SIZE + 1);

        if average > 0. {
            moving.push_back(average);
        }

        Average {
            current: average,
            last:    average,
            moving:  moving,
        }
    }

    fn update(&mut self, value: f32) {
        self.moving.push_back(value);

        if self.moving.len() > MOVING_AVG_SIZE {
            self.moving.pop_front();
        }

        self.last    = self.current;
        self.current = self.moving.iter().sum::<f32>() / self.moving.len() as f32;
    }
}

#[derive(Debug)]
pub struct ListenerData {
    pub average:      Average,
    pub unskewed_avg: Option<f32>,
    pub hourly:       [f32; 24],
    spike_count:      u8,
}

impl ListenerData {
    pub fn new(listeners: f32, hourly: [f32; 24]) -> ListenerData {
        ListenerData {
            average:      Average::new(listeners),
            unskewed_avg: None,
            hourly:       hourly,
            spike_count:  0,
        }
    }

    pub fn step(&mut self, config: &Config, hour: usize, feed: &Feed) -> bool {
        let has_spiked = self.has_spiked(&config, &feed);

        self.spike_count = if has_spiked {
            self.spike_count + 1
        } else {
            0
        };

        let listeners = feed.listeners as f32;
        self.average.update(listeners);
        self.update_unskewed(&config, listeners, has_spiked);

        self.hourly[hour] = match self.unskewed_avg {
            Some(unskewed) => unskewed,
            None           => self.average.current,
        };

        has_spiked
    }

    fn update_unskewed(&mut self, config: &Config, listeners: f32, has_spiked: bool) {
        match self.unskewed_avg {
            Some(unskewed) => {
                // Remove the unskewed average when the current average is close
                if self.average.current - unskewed < unskewed * config.unskewed_avg.reset_pcnt {
                    self.unskewed_avg = None;
                } else {
                    // Slowly adjust the unskewed average to adjust to any natural listener increases
                    let new_val = lerp(unskewed,
                                        self.average.current,
                                        config.unskewed_avg.adjust_pcnt);

                    self.unskewed_avg = Some(new_val);
                }
            },
            None if has_spiked && self.average.last > 0. => {
                let has_spiked_enough = self.spike_count > config.unskewed_avg.spikes_required;

                // The main purpose of this is to "capture" feeds on the first update cycle
                // that are hundreds if not thousands of listeners above normal
                let has_jumped_enough =
                    listeners - self.average.current >
                    self.average.last * config.unskewed_avg.jump_required;

                if has_spiked_enough || has_jumped_enough {
                    self.unskewed_avg = Some(self.average.last);
                }
            },
            None => (),
        }
    }

    pub fn has_spiked(&self, config: &Config, feed: &Feed) -> bool {
        if self.average.current == 0. {
            return false
        }

        let spike = config.get_current_spike(&feed);
        let listeners = feed.listeners as f32;

        // If a feed has a low number of listeners, make the threshold higher to
        // make the calculation less sensitive to very small listener jumps
        let threshold = if listeners < 50. {
            spike.jump + (50. - listeners) * spike.low_listener_increase
        } else {
            // Otherwise, decrease the threshold by a factor of how fast the feed's listeners are rising
            // to make it easier for the feed to show up in an update
            let pcnt     = spike.high_listener_dec;
            let per_pcnt = spike.high_listener_dec_every;

            spike.jump - (self.get_average_delta(listeners) / per_pcnt * pcnt).min(spike.jump - 0.01)
        };

        if cfg!(feature = "show-feed-info") {
            print!(" THR: {}", threshold);
        }

        listeners - self.average.current >= listeners * threshold
    }

    pub fn get_average_delta(&self, listeners: f32) -> f32 {
        let sub = match self.unskewed_avg {
            Some(unskewed) => unskewed,
            None => self.average.current,
        };

        listeners - sub
    }
}

pub type AverageMap = HashMap<u32, ListenerData>;

pub fn load_averages(path: &Path) -> Result<AverageMap> {
    let reader = csv::ReaderBuilder::new()
        .has_headers(false)
        .from_path(path)
        .chain_err(|| "failed to open listener average file")?;

    let mut avgs = HashMap::new();
    let hour = Utc::now().hour() as usize;

    for record in reader.into_deserialize() {
        let (id, avg): (_, [_; 24]) = record
            .chain_err(|| "failed to decode listener average")?;

        avgs.insert(id, ListenerData::new(avg[hour], avg));
    }

    Ok(avgs)
}

pub fn save_averages(path: &Path, averages: &AverageMap) -> Result<()> {
    let mut writer = csv::Writer::from_path(path)
        .chain_err(|| "failed to open listener average file")?;

    for (id, data) in averages {
        let mut record = Vec::with_capacity(data.hourly.len() + 1);

        record.push(id.to_string());

        for hour_data in data.hourly.iter() {
            record.push(hour_data.to_string());
        }

        writer.write_record(&record)
            .chain_err(|| "failed to encode listener average")?;
    }

    Ok(())
}<commit_msg>Move MOVING_AVG_SIZE const to Average struct for clarity<commit_after>extern crate csv;
extern crate chrono;

use std::collections::{HashMap, VecDeque};
use std::path::Path;
use config::Config;
use feed::Feed;
use util::lerp;
use self::chrono::prelude::{Utc, Timelike};

error_chain! {}

#[derive(Debug)]
pub struct Average {
    pub current: f32,
    pub last:    f32,
    moving:      VecDeque<f32>,
}

impl Average {
    pub const MOVING_SIZE: usize = 5;

    pub fn new(average: f32) -> Average {
        let mut moving = VecDeque::with_capacity(Average::MOVING_SIZE + 1);

        if average > 0. {
            moving.push_back(average);
        }

        Average {
            current: average,
            last:    average,
            moving:  moving,
        }
    }

    fn update(&mut self, value: f32) {
        self.moving.push_back(value);

        if self.moving.len() > Average::MOVING_SIZE {
            self.moving.pop_front();
        }

        self.last    = self.current;
        self.current = self.moving.iter().sum::<f32>() / self.moving.len() as f32;
    }
}

#[derive(Debug)]
pub struct ListenerData {
    pub average:      Average,
    pub unskewed_avg: Option<f32>,
    pub hourly:       [f32; 24],
    spike_count:      u8,
}

impl ListenerData {
    pub fn new(listeners: f32, hourly: [f32; 24]) -> ListenerData {
        ListenerData {
            average:      Average::new(listeners),
            unskewed_avg: None,
            hourly:       hourly,
            spike_count:  0,
        }
    }

    pub fn step(&mut self, config: &Config, hour: usize, feed: &Feed) -> bool {
        let has_spiked = self.has_spiked(&config, &feed);

        self.spike_count = if has_spiked {
            self.spike_count + 1
        } else {
            0
        };

        let listeners = feed.listeners as f32;
        self.average.update(listeners);
        self.update_unskewed(&config, listeners, has_spiked);

        self.hourly[hour] = match self.unskewed_avg {
            Some(unskewed) => unskewed,
            None           => self.average.current,
        };

        has_spiked
    }

    fn update_unskewed(&mut self, config: &Config, listeners: f32, has_spiked: bool) {
        match self.unskewed_avg {
            Some(unskewed) => {
                // Remove the unskewed average when the current average is close
                if self.average.current - unskewed < unskewed * config.unskewed_avg.reset_pcnt {
                    self.unskewed_avg = None;
                } else {
                    // Slowly adjust the unskewed average to adjust to any natural listener increases
                    let new_val = lerp(unskewed,
                                        self.average.current,
                                        config.unskewed_avg.adjust_pcnt);

                    self.unskewed_avg = Some(new_val);
                }
            },
            None if has_spiked && self.average.last > 0. => {
                let has_spiked_enough = self.spike_count > config.unskewed_avg.spikes_required;

                // The main purpose of this is to "capture" feeds on the first update cycle
                // that are hundreds if not thousands of listeners above normal
                let has_jumped_enough =
                    listeners - self.average.current >
                    self.average.last * config.unskewed_avg.jump_required;

                if has_spiked_enough || has_jumped_enough {
                    self.unskewed_avg = Some(self.average.last);
                }
            },
            None => (),
        }
    }

    pub fn has_spiked(&self, config: &Config, feed: &Feed) -> bool {
        if self.average.current == 0. {
            return false
        }

        let spike = config.get_current_spike(&feed);
        let listeners = feed.listeners as f32;

        // If a feed has a low number of listeners, make the threshold higher to
        // make the calculation less sensitive to very small listener jumps
        let threshold = if listeners < 50. {
            spike.jump + (50. - listeners) * spike.low_listener_increase
        } else {
            // Otherwise, decrease the threshold by a factor of how fast the feed's listeners are rising
            // to make it easier for the feed to show up in an update
            let pcnt     = spike.high_listener_dec;
            let per_pcnt = spike.high_listener_dec_every;

            spike.jump - (self.get_average_delta(listeners) / per_pcnt * pcnt).min(spike.jump - 0.01)
        };

        if cfg!(feature = "show-feed-info") {
            print!(" THR: {}", threshold);
        }

        listeners - self.average.current >= listeners * threshold
    }

    pub fn get_average_delta(&self, listeners: f32) -> f32 {
        let sub = match self.unskewed_avg {
            Some(unskewed) => unskewed,
            None => self.average.current,
        };

        listeners - sub
    }
}

pub type AverageMap = HashMap<u32, ListenerData>;

pub fn load_averages(path: &Path) -> Result<AverageMap> {
    let reader = csv::ReaderBuilder::new()
        .has_headers(false)
        .from_path(path)
        .chain_err(|| "failed to open listener average file")?;

    let mut avgs = HashMap::new();
    let hour = Utc::now().hour() as usize;

    for record in reader.into_deserialize() {
        let (id, avg): (_, [_; 24]) = record
            .chain_err(|| "failed to decode listener average")?;

        avgs.insert(id, ListenerData::new(avg[hour], avg));
    }

    Ok(avgs)
}

pub fn save_averages(path: &Path, averages: &AverageMap) -> Result<()> {
    let mut writer = csv::Writer::from_path(path)
        .chain_err(|| "failed to open listener average file")?;

    for (id, data) in averages {
        let mut record = Vec::with_capacity(data.hourly.len() + 1);

        record.push(id.to_string());

        for hour_data in data.hourly.iter() {
            record.push(hour_data.to_string());
        }

        writer.write_record(&record)
            .chain_err(|| "failed to encode listener average")?;
    }

    Ok(())
}<|endoftext|>


<commit_before>// Copyright(C) 2016 Chris Liebert
extern crate rusqlite;
extern crate time;

use self::rusqlite::Connection;

use std::path::Path;

use common::{ImageBlob, Material, Mesh, SceneNode, Scene, Shader, Vertex8f32};

fn create_vertex8f32(px: f64,
                     py: f64,
                     pz: f64,
                     nx: f64,
                     ny: f64,
                     nz: f64,
                     tu: f64,
                     tv: f64)
                     -> Vertex8f32 {
    let position: [f32; 3] = [px as f32, py as f32, pz as f32];
    let normal: [f32; 3] = [nx as f32, ny as f32, nz as f32];
    let texcoord: [f32; 2] = [tu as f32, tv as f32];
    Vertex8f32 {
        position: position,
        normal: normal,
        texcoord: texcoord,
    }
}

pub fn load_db(filename: &str) -> Scene {
    println!("Loading {}", filename);

    let path: &Path = Path::new(filename);
    let conn = Connection::open(path).unwrap();

    // Load vertices
    let mut vertex_stmt = conn.prepare("SELECT px, py, pz, nx, ny, nz, tu, tv FROM vertex")
        .unwrap();
    let vertex_iter = vertex_stmt.query_map(&[], |row| {
            create_vertex8f32(row.get(0),
                              row.get(1),
                              row.get(2),
                              row.get(3),
                              row.get(4),
                              row.get(5),
                              row.get(6),
                              row.get(7))
        })
        .unwrap();

    let mut vertices: Vec<Vertex8f32> = Vec::new();

    for vertex in vertex_iter {
        vertices.push(vertex.unwrap());
    }

    // Load materials
    let mut material_stmt =
        conn.prepare("SELECT name, diffuse_r, diffuse_g, diffuse_b, diffuse_texname FROM material")
            .unwrap();
    let material_iter = material_stmt.query_map(&[], |row| {
            let diffuse_r: f64 = row.get(1);
            let diffuse_g: f64 = row.get(2);
            let diffuse_b: f64 = row.get(3);
            Material {
                name: row.get(0),
                diffuse: [diffuse_r as f32, diffuse_g as f32, diffuse_b as f32],
                diffuse_texname: row.get(4),
            }
        })
        .unwrap();

    let mut materials: Vec<Material> = Vec::new();

    for material in material_iter {
        materials.push(material.unwrap());
    }

    let mut meshes: Vec<Mesh> = Vec::new();

    // Load scene nodes
    let mut scene_node_stmt =
        conn.prepare("SELECT name, material_id, start_position, end_position FROM scene_node")
            .unwrap();
    let scene_node_iter = scene_node_stmt.query_map(&[], |row| {
            let material_id: i32 = row.get(1);
            let material_index: usize = material_id as usize - 1 as usize;
            SceneNode {
                name: row.get(0),
                material_index: material_index, // index starts at 1 in database, not 0
                start_position: row.get(2),
                end_position: row.get(3),
            }
        })
        .unwrap();

    for scene_node in scene_node_iter {
        let sn = scene_node.unwrap();
        let mut new_vertices: Vec<Vertex8f32> = Vec::new();

        for i in sn.start_position as usize..(sn.end_position) as usize {
            new_vertices.push(vertices[i]);

        }

        if sn.material_index >= materials.len() {
            panic!("Material index {} out of bounds", sn.material_index);
        }

        let mesh = Mesh {
            name: sn.name,
            material_index: sn.material_index,
            vertices: new_vertices,
        };
        meshes.push(mesh);
    }

    println!("Loaded {} vertices in {} meshes",
             vertices.len(),
             meshes.len());

    // Free up some memory
    vertices.clear();

    // Load textures
    let mut texture_stmt = conn.prepare("SELECT name, image FROM texture")
        .unwrap();
    let texture_iter = texture_stmt.query_map(&[], |row| {
            ImageBlob {
                name: row.get(0),
                image: row.get(1),
            }
        })
        .unwrap();

    let mut textures: Vec<ImageBlob> = Vec::new();

    for texture in texture_iter {
        textures.push(texture.unwrap());
    }

    // Load shaders
    let mut shader_stmt =
        conn.prepare("SELECT name, vertex_source_140, fragment_source_140 FROM shader")
            .unwrap();
    let shader_iter = shader_stmt.query_map(&[], |row| {
            Shader {
                name: row.get(0),
                vertex_source_140: row.get(1),
                fragment_source_140: row.get(2),
            }
        })
        .unwrap();

    let mut shaders: Vec<Shader> = Vec::new();

    for shader in shader_iter {
        shaders.push(shader.unwrap());
    }

    return Scene {
        materials: materials,
        // scene_nodes: scene_nodes,
        // vertices: vertices,
        meshes: meshes,
        shaders: shaders,
        images: textures,
    };
}
<commit_msg>changed loader interface to have shaders queried separately from scene data.<commit_after>// Copyright(C) 2016 Chris Liebert
extern crate rusqlite;
extern crate time;

use self::rusqlite::Connection;

use std::path::Path;

use common::{ImageBlob, Material, Mesh, SceneNode, Scene, Shader, Vertex8f32};

pub struct DBLoader {
    filename: String,
}

fn create_vertex8f32(px: f64,
                     py: f64,
                     pz: f64,
                     nx: f64,
                     ny: f64,
                     nz: f64,
                     tu: f64,
                     tv: f64)
                     -> Vertex8f32 {
    let position: [f32; 3] = [px as f32, py as f32, pz as f32];
    let normal: [f32; 3] = [nx as f32, ny as f32, nz as f32];
    let texcoord: [f32; 2] = [tu as f32, tv as f32];
    Vertex8f32 {
        position: position,
        normal: normal,
        texcoord: texcoord,
    }
}

impl DBLoader {
    pub fn new(filename: &str) -> DBLoader {
        DBLoader { filename: String::from(filename) }
    }

    pub fn load_scene(&self) -> Scene {
        let conn = Connection::open(Path::new(&self.filename)).unwrap();

        // Load vertices
        let mut vertex_stmt = conn.prepare("SELECT px, py, pz, nx, ny, nz, tu, tv FROM vertex")
            .unwrap();
        let vertex_iter = vertex_stmt.query_map(&[], |row| {
                create_vertex8f32(row.get(0),
                                  row.get(1),
                                  row.get(2),
                                  row.get(3),
                                  row.get(4),
                                  row.get(5),
                                  row.get(6),
                                  row.get(7))
            })
            .unwrap();

        let mut vertices: Vec<Vertex8f32> = Vec::new();

        for vertex in vertex_iter {
            vertices.push(vertex.unwrap());
        }

        // Load materials
        let mut material_stmt =
            conn.prepare("SELECT name, diffuse_r, diffuse_g, diffuse_b, diffuse_texname FROM \
                          material")
                .unwrap();
        let material_iter = material_stmt.query_map(&[], |row| {
                let diffuse_r: f64 = row.get(1);
                let diffuse_g: f64 = row.get(2);
                let diffuse_b: f64 = row.get(3);
                Material {
                    name: row.get(0),
                    diffuse: [diffuse_r as f32, diffuse_g as f32, diffuse_b as f32],
                    diffuse_texname: row.get(4),
                }
            })
            .unwrap();

        let mut materials: Vec<Material> = Vec::new();

        for material in material_iter {
            materials.push(material.unwrap());
        }

        let mut meshes: Vec<Mesh> = Vec::new();

        // Load scene nodes
        let mut scene_node_stmt =
            conn.prepare("SELECT name, material_id, start_position, end_position FROM scene_node")
                .unwrap();
        let scene_node_iter = scene_node_stmt.query_map(&[], |row| {
                let material_id: i32 = row.get(1);
                let material_index: usize = material_id as usize - 1 as usize;
                SceneNode {
                    name: row.get(0),
                    material_index: material_index, // index starts at 1 in database, not 0
                    start_position: row.get(2),
                    end_position: row.get(3),
                }
            })
            .unwrap();

        for scene_node in scene_node_iter {
            let sn = scene_node.unwrap();
            let mut new_vertices: Vec<Vertex8f32> = Vec::new();

            for i in sn.start_position as usize..(sn.end_position) as usize {
                new_vertices.push(vertices[i]);

            }

            if sn.material_index >= materials.len() {
                panic!("Material index {} out of bounds", sn.material_index);
            }

            let mesh = Mesh {
                name: sn.name,
                material_index: sn.material_index,
                vertices: new_vertices,
            };
            meshes.push(mesh);
        }

        println!("Loaded {} vertices in {} meshes",
                 vertices.len(),
                 meshes.len());

        // Free up some memory
        vertices.clear();

        // Load textures
        let mut texture_stmt = conn.prepare("SELECT name, image FROM texture")
            .unwrap();
        let texture_iter = texture_stmt.query_map(&[], |row| {
                ImageBlob {
                    name: row.get(0),
                    image: row.get(1),
                }
            })
            .unwrap();

        let mut textures: Vec<ImageBlob> = Vec::new();

        for texture in texture_iter {
            textures.push(texture.unwrap());
        }

        // conn.close();
        return Scene {
            materials: materials,
            // scene_nodes: scene_nodes,
            // vertices: vertices,
            meshes: meshes,
            // shaders: shaders,
            images: textures,
        };
    }

    pub fn load_shader(&self, name: &str, glsl_version_string: &str) -> Shader {
        let conn = Connection::open(Path::new(&self.filename)).unwrap();
        let use_gles = false; // Use OpenGLES instead of OpenGL (for mobile devices)
        let glsl_version = 110;

        // Load the first shader in the database by default
        // TODO: load from config settings table?
        let shader_index = 0;

        let mut shader_id: i32 = conn.query_row("SELECT id FROM shader WHERE name = 'default'", //
                       &[],
                       |row| row.get(0))
            .unwrap();

        println!("Default shader id={}", shader_id);

        let mut vertex_source: String =
            conn.query_row("SELECT source FROM shader_version WHERE shader_id=1 AND version = \
                            110 AND type = 'vertex'", //
                           &[],
                           |row| row.get(0))
                .unwrap();

        let mut fragment_source: String =
            conn.query_row("SELECT source FROM shader_version WHERE shader_id=1 AND version = \
                            110 AND type = 'fragment'",
                           &[],
                           |row| row.get(0))
                .unwrap();

        Shader {
            name: String::from(name),
            vertex_source: vertex_source,
            fragment_source: fragment_source,
        }
    }
}
<|endoftext|>


<commit_before>use log::{set_logger, Log, LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};
use std::io::{Write, stderr};
use time::now;

pub struct Logger {
  max_level: LogLevel
}

impl Logger {
  pub fn new(max_level: LogLevel) -> Self {
    Logger {
      max_level: max_level
    }
  }

  pub fn init(self) -> Result<(), SetLoggerError> {
    set_logger(|max_log_level| {
      max_log_level.set(LogLevelFilter::Debug);
      Box::new(self)
    })
  }
}

impl Log for Logger {
  fn enabled(&self, metadata: &LogMetadata) -> bool {
    metadata.level() <= self.max_level
  }

  fn log(&self, record: &LogRecord) {
    if self.enabled(record.metadata()) {
      let time_now = now();
      let time = time_now.strftime("%H:%M:%S").unwrap();
      writeln!(stderr(), "[{}] {} – {}", time, record.level(), record.args()).unwrap();
    }
  }
}
<commit_msg>fix: filter out rustls log lines<commit_after>use log::{set_logger, Log, LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};
use std::io::{Write, stderr};
use time::now;

pub struct Logger {
  max_level: LogLevel
}

impl Logger {
  pub fn new(max_level: LogLevel) -> Self {
    Logger {
      max_level: max_level
    }
  }

  pub fn init(self) -> Result<(), SetLoggerError> {
    set_logger(|max_log_level| {
      max_log_level.set(LogLevelFilter::Debug);
      Box::new(self)
    })
  }
}

impl Log for Logger {
  fn enabled(&self, metadata: &LogMetadata) -> bool {
    metadata.level() <= self.max_level
  }

  fn log(&self, record: &LogRecord) {
    if self.enabled(record.metadata()) && !record.target().contains("rustls") {
      let time_now = now();
      let time = time_now.strftime("%H:%M:%S").unwrap();
      writeln!(stderr(), "[{}] {} – {}", time, record.level(), record.args()).unwrap();
    }
  }
}
<|endoftext|>


<commit_before>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.
/// The standard logging macro.
///
/// This macro will generically log with the specified `LogLevel` and `format!`
/// based argument list.
///
/// The `max_level_*` features can be used to statically disable logging at
/// various levels.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// use log::LogLevel;
///
/// # fn main() {
/// let data = (42, "Forty-two");
/// let private_data = "private";
///
/// log!(LogLevel::Error, "Received errors: {}, {}", data.0, data.1);
/// log!(target: "app_events", LogLevel::Warn, "App warning: {}, {}, {}",
///     data.0, data.1, private_data);
/// # }
/// ```
#[macro_export]
macro_rules! log {
    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
        static _LOC: $crate::LogLocation = $crate::LogLocation {
            __line: line!(),
            __file: file!(),
            __module_path: module_path!(),
        };
        let lvl = $lvl;
        if lvl <= $crate::__static_max_level() && lvl <= $crate::max_log_level() {
            $crate::__log(lvl, $target, &_LOC, format_args!($($arg)+))
        }
    });
    ($lvl:expr, $($arg:tt)+) => (log!(target: module_path!(), $lvl, $($arg)+))
}

/// Logs a message at the error level.
///
/// Logging at this level is disabled if the `max_level_off` feature is present.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// let (err_info, port) = ("No connection", 22);
///
/// error!("Error: {} on port {}", err_info, port);
/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22);
/// # }
/// ```
#[macro_export]
macro_rules! error {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Error, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Error, $($arg)*);
    )
}

/// Logs a message at the warn level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off` or `max_level_error`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off` or `max_level_error`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// let warn_description = "Invalid Input";
///
/// warn!("Warning! {}!", warn_description);
/// warn!(target: "input_events", "App received warning: {}", warn_description);
/// # }
/// ```
#[macro_export]
macro_rules! warn {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Warn, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Warn, $($arg)*);
    )
}

/// Logs a message at the info level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off`, `max_level_error`, or `max_level_warn`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off`, `release_max_level_error`, or
/// `release_max_level_warn`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// # struct Connection { port: u32, speed: f32 }
/// let conn_info = Connection { port: 40, speed: 3.20 };
///
/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed);
/// info!(target: "connection_events", "Successfull connection, port: {}, speed: {}",
///       conn_info.port, conn_info.speed);
/// # }
/// ```
#[macro_export]
macro_rules! info {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Info, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Info, $($arg)*);
    )
}

/// Logs a message at the debug level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off`, `max_level_error`, `max_level_warn`, or
/// `max_level_info`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off`, `release_max_level_error`,
/// `release_max_level_warn`, or `release_max_level_info`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// # struct Position { x: f32, y: f32 }
/// let pos = Position { x: 3.234, y: -1.223 };
///
/// debug!("New position: x: {}, y: {}", pos.x, pos.y);
/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y);
/// # }
/// ```
#[macro_export]
macro_rules! debug {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Debug, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Debug, $($arg)*);
    )
}

/// Logs a message at the trace level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off`, `max_level_error`, `max_level_warn`,
/// `max_level_info`, or `max_level_debug`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off`, `release_max_level_error`,
/// `release_max_level_warn`, `release_max_level_info`, or
/// `release_max_level_debug`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// # struct Position { x: f32, y: f32 }
/// let pos = Position { x: 3.234, y: -1.223 };
///
/// trace!("Position is: x: {}, y: {}", pos.x, pos.y);
/// trace!(target: "app_events", "x is {} and y is {}",
///        if pos.x >= 0.0 { "positive" } else { "negative" },
///        if pos.y >= 0.0 { "positive" } else { "negative" });
/// # }
/// ```
#[macro_export]
macro_rules! trace {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Trace, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Trace, $($arg)*);
    )
}

/// Determines if a message logged at the specified level in that module will
/// be logged.
///
/// This can be used to avoid expensive computation of log message arguments if
/// the message would be ignored anyway.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// use log::LogLevel::Debug;
///
/// # fn foo() {
/// if log_enabled!(Debug) {
///     let data = expensive_call();
///     debug!("expensive debug data: {} {}", data.x, data.y);
/// }
/// # }
/// # struct Data { x: u32, y: u32 }
/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } }
/// # fn main() {}
/// ```
#[macro_export]
macro_rules! log_enabled {
    (target: $target:expr, $lvl:expr) => ({
        let lvl = $lvl;
        lvl <= $crate::__static_max_level() && lvl <= $crate::max_log_level() &&
            $crate::__enabled(lvl, $target)
    });
    ($lvl:expr) => (log_enabled!(target: module_path!(), $lvl))
}
<commit_msg>extended example to use both patterns for log_enabled!<commit_after>// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.
/// The standard logging macro.
///
/// This macro will generically log with the specified `LogLevel` and `format!`
/// based argument list.
///
/// The `max_level_*` features can be used to statically disable logging at
/// various levels.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// use log::LogLevel;
///
/// # fn main() {
/// let data = (42, "Forty-two");
/// let private_data = "private";
///
/// log!(LogLevel::Error, "Received errors: {}, {}", data.0, data.1);
/// log!(target: "app_events", LogLevel::Warn, "App warning: {}, {}, {}",
///     data.0, data.1, private_data);
/// # }
/// ```
#[macro_export]
macro_rules! log {
    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
        static _LOC: $crate::LogLocation = $crate::LogLocation {
            __line: line!(),
            __file: file!(),
            __module_path: module_path!(),
        };
        let lvl = $lvl;
        if lvl <= $crate::__static_max_level() && lvl <= $crate::max_log_level() {
            $crate::__log(lvl, $target, &_LOC, format_args!($($arg)+))
        }
    });
    ($lvl:expr, $($arg:tt)+) => (log!(target: module_path!(), $lvl, $($arg)+))
}

/// Logs a message at the error level.
///
/// Logging at this level is disabled if the `max_level_off` feature is present.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// let (err_info, port) = ("No connection", 22);
///
/// error!("Error: {} on port {}", err_info, port);
/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22);
/// # }
/// ```
#[macro_export]
macro_rules! error {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Error, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Error, $($arg)*);
    )
}

/// Logs a message at the warn level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off` or `max_level_error`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off` or `max_level_error`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// let warn_description = "Invalid Input";
///
/// warn!("Warning! {}!", warn_description);
/// warn!(target: "input_events", "App received warning: {}", warn_description);
/// # }
/// ```
#[macro_export]
macro_rules! warn {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Warn, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Warn, $($arg)*);
    )
}

/// Logs a message at the info level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off`, `max_level_error`, or `max_level_warn`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off`, `release_max_level_error`, or
/// `release_max_level_warn`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// # struct Connection { port: u32, speed: f32 }
/// let conn_info = Connection { port: 40, speed: 3.20 };
///
/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed);
/// info!(target: "connection_events", "Successfull connection, port: {}, speed: {}",
///       conn_info.port, conn_info.speed);
/// # }
/// ```
#[macro_export]
macro_rules! info {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Info, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Info, $($arg)*);
    )
}

/// Logs a message at the debug level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off`, `max_level_error`, `max_level_warn`, or
/// `max_level_info`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off`, `release_max_level_error`,
/// `release_max_level_warn`, or `release_max_level_info`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// # struct Position { x: f32, y: f32 }
/// let pos = Position { x: 3.234, y: -1.223 };
///
/// debug!("New position: x: {}, y: {}", pos.x, pos.y);
/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y);
/// # }
/// ```
#[macro_export]
macro_rules! debug {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Debug, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Debug, $($arg)*);
    )
}

/// Logs a message at the trace level.
///
/// Logging at this level is disabled if any of the following features are
/// present: `max_level_off`, `max_level_error`, `max_level_warn`,
/// `max_level_info`, or `max_level_debug`.
///
/// When building in release mode (i.e., without the `debug_assertions` option),
/// logging at this level is also disabled if any of the following features are
/// present: `release_max_level_off`, `release_max_level_error`,
/// `release_max_level_warn`, `release_max_level_info`, or
/// `release_max_level_debug`.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// # fn main() {
/// # struct Position { x: f32, y: f32 }
/// let pos = Position { x: 3.234, y: -1.223 };
///
/// trace!("Position is: x: {}, y: {}", pos.x, pos.y);
/// trace!(target: "app_events", "x is {} and y is {}",
///        if pos.x >= 0.0 { "positive" } else { "negative" },
///        if pos.y >= 0.0 { "positive" } else { "negative" });
/// # }
/// ```
#[macro_export]
macro_rules! trace {
    (target: $target:expr, $($arg:tt)*) => (
        log!(target: $target, $crate::LogLevel::Trace, $($arg)*);
    );
    ($($arg:tt)*) => (
        log!($crate::LogLevel::Trace, $($arg)*);
    )
}

/// Determines if a message logged at the specified level in that module will
/// be logged.
///
/// This can be used to avoid expensive computation of log message arguments if
/// the message would be ignored anyway.
///
/// # Examples
///
/// ```rust
/// # #[macro_use]
/// # extern crate log;
/// use log::LogLevel::Debug;
///
/// # fn foo() {
/// if log_enabled!(Debug) {
///     let data = expensive_call();
///     debug!("expensive debug data: {} {}", data.x, data.y);
/// }
/// if log_enabled!(target: "Global", Debug) {
///    let data = expensive_call();
///    debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y);
/// }
/// # }
/// # struct Data { x: u32, y: u32 }
/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } }
/// # fn main() {}
/// ```
#[macro_export]
macro_rules! log_enabled {
    (target: $target:expr, $lvl:expr) => ({
        let lvl = $lvl;
        lvl <= $crate::__static_max_level() && lvl <= $crate::max_log_level() &&
            $crate::__enabled(lvl, $target)
    });
    ($lvl:expr) => (log_enabled!(target: module_path!(), $lvl))
}
<|endoftext|>


<commit_before>// Bitcoin secp256k1 bindings
// Written in 2014 by
//   Dawid Ciężarkiewicz
//   Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

// This is a macro that routinely comes in handy
macro_rules! impl_array_newtype {
    ($thing:ident, $ty:ty, $len:expr) => {
        impl Copy for $thing {}

        impl $thing {
            #[inline]
            /// Converts the object to a raw pointer for FFI interfacing
            pub fn as_ptr(&self) -> *const $ty {
                let &$thing(ref dat) = self;
                dat.as_ptr()
            }

            #[inline]
            /// Converts the object to a mutable raw pointer for FFI interfacing
            pub fn as_mut_ptr(&mut self) -> *mut $ty {
                let &mut $thing(ref mut dat) = self;
                dat.as_mut_ptr()
            }

            #[inline]
            /// Returns the length of the object as an array
            pub fn len(&self) -> usize { $len }

            #[inline]
            /// Returns whether the object as an array is empty
            pub fn is_empty(&self) -> bool { false }
        }

        impl PartialEq for $thing {
            #[inline]
            fn eq(&self, other: &$thing) -> bool {
                &self[..] == &other[..]
            }
        }

        impl Eq for $thing {}

        impl PartialOrd for $thing {
            #[inline]
            fn partial_cmp(&self, other: &$thing) -> Option<::core::cmp::Ordering> {
                self[..].partial_cmp(&other[..])
            }
        }

        impl Ord for $thing {
            #[inline]
            fn cmp(&self, other: &$thing) -> ::core::cmp::Ordering {
                self[..].cmp(&other[..])
            }
        }

        impl Clone for $thing {
            #[inline]
            fn clone(&self) -> $thing {
                let &$thing(ref dat) = self;
                $thing(dat.clone())
            }
        }

        impl ::core::ops::Index<usize> for $thing {
            type Output = $ty;

            #[inline]
            fn index(&self, index: usize) -> &$ty {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::Range<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::core::ops::Range<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::RangeTo<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::core::ops::RangeTo<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::RangeFrom<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::RangeFull> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, _: ::core::ops::RangeFull) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[..]
            }
        }
        impl ::ffi::CPtr for $thing {
            type Target = $ty;
            fn as_c_ptr(&self) -> *const Self::Target {
                if self.is_empty() {
                    ::core::ptr::null()
                } else {
                    self.as_ptr()
                }
            }

            fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
                if self.is_empty() {
                    ::core::ptr::null::<Self::Target>() as *mut _
                } else {
                    self.as_mut_ptr()
                }
            }
        }
    }
}

macro_rules! impl_pretty_debug {
    ($thing:ident) => {
        impl ::core::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                try!(write!(f, "{}(", stringify!($thing)));
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                write!(f, ")")
            }
        }
     }
}

macro_rules! impl_raw_debug {
    ($thing:ident) => {
        impl ::core::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                Ok(())
            }
        }
     }
}

#[cfg(feature="serde")]
/// Implements `Serialize` and `Deserialize` for a type `$t` which represents
/// a newtype over a byte-slice over length `$len`. Type `$t` must implement
/// the `FromStr` and `Display` trait.
macro_rules! serde_impl(
    ($t:ident, $len:expr) => (
        impl ::serde::Serialize for $t {
            fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
                if s.is_human_readable() {
                    s.collect_str(self)
                } else {
                    s.serialize_bytes(&self[..])
                }
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $t {
            fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<$t, D::Error> {
                use ::serde::de::Error;
                use core::str::FromStr;

                if d.is_human_readable() {
                    let sl: &str = ::serde::Deserialize::deserialize(d)?;
                    SecretKey::from_str(sl).map_err(D::Error::custom)
                } else {
                    let sl: &[u8] = ::serde::Deserialize::deserialize(d)?;
                    if sl.len() != $len {
                        Err(D::Error::invalid_length(sl.len(), &stringify!($len)))
                    } else {
                        let mut ret = [0; $len];
                        ret.copy_from_slice(sl);
                        Ok($t(ret))
                    }
                }
            }
        }
    )
);

#[cfg(not(feature="serde"))]
macro_rules! serde_impl(
    ($t:ident, $len:expr) => ()
);
<commit_msg>Remove trailing whitespace<commit_after>// Bitcoin secp256k1 bindings
// Written in 2014 by
//   Dawid Ciężarkiewicz
//   Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

// This is a macro that routinely comes in handy
macro_rules! impl_array_newtype {
    ($thing:ident, $ty:ty, $len:expr) => {
        impl Copy for $thing {}

        impl $thing {
            #[inline]
            /// Converts the object to a raw pointer for FFI interfacing
            pub fn as_ptr(&self) -> *const $ty {
                let &$thing(ref dat) = self;
                dat.as_ptr()
            }

            #[inline]
            /// Converts the object to a mutable raw pointer for FFI interfacing
            pub fn as_mut_ptr(&mut self) -> *mut $ty {
                let &mut $thing(ref mut dat) = self;
                dat.as_mut_ptr()
            }

            #[inline]
            /// Returns the length of the object as an array
            pub fn len(&self) -> usize { $len }

            #[inline]
            /// Returns whether the object as an array is empty
            pub fn is_empty(&self) -> bool { false }
        }

        impl PartialEq for $thing {
            #[inline]
            fn eq(&self, other: &$thing) -> bool {
                &self[..] == &other[..]
            }
        }

        impl Eq for $thing {}

        impl PartialOrd for $thing {
            #[inline]
            fn partial_cmp(&self, other: &$thing) -> Option<::core::cmp::Ordering> {
                self[..].partial_cmp(&other[..])
            }
        }

        impl Ord for $thing {
            #[inline]
            fn cmp(&self, other: &$thing) -> ::core::cmp::Ordering {
                self[..].cmp(&other[..])
            }
        }

        impl Clone for $thing {
            #[inline]
            fn clone(&self) -> $thing {
                let &$thing(ref dat) = self;
                $thing(dat.clone())
            }
        }

        impl ::core::ops::Index<usize> for $thing {
            type Output = $ty;

            #[inline]
            fn index(&self, index: usize) -> &$ty {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::Range<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::core::ops::Range<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::RangeTo<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::core::ops::RangeTo<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::RangeFrom<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::core::ops::RangeFrom<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::core::ops::Index<::core::ops::RangeFull> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, _: ::core::ops::RangeFull) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[..]
            }
        }
        impl ::ffi::CPtr for $thing {
            type Target = $ty;
            fn as_c_ptr(&self) -> *const Self::Target {
                if self.is_empty() {
                    ::core::ptr::null()
                } else {
                    self.as_ptr()
                }
            }

            fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
                if self.is_empty() {
                    ::core::ptr::null::<Self::Target>() as *mut _
                } else {
                    self.as_mut_ptr()
                }
            }
        }
    }
}

macro_rules! impl_pretty_debug {
    ($thing:ident) => {
        impl ::core::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                try!(write!(f, "{}(", stringify!($thing)));
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                write!(f, ")")
            }
        }
     }
}

macro_rules! impl_raw_debug {
    ($thing:ident) => {
        impl ::core::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                Ok(())
            }
        }
     }
}

#[cfg(feature="serde")]
/// Implements `Serialize` and `Deserialize` for a type `$t` which represents
/// a newtype over a byte-slice over length `$len`. Type `$t` must implement
/// the `FromStr` and `Display` trait.
macro_rules! serde_impl(
    ($t:ident, $len:expr) => (
        impl ::serde::Serialize for $t {
            fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
                if s.is_human_readable() {
                    s.collect_str(self)
                } else {
                    s.serialize_bytes(&self[..])
                }
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $t {
            fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<$t, D::Error> {
                use ::serde::de::Error;
                use core::str::FromStr;

                if d.is_human_readable() {
                    let sl: &str = ::serde::Deserialize::deserialize(d)?;
                    SecretKey::from_str(sl).map_err(D::Error::custom)
                } else {
                    let sl: &[u8] = ::serde::Deserialize::deserialize(d)?;
                    if sl.len() != $len {
                        Err(D::Error::invalid_length(sl.len(), &stringify!($len)))
                    } else {
                        let mut ret = [0; $len];
                        ret.copy_from_slice(sl);
                        Ok($t(ret))
                    }
                }
            }
        }
    )
);

#[cfg(not(feature="serde"))]
macro_rules! serde_impl(
    ($t:ident, $len:expr) => ()
);
<|endoftext|>


<commit_before>use std::fmt::Show;
/// Defines all the traits which a matrix element must support
pub trait MatElt : Num+Copy+Show {

}

/// Indicate that i64 fits all requirements for being a matrix element.
impl MatElt for i64 {

}

/// Indicate that f64 fits all requirements for being a matrix element.
impl MatElt for f64 {

}

/// Indicate that u8 fits all requirements for being a matrix element.
impl MatElt for u8 {

}

<commit_msg>Added more types for which matrices can be constructed.<commit_after>// Imports
use std::fmt::Show;

/// Defines all the traits which a matrix element must support
pub trait MatElt : Num+Copy+Show {

}

/// Indicate that i8 fits all requirements for being a matrix element.
impl MatElt for i8 {

}
/// Indicate that i16 fits all requirements for being a matrix element.
impl MatElt for i16 {

}
/// Indicate that i32 fits all requirements for being a matrix element.
impl MatElt for i32 {

}
/// Indicate that i64 fits all requirements for being a matrix element.
impl MatElt for i64 {

}

/// Indicate that u8 fits all requirements for being a matrix element.
impl MatElt for u8 {

}
/// Indicate that u16 fits all requirements for being a matrix element.
impl MatElt for u16 {

}
/// Indicate that u32 fits all requirements for being a matrix element.
impl MatElt for u32 {

}

/// Indicate that u64 fits all requirements for being a matrix element.
impl MatElt for u64 {

}

/// Indicate that f32 fits all requirements for being a matrix element.
impl MatElt for f32 {

}

/// Indicate that f64 fits all requirements for being a matrix element.
impl MatElt for f64 {

}
<|endoftext|>


<commit_before>use std::{
    fmt::Debug,
    os::unix::prelude::AsRawFd,
    sync::{Arc, Mutex},
};

use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::zwp_virtual_keyboard_v1::{
    self, ZwpVirtualKeyboardV1,
};
use wayland_server::{
    backend::{ClientId, ObjectId},
    protocol::wl_keyboard::{KeyState, KeymapFormat},
    Client, DataInit, Dispatch, DisplayHandle,
};
use xkbcommon::xkb;

use crate::{
    input::{Seat, SeatHandler},
    utils::SERIAL_COUNTER,
    wayland::seat::{keyboard::for_each_focused_kbds, WaylandFocus},
};

use super::VirtualKeyboardManagerState;

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
struct SerializedMods {
    depressed: u32,
    latched: u32,
    locked: u32,
    group: u32,
}

#[derive(Debug, Default)]
pub(crate) struct VirtualKeyboard {
    instances: u8,
    modifiers: Option<SerializedMods>,
    old_keymap: Option<String>,
}

/// Handle to a virtual keyboard instance
#[derive(Debug, Clone, Default)]
pub(crate) struct VirtualKeyboardHandle {
    pub(crate) inner: Arc<Mutex<VirtualKeyboard>>,
}

impl VirtualKeyboardHandle {
    pub(super) fn count_instance(&self) {
        let mut inner = self.inner.lock().unwrap();
        inner.instances += 1;
    }
}

/// User data of ZwpVirtualKeyboardV1 object
pub struct VirtualKeyboardUserData<D: SeatHandler> {
    pub(super) handle: VirtualKeyboardHandle,
    pub(crate) seat: Seat<D>,
}

impl<D: SeatHandler> Debug for VirtualKeyboardUserData<D>
where
    <D as SeatHandler>::KeyboardFocus: Debug,
    <D as SeatHandler>::PointerFocus: Debug,
{
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("VirtualKeyboardUserData")
            .field("handle", &self.handle)
            .field("seat", &self.seat.arc)
            .finish()
    }
}

impl<D> Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>, D> for VirtualKeyboardManagerState
where
    D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
    D: SeatHandler + 'static,
    <D as SeatHandler>::KeyboardFocus: WaylandFocus,
{
    fn request(
        _data: &mut D,
        _client: &Client,
        _: &ZwpVirtualKeyboardV1,
        request: zwp_virtual_keyboard_v1::Request,
        data: &VirtualKeyboardUserData<D>,
        _dh: &DisplayHandle,
        _data_init: &mut DataInit<'_, D>,
    ) {
        match request {
            zwp_virtual_keyboard_v1::Request::Keymap { format, fd, size } => {
                // This should be wl_keyboard::KeymapFormat::XkbV1,
                // but the protocol does not state the parameter is an enum.
                if format == 1 {
                    let keyboard_handle = data.seat.get_keyboard().unwrap();
                    let internal = keyboard_handle
                        .arc
                        .internal
                        .lock()
                        .unwrap();
                    let old_keymap = internal
                        .keymap
                        .get_as_string(xkb::FORMAT_TEXT_V1);
                    let new_keymap = unsafe {
                        xkb::Keymap::new_from_fd(
                            &xkb::Context::new(xkb::CONTEXT_NO_FLAGS),
                            fd.as_raw_fd(),
                            size as usize,
                            format,
                            xkb::KEYMAP_COMPILE_NO_FLAGS,
                        )
                        .unwrap()
                        .unwrap()
                    };
                    if old_keymap != new_keymap.get_as_string(xkb::FORMAT_TEXT_V1) {
                        let mut inner = data.handle.inner.lock().unwrap();
                        inner.old_keymap= Some(old_keymap);
                        keyboard_handle.change_keymap(new_keymap);
                        let known_kbds = &keyboard_handle.arc.known_kbds;
                        for kbd in &*known_kbds.lock().unwrap() {
                            kbd.keymap(KeymapFormat::XkbV1, fd.as_raw_fd(), size);
                        }
                    }
                }
            }
            zwp_virtual_keyboard_v1::Request::Key { time, key, state } => {
                let keyboard_handle = data.seat.get_keyboard().unwrap();
                let internal = keyboard_handle.arc.internal.lock().unwrap();
                let inner = data.handle.inner.lock().unwrap();
                if let Some(focus) = internal.focus.as_ref().and_then(|f| f.0.wl_surface()) {
                    for_each_focused_kbds(&data.seat, focus, |kbd| {
                        // This should be wl_keyboard::KeyState,
                        // but the protocol does not state the parameter is an enum.
                        let key_state = if state == 1 {
                            KeyState::Pressed
                        } else {
                            KeyState::Released
                        };
                        kbd.key(SERIAL_COUNTER.next_serial().0, time, key, key_state);
                        if let Some(mods) = inner.modifiers {
                            kbd.modifiers(
                                SERIAL_COUNTER.next_serial().0,
                                mods.depressed,
                                mods.latched,
                                mods.locked,
                                mods.group,
                            );
                        }
                    });
                }
            }
            zwp_virtual_keyboard_v1::Request::Modifiers {
                mods_depressed,
                mods_latched,
                mods_locked,
                group,
            } => {
                data.handle.inner.lock().unwrap().modifiers = Some(SerializedMods {
                    depressed: mods_depressed,
                    latched: mods_latched,
                    locked: mods_locked,
                    group,
                });
            }
            zwp_virtual_keyboard_v1::Request::Destroy => {
                // Nothing to do
            }
            _ => unreachable!(),
        }
    }

    fn destroyed(
        _state: &mut D,
        _client: ClientId,
        _virtual_keyboard: ObjectId,
        data: &VirtualKeyboardUserData<D>,
    ) {
        let mut inner = data.handle.inner.lock().unwrap();
        inner.instances -= 1;
        if inner.instances == 0 {
            if let Some(old_keymap) = &inner.old_keymap {
                let keyboard_handle = data.seat.get_keyboard().unwrap();
                let old_keymap = xkb::Keymap::new_from_string(
                    &xkb::Context::new(xkb::CONTEXT_NO_FLAGS),
                    old_keymap.to_string(),
                    xkb::KEYMAP_FORMAT_TEXT_V1,
                    xkb::KEYMAP_COMPILE_NO_FLAGS,
                )
                .unwrap();
                keyboard_handle.change_keymap(old_keymap);
                let keymap_file = keyboard_handle.arc.keymap.lock().unwrap();
                keymap_file.with_fd(false, |fd, size| {
                    let known_kbds = &keyboard_handle.arc.known_kbds;
                    for kbd in &*known_kbds.lock().unwrap() {
                        kbd.keymap(KeymapFormat::XkbV1, fd.as_raw_fd(), size as u32);
                    }
                }).ok(); //TODO: log some kind of error here;
            }
        }
    }
}
<commit_msg>format...<commit_after>use std::{
    fmt::Debug,
    os::unix::prelude::AsRawFd,
    sync::{Arc, Mutex},
};

use wayland_protocols_misc::zwp_virtual_keyboard_v1::server::zwp_virtual_keyboard_v1::{
    self, ZwpVirtualKeyboardV1,
};
use wayland_server::{
    backend::{ClientId, ObjectId},
    protocol::wl_keyboard::{KeyState, KeymapFormat},
    Client, DataInit, Dispatch, DisplayHandle,
};
use xkbcommon::xkb;

use crate::{
    input::{Seat, SeatHandler},
    utils::SERIAL_COUNTER,
    wayland::seat::{keyboard::for_each_focused_kbds, WaylandFocus},
};

use super::VirtualKeyboardManagerState;

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
struct SerializedMods {
    depressed: u32,
    latched: u32,
    locked: u32,
    group: u32,
}

#[derive(Debug, Default)]
pub(crate) struct VirtualKeyboard {
    instances: u8,
    modifiers: Option<SerializedMods>,
    old_keymap: Option<String>,
}

/// Handle to a virtual keyboard instance
#[derive(Debug, Clone, Default)]
pub(crate) struct VirtualKeyboardHandle {
    pub(crate) inner: Arc<Mutex<VirtualKeyboard>>,
}

impl VirtualKeyboardHandle {
    pub(super) fn count_instance(&self) {
        let mut inner = self.inner.lock().unwrap();
        inner.instances += 1;
    }
}

/// User data of ZwpVirtualKeyboardV1 object
pub struct VirtualKeyboardUserData<D: SeatHandler> {
    pub(super) handle: VirtualKeyboardHandle,
    pub(crate) seat: Seat<D>,
}

impl<D: SeatHandler> Debug for VirtualKeyboardUserData<D>
where
    <D as SeatHandler>::KeyboardFocus: Debug,
    <D as SeatHandler>::PointerFocus: Debug,
{
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("VirtualKeyboardUserData")
            .field("handle", &self.handle)
            .field("seat", &self.seat.arc)
            .finish()
    }
}

impl<D> Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>, D> for VirtualKeyboardManagerState
where
    D: Dispatch<ZwpVirtualKeyboardV1, VirtualKeyboardUserData<D>>,
    D: SeatHandler + 'static,
    <D as SeatHandler>::KeyboardFocus: WaylandFocus,
{
    fn request(
        _data: &mut D,
        _client: &Client,
        _: &ZwpVirtualKeyboardV1,
        request: zwp_virtual_keyboard_v1::Request,
        data: &VirtualKeyboardUserData<D>,
        _dh: &DisplayHandle,
        _data_init: &mut DataInit<'_, D>,
    ) {
        match request {
            zwp_virtual_keyboard_v1::Request::Keymap { format, fd, size } => {
                // This should be wl_keyboard::KeymapFormat::XkbV1,
                // but the protocol does not state the parameter is an enum.
                if format == 1 {
                    let keyboard_handle = data.seat.get_keyboard().unwrap();
                    let internal = keyboard_handle.arc.internal.lock().unwrap();
                    let old_keymap = internal.keymap.get_as_string(xkb::FORMAT_TEXT_V1);
                    let new_keymap = unsafe {
                        xkb::Keymap::new_from_fd(
                            &xkb::Context::new(xkb::CONTEXT_NO_FLAGS),
                            fd.as_raw_fd(),
                            size as usize,
                            format,
                            xkb::KEYMAP_COMPILE_NO_FLAGS,
                        )
                        .unwrap()
                        .unwrap()
                    };
                    if old_keymap != new_keymap.get_as_string(xkb::FORMAT_TEXT_V1) {
                        let mut inner = data.handle.inner.lock().unwrap();
                        inner.old_keymap = Some(old_keymap);
                        keyboard_handle.change_keymap(new_keymap);
                        let known_kbds = &keyboard_handle.arc.known_kbds;
                        for kbd in &*known_kbds.lock().unwrap() {
                            kbd.keymap(KeymapFormat::XkbV1, fd.as_raw_fd(), size);
                        }
                    }
                }
            }
            zwp_virtual_keyboard_v1::Request::Key { time, key, state } => {
                let keyboard_handle = data.seat.get_keyboard().unwrap();
                let internal = keyboard_handle.arc.internal.lock().unwrap();
                let inner = data.handle.inner.lock().unwrap();
                if let Some(focus) = internal.focus.as_ref().and_then(|f| f.0.wl_surface()) {
                    for_each_focused_kbds(&data.seat, focus, |kbd| {
                        // This should be wl_keyboard::KeyState,
                        // but the protocol does not state the parameter is an enum.
                        let key_state = if state == 1 {
                            KeyState::Pressed
                        } else {
                            KeyState::Released
                        };
                        kbd.key(SERIAL_COUNTER.next_serial().0, time, key, key_state);
                        if let Some(mods) = inner.modifiers {
                            kbd.modifiers(
                                SERIAL_COUNTER.next_serial().0,
                                mods.depressed,
                                mods.latched,
                                mods.locked,
                                mods.group,
                            );
                        }
                    });
                }
            }
            zwp_virtual_keyboard_v1::Request::Modifiers {
                mods_depressed,
                mods_latched,
                mods_locked,
                group,
            } => {
                data.handle.inner.lock().unwrap().modifiers = Some(SerializedMods {
                    depressed: mods_depressed,
                    latched: mods_latched,
                    locked: mods_locked,
                    group,
                });
            }
            zwp_virtual_keyboard_v1::Request::Destroy => {
                // Nothing to do
            }
            _ => unreachable!(),
        }
    }

    fn destroyed(
        _state: &mut D,
        _client: ClientId,
        _virtual_keyboard: ObjectId,
        data: &VirtualKeyboardUserData<D>,
    ) {
        let mut inner = data.handle.inner.lock().unwrap();
        inner.instances -= 1;
        if inner.instances == 0 {
            if let Some(old_keymap) = &inner.old_keymap {
                let keyboard_handle = data.seat.get_keyboard().unwrap();
                let old_keymap = xkb::Keymap::new_from_string(
                    &xkb::Context::new(xkb::CONTEXT_NO_FLAGS),
                    old_keymap.to_string(),
                    xkb::KEYMAP_FORMAT_TEXT_V1,
                    xkb::KEYMAP_COMPILE_NO_FLAGS,
                )
                .unwrap();
                keyboard_handle.change_keymap(old_keymap);
                let keymap_file = keyboard_handle.arc.keymap.lock().unwrap();
                keymap_file
                    .with_fd(false, |fd, size| {
                        let known_kbds = &keyboard_handle.arc.known_kbds;
                        for kbd in &*known_kbds.lock().unwrap() {
                            kbd.keymap(KeymapFormat::XkbV1, fd.as_raw_fd(), size as u32);
                        }
                    })
                    .ok(); //TODO: log some kind of error here;
            }
        }
    }
}
<|endoftext|>


<commit_before>/// # Even Fibonacci numbers
/// ## Problem 2
/// Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
/// 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
/// By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

extern crate num;

use std::mem;

struct Fib {
    a: int,
    b: int,
}

impl Iterator<int> for Fib {
    fn next(&mut self) -> Option<int> {
        let new_b = self.a + self.b;
        let new_a = mem::replace(&mut self.b, new_b);

        Some(mem::replace(&mut self.a, new_a))
    }
}

fn main() {
    let fib = Fib {a: 1i, b: 2i};
    let mut total = 0;

    for n in fib.take_while(|&n| n <= 4000000) {
        match n {
            n if n % 2 == 0 => total += n,
            _ => { /* do nothing */ }
        }
    }

    println!("Result: {}", total);
}
<commit_msg>Rust: Problem 2 - use `if`, not `match`<commit_after>/// # Even Fibonacci numbers
/// ## Problem 2
/// Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
/// 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
/// By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

extern crate num;

use std::mem;

struct Fib {
    a: int,
    b: int,
}

impl Iterator<int> for Fib {
    fn next(&mut self) -> Option<int> {
        let new_b = self.a + self.b;
        let new_a = mem::replace(&mut self.b, new_b);

        Some(mem::replace(&mut self.a, new_a))
    }
}

fn main() {
    let fib = Fib {a: 1i, b: 2i};
    let mut total = 0;

    for n in fib.take_while(|&n| n <= 4000000) {
        if n % 2 == 0 {
            total +=n;
        }
    }

    println!("Result: {}", total);
}
<|endoftext|>