<commit_before>extern mod extra;

use std::cell::Cell;
use std::rt::io::net::tcp::{TcpListener, TcpStream};
use std::rt::io::net::ip::Ipv4;
use std::rt::io::{Listener, Reader, ReaderUtil, Writer};
use extra::arc::RWArc;
use std::hashmap::HashMap;
use std::{uint, int, str};

fn main() {
    println("Started");

    let data = ~HashMap::new::<~[u8], ~[u8]>();
    let data_arc = RWArc::new(data);

    let port = 6380;
    let mut listener = TcpListener::bind(Ipv4(127, 0, 0, 1, port)).expect("Unable to bind to 127.0.0.1:6380");
    println(fmt!("Server is listening on %s", listener.socket_name().expect("").to_str()));

    loop {
        let stream = Cell::new(listener.accept());

        let local_arc = data_arc.clone();

        do std::task::spawn_supervised {
            let mut stream = stream.take().unwrap();
            println(fmt!("Client connected: %s", stream.peer_name().expect("").to_str()));

            let crlf = bytes!("\r\n");
            loop {
                let parse_res = parse_args(&mut stream);
                let mut response;
                match parse_res {
                    Err(msg) => {
                        response = msg.as_bytes().to_owned();
                    },
                    Ok(args) => {
                        response = cmd_dispatcher(&local_arc, args);
                    }
                }
                response.push_all(crlf);
                stream.write(response);
            }
        }
    }
}

fn read_byte(stream: &mut TcpStream) -> u8 {
    stream.read_byte().expect("")
}

fn read_bytes(stream: &mut TcpStream, len: uint) -> ~[u8] {
    let mut buffer = std::vec::with_capacity::<u8>(len);

    for i in range(0, len) {
        buffer[i] = stream.read_byte().expect("");
    }

    buffer
}

fn read_until(stream: &mut TcpStream, until: u8) -> ~[u8] {
    let mut buffer: ~[u8] = ~[];

    loop {
        let byte = stream.read_byte().expect("");
        if byte == until {
            break
        }
        buffer.push(byte);
    }

    buffer
}

static CR: u8 = '\r' as u8;
static STAR: u8 = '*' as u8;
static DOLLAR: u8 = '$' as u8;

fn parse_args(stream: &mut TcpStream) -> Result<~[~[u8]], ~str> {
    let first_byte = read_byte(stream);
    let mut args = ~[];

    if first_byte == STAR {
        let mut arg_count;
        match uint::parse_bytes(read_until(stream, CR), 10) {
            Some(count) => {
                arg_count = count;
            },
            None => {
                return Err(~"Could not parse argument count as uint");
            }
        }

        // discard \n
        read_byte(stream);

        for _ in range(0, arg_count) {
            let byte = read_byte(stream);
            if byte != DOLLAR {
                return Err(fmt!("No argument length found, expected $, got %?", byte));
            }
            let arg_len;
            match uint::parse_bytes(read_until(stream, CR), 10) {
                Some(count) => {
                    arg_len = count;
                },
                None => {
                    return Err(~"Could not parse argument length as uint");
                }
            }
            // discard \n
            read_byte(stream);

            args.push(stream.read_bytes(arg_len));

            // discard \r\n
            stream.read_bytes(2);
        }
    } else {
        let input = str::from_byte(first_byte);
        let input = input.append(str::from_bytes(read_until(stream, CR)));

        // discard \n
        stream.read_byte();

        let words: ~[&str] = input.split_iter(' ').collect();
        args = words.map(|word| {
            word.as_bytes().to_owned()
        })
    }

    Ok(args)
}

fn cmd_dispatcher(arc: &RWArc<~HashMap<~[u8], ~[u8]>>, mut args: ~[~[u8]]) -> ~[u8] {
    let command = args[0].to_ascii().to_lower().into_str().to_owned();

    //println(fmt!("%s: %?", command, args));

    let mut output = ~[];
    if command == ~"get" {
        do arc.read() |data| {
            let res = data.find(&args[1]);
            if res.is_some() {
                let result = [~"$", res.unwrap().len().to_str(), ~"\r\n"].concat();
                output = result.as_bytes().to_owned();
                output.push_all(*res.unwrap());
            } else {
                output = bytes!("$-1").to_owned();
            }
        }
    } else if command == ~"set" {
        if (args.len() < 3) {
            output = bytes!("-ERR wrong number of arguments for 'set' command").to_owned();
        } else {
            do arc.write() |data| {
                args.truncate(3);
                let val = args.pop();
                let key = args.pop();
                data.insert(key, val);

                output = bytes!("+OK").to_owned();
            }
        }
    } else if command == ~"incr" || command == ~"decr" || command == ~"incrby" || command == ~"decrby" {
        let mut cur_val = 0;

        do arc.read() |data| {
            let res = data.find(&args[1]);

            if res.is_some() {
                match int::parse_bytes(*res.unwrap(), 10) {
                    Some(val) => {
                        cur_val = val;
                    },
                    None => {
                        output = bytes!("-ERR value is not an integer or out of range").to_owned();
                    }
                }
            }
        }

        let mut incr_by = 1;
        if command == ~"incrby" || command == ~"decrby" {
            args.truncate(3);
            match int::parse_bytes(args.pop(), 10) {
                Some(val) => {
                    incr_by = val;
                },
                None => {
                    output = bytes!("-ERR incrby argument is not an integer or out of range").to_owned();
                }
            }
        }
        if command == ~"decr" || command == ~"decrby" {
            incr_by = -incr_by;
        }

        if output.len() == 0 {
            do arc.write() |data| {
                args.truncate(2);
                let key = args.pop();
                let new_val = (cur_val + incr_by).to_str();
                let new_val = new_val.as_bytes().to_owned();
                output = bytes!(":").to_owned();
                output.push_all(new_val);
                data.insert(key, new_val);
            }
        }
    } else {
        let result = fmt!("-ERR unknown command '%s'", command);
        output = result.as_bytes().to_owned();
    }

    output
}
<commit_msg>Update to latest rust, buggy state though<commit_after>extern mod extra;

use std::cell::Cell;
use std::io::net::tcp::{TcpListener, TcpStream};
use std::io::net::ip::SocketAddr;
use std::io::{Listener, Reader, Writer, Acceptor};
use extra::arc::RWArc;
use std::hashmap::HashMap;
use std::{uint, int, str};

fn main() {
    println("Started");

    let data: HashMap<~[u8], ~[u8]> = HashMap::new();
    let data_arc = RWArc::new(data);

    let port = 6380;
    let addr: SocketAddr = FromStr::from_str(format!("127.0.0.1:{}", port)).expect("");
    let mut listener = TcpListener::bind(addr).expect(format!("Unable to bind to 127.0.0.1:{}", port));
    let sock = listener.socket_name().expect("");
    let mut acceptor = listener.listen().expect(format!("Could not start listening for connections"));
    println(format!("Server listening on {}", sock.to_str()));

    loop {
        let stream = Cell::new(acceptor.accept());

        let local_arc = data_arc.clone();

        do std::task::spawn_supervised {
            let mut stream = stream.take().unwrap();
            println(format!("New client: {}", stream.peer_name().expect("").to_str()));

            let crlf = bytes!("\r\n");
            loop {
                let parse_res = parse_args(&mut stream);
                let mut response;
                match parse_res {
                    Err(msg) => {
                        response = msg.as_bytes().to_owned();
                    },
                    Ok(args) => {
                        response = cmd_dispatcher(&local_arc, args);
                    }
                }
                response.push_all(crlf);
                stream.write(response);
            }
        }
    }
}

fn read_byte(stream: &mut TcpStream) -> u8 {
    stream.read_byte().expect("")
}

fn read_bytes(stream: &mut TcpStream, len: uint) -> ~[u8] {
    let mut buffer = std::vec::with_capacity::<u8>(len);

    for i in range(0, len) {
        buffer[i] = stream.read_byte().expect("");
    }

    buffer
}

fn read_until(stream: &mut TcpStream, until: u8) -> ~[u8] {
    let mut buffer: ~[u8] = ~[];

    loop {
        let byte = stream.read_byte().expect("");
        if byte == until {
            break
        }
        buffer.push(byte);
    }

    buffer
}

static CR: u8 = '\r' as u8;
static STAR: u8 = '*' as u8;
static DOLLAR: u8 = '$' as u8;

fn parse_args(stream: &mut TcpStream) -> Result<~[~[u8]], ~str> {
    let first_byte = read_byte(stream);
    let mut args = ~[];

    if first_byte == STAR {
        let mut arg_count;
        match uint::parse_bytes(read_until(stream, CR), 10) {
            Some(count) => {
                arg_count = count;
            },
            None => {
                return Err(~"Could not parse argument count as uint");
            }
        }

        // discard \n
        read_byte(stream);

        for _ in range(0, arg_count) {
            let byte = read_byte(stream);
            if byte != DOLLAR {
                return Err(format!("No argument length found, expected $, got {}", byte));
            }
            let arg_len;
            match uint::parse_bytes(read_until(stream, CR), 10) {
                Some(count) => {
                    arg_len = count;
                },
                None => {
                    return Err(~"Could not parse argument length as uint");
                }
            }
            // discard \n
            read_byte(stream);

            args.push(stream.read_bytes(arg_len));

            // discard \r\n
            stream.read_bytes(2);
        }
    } else {
        let input = str::from_byte(first_byte);
        let input = input.append(read_until(stream, CR).to_str());

        // discard \n
        stream.read_byte();

        let words: ~[&str] = input.split_iter(' ').collect();
        args = words.map(|word| {
            word.as_bytes().to_owned()
        })
    }

    Ok(args)
}

fn cmd_dispatcher(arc: &RWArc<HashMap<~[u8], ~[u8]>>, mut args: ~[~[u8]]) -> ~[u8] {
    let command = args[0].to_ascii().to_lower().into_str().to_owned();

    //println(format!("{}: %?", command, args));

    let mut output = ~[];
    if command == ~"get" {
        do arc.read() |data| {
            let res = data.find(&args[1]);
            if res.is_some() {
                let result = [~"$", res.unwrap().len().to_str(), ~"\r\n"].concat();
                output = result.as_bytes().to_owned();
                output.push_all(*res.unwrap());
            } else {
                output = bytes!("$-1").to_owned();
            }
        }
    } else if command == ~"set" {
        if (args.len() < 3) {
            output = bytes!("-ERR wrong number of arguments for 'set' command").to_owned();
        } else {
            do arc.write() |data| {
                args.truncate(3);
                let val = args.pop();
                let key = args.pop();
                data.insert(key, val);

                output = bytes!("+OK").to_owned();
            }
        }
    } else if command == ~"incr" || command == ~"decr" || command == ~"incrby" || command == ~"decrby" {
        let mut cur_val = 0;

        do arc.read() |data| {
            let res = data.find(&args[1]);

            if res.is_some() {
                match int::parse_bytes(*res.unwrap(), 10) {
                    Some(val) => {
                        cur_val = val;
                    },
                    None => {
                        output = bytes!("-ERR value is not an integer or out of range").to_owned();
                    }
                }
            }
        }

        let mut incr_by = 1;
        if command == ~"incrby" || command == ~"decrby" {
            args.truncate(3);
            match int::parse_bytes(args.pop(), 10) {
                Some(val) => {
                    incr_by = val;
                },
                None => {
                    output = bytes!("-ERR incrby argument is not an integer or out of range").to_owned();
                }
            }
        }
        if command == ~"decr" || command == ~"decrby" {
            incr_by = -incr_by;
        }

        if output.len() == 0 {
            do arc.write() |data| {
                args.truncate(2);
                let key = args.pop();
                let new_val = (cur_val + incr_by).to_str();
                let new_val = new_val.as_bytes().to_owned();
                output = bytes!(":").to_owned();
                output.push_all(new_val);
                data.insert(key, new_val);
            }
        }
    } else {
        let result = format!("-ERR unknown command '{}'", command);
        output = result.as_bytes().to_owned();
    }

    output
}
<|endoftext|>


<commit_before>// See: https://github.com/rust-lang/regex/issues/48
#[test]
fn invalid_regexes_no_crash() {
    assert!(regex_new!("(*)").is_err());
    assert!(regex_new!("(?:?)").is_err());
    assert!(regex_new!("(?)").is_err());
    assert!(regex_new!("*").is_err());
}

// See: https://github.com/rust-lang/regex/issues/98
#[test]
fn regression_many_repeat_stack_overflow() {
    let re = regex!("^.{1,2500}");
    assert_eq!(vec![(0, 1)], findall!(re, "a"));
}

// See: https://github.com/rust-lang/regex/issues/75
mat!(regression_unsorted_binary_search_1, r"(?i)[a_]+", "A_", Some((0, 2)));
mat!(regression_unsorted_binary_search_2, r"(?i)[A_]+", "a_", Some((0, 2)));

// See: https://github.com/rust-lang/regex/issues/99
mat!(regression_negated_char_class_1, r"(?i)[^x]", "x", None);
mat!(regression_negated_char_class_2, r"(?i)[^x]", "X", None);

// See: https://github.com/rust-lang/regex/issues/101
mat!(regression_ascii_word_underscore, r"[:word:]", "_", Some((0, 1)));

// See: https://github.com/rust-lang-nursery/regex/issues/129
#[test]
fn regression_captures_rep() {
    let re = regex!(r"([a-f]){2}(?P<foo>[x-z])");
    let caps = re.captures(text!("abx")).unwrap();
    assert_eq!(caps.name("foo").unwrap(), text!("x"));
}

// See: https://github.com/rust-lang-nursery/regex/issues/153
mat!(regression_alt_in_alt1, r"ab?|$", "az", Some((0, 1)));
mat!(regression_alt_in_alt2, r"^(.*?)(\n|\r\n?|$)", "ab\rcd", Some((0, 3)));

// See: https://github.com/rust-lang-nursery/regex/issues/169
mat!(regression_leftmost_first_prefix, r"z*azb", "azb", Some((0, 3)));

// See: https://github.com/rust-lang/regex/issues/76
mat!(uni_case_lower_nocase_flag, u!(r"(?i)\p{Ll}+"), "ΛΘΓΔα", Some((0, 10)));
<commit_msg>Regression test for #191.<commit_after>// See: https://github.com/rust-lang/regex/issues/48
#[test]
fn invalid_regexes_no_crash() {
    assert!(regex_new!("(*)").is_err());
    assert!(regex_new!("(?:?)").is_err());
    assert!(regex_new!("(?)").is_err());
    assert!(regex_new!("*").is_err());
}

// See: https://github.com/rust-lang/regex/issues/98
#[test]
fn regression_many_repeat_stack_overflow() {
    let re = regex!("^.{1,2500}");
    assert_eq!(vec![(0, 1)], findall!(re, "a"));
}

// See: https://github.com/rust-lang/regex/issues/75
mat!(regression_unsorted_binary_search_1, r"(?i)[a_]+", "A_", Some((0, 2)));
mat!(regression_unsorted_binary_search_2, r"(?i)[A_]+", "a_", Some((0, 2)));

// See: https://github.com/rust-lang/regex/issues/99
mat!(regression_negated_char_class_1, r"(?i)[^x]", "x", None);
mat!(regression_negated_char_class_2, r"(?i)[^x]", "X", None);

// See: https://github.com/rust-lang/regex/issues/101
mat!(regression_ascii_word_underscore, r"[:word:]", "_", Some((0, 1)));

// See: https://github.com/rust-lang-nursery/regex/issues/129
#[test]
fn regression_captures_rep() {
    let re = regex!(r"([a-f]){2}(?P<foo>[x-z])");
    let caps = re.captures(text!("abx")).unwrap();
    assert_eq!(caps.name("foo").unwrap(), text!("x"));
}

// See: https://github.com/rust-lang-nursery/regex/issues/153
mat!(regression_alt_in_alt1, r"ab?|$", "az", Some((0, 1)));
mat!(regression_alt_in_alt2, r"^(.*?)(\n|\r\n?|$)", "ab\rcd", Some((0, 3)));

// See: https://github.com/rust-lang-nursery/regex/issues/169
mat!(regression_leftmost_first_prefix, r"z*azb", "azb", Some((0, 3)));

// See: https://github.com/rust-lang/regex/issues/76
mat!(uni_case_lower_nocase_flag, u!(r"(?i)\p{Ll}+"), "ΛΘΓΔα", Some((0, 10)));

// See: https://github.com/rust-lang-nursery/regex/issues/191
mat!(many_alternates, r"1|2|3|4|5|6|7|8|9|10|int", "int", Some((0, 3)));
<|endoftext|>


<commit_before>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{ReadStream, Stream, StreamProducer};
use flac::metadata;
use flac::metadata::VorbisComment;

use std::env;
use std::fs::File;

const USAGE: &'static str = "
Usage: metadata streaminfo [options] <input>
       metadata comments [options] <input>
       metadata --help

Options:
  --block-size       Show both the max and min block size from StreamInfo.
  --frame-size       Show both the max and min frame size from StreamInfo.
  --sample-rate      Show the sample rate from StreamInfo.
  --channels         Show the number of channels from StreamInfo.
  --bits-per-sample  Show the size in bits for each sample from StreamInfo.
  --total-samples    Show total number of samples from StreamInfo.
  --md5              Show the MD5 signature from StreamInfo.
  --vendor           Show the vendor string from VorbisComment.
  --name=NAME        Show the comments matching the `NAME` from VorbisComment.
  -h, --help         Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_input: String,
  cmd_streaminfo: bool,
  cmd_comments: bool,
  flag_block_size: bool,
  flag_frame_size: bool,
  flag_sample_rate: bool,
  flag_channels: bool,
  flag_bits_per_sample: bool,
  flag_total_samples: bool,
  flag_md5: bool,
  flag_vendor: bool,
  flag_name: Option<String>,
}

fn print_stream_info<P>(stream: &Stream<P>, args: &Arguments)
 where P: StreamProducer {
  let info     = stream.info();
  let no_flags = (args.flag_block_size      || args.flag_frame_size    ||
                  args.flag_sample_rate     || args.flag_channels      ||
                  args.flag_bits_per_sample || args.flag_total_samples ||
                  args.flag_md5) == false;

  if no_flags || args.flag_block_size {
    println!("Minimum block size: {} samples", info.min_block_size);
    println!("Maximum block size: {} samples", info.max_block_size);
  }

  if no_flags || args.flag_frame_size {
    println!("Minimum frame size: {} bytes", info.min_frame_size);
    println!("Maximum frame size: {} bytes", info.max_frame_size);
  }

  if no_flags || args.flag_sample_rate {
    println!("Sample rate: {} Hz", info.sample_rate);
  }

  if no_flags || args.flag_channels {
    println!("Number of channels: {}", info.channels);
  }

  if no_flags || args.flag_bits_per_sample {
    println!("Bits per sample: {}", info.bits_per_sample);
  }

  if no_flags || args.flag_total_samples {
    println!("Total samples: {}", info.total_samples);
  }

  if no_flags || args.flag_md5 {
    let mut md5  = String::with_capacity(32);

    for byte in &info.md5_sum {
      let hex = format!("{:02x}", byte);

      md5.push_str(&hex);
    }

    println!("MD5 sum: {}", md5);
  }
}

fn print_vorbis_comments(vorbis_comment: &VorbisComment, args: &Arguments) {
  let mut index = 1;
  let no_flags  = (args.flag_vendor || args.flag_name.is_some()) == false;

  if no_flags || args.flag_vendor {
    println!("Vendor String: {}", vorbis_comment.vendor_string);
  }

  if no_flags {
    println!("Number of Comments: {}", vorbis_comment.comments.len());
  }

  for comment in &vorbis_comment.comments {
    let is_name = if let Some(ref name) = args.flag_name {
      name == comment.0
    } else {
      false
    };

    if no_flags || is_name {
      println!("  {}: \"{}\" = {}", index, comment.0, comment.1);
    }

    index += 1;
  }
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  let stream = Stream::<ReadStream<File>>::from_file(&args.arg_input)
                 .expect("Couldn't parse file");

  if args.cmd_streaminfo {
    print_stream_info(&stream, &args);
  }

  for meta in stream.metadata() {
    match meta.data {
      metadata::Data::VorbisComment(ref v) => {
        if args.cmd_comments {
          print_vorbis_comments(v, &args)
        }
      }
      _                                    => continue,
    }
  }
}
<commit_msg>Add a macro for option print formating<commit_after>extern crate docopt;
extern crate flac;
extern crate rustc_serialize;

use docopt::Docopt;
use flac::{ReadStream, Stream, StreamProducer};
use flac::metadata;
use flac::metadata::VorbisComment;

use std::env;
use std::fs::File;

const USAGE: &'static str = "
Usage: metadata streaminfo [options] <input>
       metadata comments [options] <input>
       metadata --help

Options:
  --block-size       Show both the max and min block size from StreamInfo.
  --frame-size       Show both the max and min frame size from StreamInfo.
  --sample-rate      Show the sample rate from StreamInfo.
  --channels         Show the number of channels from StreamInfo.
  --bits-per-sample  Show the size in bits for each sample from StreamInfo.
  --total-samples    Show total number of samples from StreamInfo.
  --md5              Show the MD5 signature from StreamInfo.
  --vendor           Show the vendor string from VorbisComment.
  --name=NAME        Show the comments matching the `NAME` from VorbisComment.
  -h, --help         Show this message.
";

#[derive(Debug, RustcDecodable)]
struct Arguments {
  arg_input: String,
  cmd_streaminfo: bool,
  cmd_comments: bool,
  flag_block_size: bool,
  flag_frame_size: bool,
  flag_sample_rate: bool,
  flag_channels: bool,
  flag_bits_per_sample: bool,
  flag_total_samples: bool,
  flag_md5: bool,
  flag_vendor: bool,
  flag_name: Option<String>,
}

macro_rules! format_print (
  ($format_str: expr, $opt_str: expr, $data: expr, $no_flag: expr) => (
    {
      println!($format_str, if $no_flag {
        $opt_str
      } else {
        ""
      }, $data);
    }
  );
);

fn print_stream_info<P>(stream: &Stream<P>, args: &Arguments)
 where P: StreamProducer {
  let info     = stream.info();
  let no_flags = (args.flag_block_size      || args.flag_frame_size    ||
                  args.flag_sample_rate     || args.flag_channels      ||
                  args.flag_bits_per_sample || args.flag_total_samples ||
                  args.flag_md5) == false;

  if no_flags || args.flag_block_size {
    println!("Minimum block size: {} samples", info.min_block_size);
    println!("Maximum block size: {} samples", info.max_block_size);
  }

  if no_flags || args.flag_frame_size {
    println!("Minimum frame size: {} bytes", info.min_frame_size);
    println!("Maximum frame size: {} bytes", info.max_frame_size);
  }

  if no_flags || args.flag_sample_rate {
    println!("Sample rate: {} Hz", info.sample_rate);
  }

  if no_flags || args.flag_channels {
    println!("Number of channels: {}", info.channels);
  }

  if no_flags || args.flag_bits_per_sample {
    println!("Bits per sample: {}", info.bits_per_sample);
  }

  if no_flags || args.flag_total_samples {
    println!("Total samples: {}", info.total_samples);
  }

  if no_flags || args.flag_md5 {
    let mut md5  = String::with_capacity(32);

    for byte in &info.md5_sum {
      let hex = format!("{:02x}", byte);

      md5.push_str(&hex);
    }

    println!("MD5 sum: {}", md5);
  }
}

fn print_vorbis_comments(vorbis_comment: &VorbisComment, args: &Arguments) {
  let mut index = 1;
  let no_flags  = (args.flag_vendor || args.flag_name.is_some()) == false;

  if no_flags || args.flag_vendor {
    println!("Vendor String: {}", vorbis_comment.vendor_string);
  }

  if no_flags {
    println!("Number of Comments: {}", vorbis_comment.comments.len());
  }

  for comment in &vorbis_comment.comments {
    let is_name = if let Some(ref name) = args.flag_name {
      name == comment.0
    } else {
      false
    };

    if no_flags || is_name {
      println!("  {}: \"{}\" = {}", index, comment.0, comment.1);
    }

    index += 1;
  }
}

fn main() {
  let args: Arguments = Docopt::new(USAGE)
    .and_then(|d| d.argv(env::args()).decode())
    .unwrap_or_else(|e| e.exit());

  let stream = Stream::<ReadStream<File>>::from_file(&args.arg_input)
                 .expect("Couldn't parse file");

  if args.cmd_streaminfo {
    print_stream_info(&stream, &args);
  }

  for meta in stream.metadata() {
    match meta.data {
      metadata::Data::VorbisComment(ref v) => {
        if args.cmd_comments {
          print_vorbis_comments(v, &args)
        }
      }
      _                                    => continue,
    }
  }
}
<|endoftext|>


<commit_before>extern crate mac;
extern crate serialize;

extern crate iron;
extern crate hyper;
extern crate params;

use std::path::Path;
use std::{thread, time};
use std::fs::File;
use std::io::Read;
use std::io::BufReader;

use iron::prelude::*;
use iron::status;
use params::Params;

use mac::hmac_sha1;
use serialize::from_hex;

fn insecure_compare(u: &[u8], v: &[u8]) -> bool {
    if u.len() != v.len() {
        return false;
    }

    for (x, y) in u.iter().zip(v.iter()) {
        if x != y {
            return false;
        }
        thread::sleep(time::Duration::from_millis(1));
    }
    true
}

fn file_hmac_sha1(key: &[u8], file: &str) -> Option<Vec<u8>> {
    let path = Path::new("/home/ph/Development/matasano/matasano/src/").join(file);

    let file = match File::open(&path) {
        Ok(file) => file,
        Err(_) =>  {
            println!("Failed to load file from {:?}", path);
            return None;
        },
    };
    let mut reader = BufReader::new(file);
    let mut content = Vec::new();
    reader.read_to_end(&mut content).ok().unwrap();
    Some(hmac_sha1(key, &content))
}

fn verify_signature(req: &mut Request, key: &[u8]) -> IronResult<Response> {
    let params = req.get_ref::<Params>().unwrap();
    let file = match params.find(&["file"]) {
        //None => return Err(CustomError::new("missing file parameter")),
        Some(&params::Value::String(ref file)) => file.clone(), // clone() is critical
        //_ => return Err(CustomError::new("file parameter was not a single string"))
        _ => return Ok(Response::with(status::InternalServerError))
    };
    let signature = match params.find(&["signature"]) {
        //None => return Err(CustomError::new("missing signature parameter")),
        Some(&params::Value::String(ref signature)) => signature.clone(), // clone() is critical
        //_ => return Err(CustomError::new("signature parameter was not a single string"))
        _ => return Ok(Response::with(status::InternalServerError))
    };

    let computed_hmac = match file_hmac_sha1(&key, &file) {
       Some(hmac) => hmac,
       None => return Ok(Response::with(status::InternalServerError)),
    };

    if insecure_compare(&computed_hmac, &from_hex(&signature).unwrap()) {
        Ok(Response::with(status::Ok))
    } else {
        Ok(Response::with(status::InternalServerError))
    }
}

pub fn start(key: Vec<u8>) -> hyper::server::Listening {
    Iron::new(move |req: &mut Request| verify_signature(req, &key)).http("localhost:3000").unwrap()
}
<commit_msg>Another clippy warning<commit_after>extern crate mac;
extern crate serialize;

extern crate iron;
extern crate hyper;
extern crate params;

use std::path::Path;
use std::{thread, time};
use std::fs::File;
use std::io::Read;
use std::io::BufReader;

use iron::prelude::*;
use iron::status;
use params::Params;

use mac::hmac_sha1;
use serialize::from_hex;

fn insecure_compare(u: &[u8], v: &[u8]) -> bool {
    if u.len() != v.len() {
        return false;
    }

    for (x, y) in u.iter().zip(v.iter()) {
        if x != y {
            return false;
        }
        thread::sleep(time::Duration::from_millis(1));
    }
    true
}

fn file_hmac_sha1(key: &[u8], file: &str) -> Option<Vec<u8>> {
    let path = Path::new("/home/ph/Development/matasano/matasano/src/").join(file);

    let file = match File::open(&path) {
        Ok(file) => file,
        Err(_) =>  {
            println!("Failed to load file from {:?}", path);
            return None;
        },
    };
    let mut reader = BufReader::new(file);
    let mut content = Vec::new();
    reader.read_to_end(&mut content).ok().unwrap();
    Some(hmac_sha1(key, &content))
}

fn verify_signature(req: &mut Request, key: &[u8]) -> IronResult<Response> {
    let params = req.get_ref::<Params>().unwrap();
    let file = match params.find(&["file"]) {
        //None => return Err(CustomError::new("missing file parameter")),
        Some(&params::Value::String(ref file)) => file.clone(), // clone() is critical
        //_ => return Err(CustomError::new("file parameter was not a single string"))
        _ => return Ok(Response::with(status::InternalServerError))
    };
    let signature = match params.find(&["signature"]) {
        //None => return Err(CustomError::new("missing signature parameter")),
        Some(&params::Value::String(ref signature)) => signature.clone(), // clone() is critical
        //_ => return Err(CustomError::new("signature parameter was not a single string"))
        _ => return Ok(Response::with(status::InternalServerError))
    };

    let computed_hmac = match file_hmac_sha1(key, &file) {
       Some(hmac) => hmac,
       None => return Ok(Response::with(status::InternalServerError)),
    };

    if insecure_compare(&computed_hmac, &from_hex(&signature).unwrap()) {
        Ok(Response::with(status::Ok))
    } else {
        Ok(Response::with(status::InternalServerError))
    }
}

pub fn start(key: Vec<u8>) -> hyper::server::Listening {
    Iron::new(move |req: &mut Request| verify_signature(req, &key)).http("localhost:3000").unwrap()
}
<|endoftext|>


<commit_before>extern crate rsteglib;

use rsteglib::image_encoder::CoverImage;

#[test]
fn create() {
    let cover_image = CoverImage::new()
        .set_cover_image("/home/hugh/Pictures/static.politico.com.jpeg")
        .set_message("whatever")
        .set_output_image_path("hdsd");
}
<commit_msg>This test shouldn't have been commited in the first place<commit_after>extern crate rsteglib;

use rsteglib::image_encoder::CoverImage;

<|endoftext|>


<commit_before>use gemlab::{mesh::Mesh, StrError};
use russell_chk::assert_vec_approx_eq;
use russell_lab::Vector;

#[test]
fn column_distorted_tris_quads() -> Result<(), StrError> {
    // read mesh
    let mesh = Mesh::from_text_file("./data/meshes/column_distorted_tris_quads.msh")?;
    println!("{}", mesh);

    // check sizes
    assert_eq!(mesh.points.len(), 13);
    assert_eq!(mesh.cells.len(), 7);
    assert_eq!(mesh.boundary_points.len(), 13);
    assert_eq!(mesh.boundary_edges.len(), 13);
    assert_eq!(mesh.boundary_faces.len(), 0);

    // check cells
    assert_eq!(mesh.cells[0].points, &[0, 7, 8, 1]);
    assert_eq!(mesh.cells[1].points, &[1, 8, 9, 2]);
    assert_eq!(mesh.cells[2].points, &[2, 9, 10, 3]);
    assert_eq!(mesh.cells[3].points, &[3, 10, 4]);
    assert_eq!(mesh.cells[4].points, &[4, 10, 11]);
    assert_eq!(mesh.cells[5].points, &[4, 11, 5]);
    assert_eq!(mesh.cells[6].points, &[5, 11, 12, 6]);

    // check edges
    let edge = mesh.boundary_edges.get(&(0, 1)).unwrap();
    assert_eq!(edge.points, &[0, 1]);
    let edge = mesh.boundary_edges.get(&(9, 10)).unwrap();
    assert_eq!(edge.points, &[10, 9]);
    let edge = mesh.boundary_edges.get(&(3, 4)).unwrap();
    assert_eq!(edge.points, &[3, 4]);

    // the magnitude of the normal vector should be equal to edge_length / 2.0
    // for both tris or quas where 2.0 corresponds to the edge_length in the reference system
    // Note that the edge is mapped to [-1,+1] in both Lin or Qua

    // edge keys and correct normal vectors (solutions)
    let edge_keys_and_solutions = [
        // left
        (vec![(0, 1)], [-0.5 / 2.0, 0.0]),
        (vec![(1, 2)], [-0.5 / 2.0, 0.0]),
        (vec![(2, 3)], [-1.0 / 2.0, 0.0]),
        (vec![(3, 4)], [-0.5 / 2.0, 0.0]),
        (vec![(4, 5)], [-0.5 / 2.0, 0.0]),
        (vec![(5, 6)], [-0.1 / 2.0, 0.0]),
        // right
        (vec![(7, 8)], [0.2 / 2.0, 0.0]),
        (vec![(8, 9)], [0.8 / 2.0, 0.0]),
        (vec![(9, 10)], [0.8 / 2.0, 0.0]),
        (vec![(10, 11)], [1.2 / 2.0, 0.0]),
        (vec![(11, 12)], [0.1 / 2.0, 0.0]),
        // bottom
        (vec![(0, 7)], [0.0, -1.0 / 2.0]),
        // top
        (vec![(6, 12)], [0.0, 1.0 / 2.0]),
    ];

    // check if the normal vectors at boundary are outward
    let mut normal = Vector::new(mesh.space_ndim);
    let ksi = &[0.0, 0.0, 0.0];
    for (edge_keys, solution) in &edge_keys_and_solutions {
        for edge_key in edge_keys {
            let mut edge_shape = mesh.alloc_shape_boundary_edge(edge_key)?;
            assert_eq!(edge_shape.nnode, 2);
            edge_shape.calc_boundary_normal(&mut normal, ksi)?;
            assert_vec_approx_eq!(normal.as_data(), solution, 1e-14);
        }
    }

    Ok(())
}

#[test]
fn rectangle_tris_quads() -> Result<(), StrError> {
    // read mesh
    let mesh = Mesh::from_text_file("./data/meshes/rectangle_tris_quads.msh")?;
    println!("{}", mesh);
    Ok(())
}
<commit_msg>Improve test<commit_after>use gemlab::mesh::{At, Mesh};
use gemlab::StrError;
use russell_chk::assert_vec_approx_eq;
use russell_lab::Vector;

#[test]
fn column_distorted_tris_quads() -> Result<(), StrError> {
    // read mesh
    let mesh = Mesh::from_text_file("./data/meshes/column_distorted_tris_quads.msh")?;
    println!("{}", mesh);

    // check sizes
    assert_eq!(mesh.points.len(), 13);
    assert_eq!(mesh.cells.len(), 7);
    assert_eq!(mesh.boundary_points.len(), 13);
    assert_eq!(mesh.boundary_edges.len(), 13);
    assert_eq!(mesh.boundary_faces.len(), 0);

    // check cells
    assert_eq!(mesh.cells[0].points, &[0, 7, 8, 1]);
    assert_eq!(mesh.cells[1].points, &[1, 8, 9, 2]);
    assert_eq!(mesh.cells[2].points, &[2, 9, 10, 3]);
    assert_eq!(mesh.cells[3].points, &[3, 10, 4]);
    assert_eq!(mesh.cells[4].points, &[4, 10, 11]);
    assert_eq!(mesh.cells[5].points, &[4, 11, 5]);
    assert_eq!(mesh.cells[6].points, &[5, 11, 12, 6]);

    // check edges
    let edge = mesh.boundary_edges.get(&(0, 1)).unwrap();
    assert_eq!(edge.points, &[0, 1]);
    let edge = mesh.boundary_edges.get(&(9, 10)).unwrap();
    assert_eq!(edge.points, &[10, 9]);
    let edge = mesh.boundary_edges.get(&(3, 4)).unwrap();
    assert_eq!(edge.points, &[3, 4]);

    // the magnitude of the normal vector should be equal to edge_length / 2.0
    // for both tris or quas where 2.0 corresponds to the edge_length in the reference system
    // Note that the edge is mapped to [-1,+1] in both Lin or Qua

    // edge keys and correct normal vectors (solutions)
    let edge_keys_and_solutions = [
        // left
        (vec![(0, 1)], [-0.5 / 2.0, 0.0]),
        (vec![(1, 2)], [-0.5 / 2.0, 0.0]),
        (vec![(2, 3)], [-1.0 / 2.0, 0.0]),
        (vec![(3, 4)], [-0.5 / 2.0, 0.0]),
        (vec![(4, 5)], [-0.5 / 2.0, 0.0]),
        (vec![(5, 6)], [-0.1 / 2.0, 0.0]),
        // right
        (vec![(7, 8)], [0.2 / 2.0, 0.0]),
        (vec![(8, 9)], [0.8 / 2.0, 0.0]),
        (vec![(9, 10)], [0.8 / 2.0, 0.0]),
        (vec![(10, 11)], [1.2 / 2.0, 0.0]),
        (vec![(11, 12)], [0.1 / 2.0, 0.0]),
        // bottom
        (vec![(0, 7)], [0.0, -1.0 / 2.0]),
        // top
        (vec![(6, 12)], [0.0, 1.0 / 2.0]),
    ];

    // check if the normal vectors at boundary are outward
    let mut normal = Vector::new(mesh.space_ndim);
    let ksi = &[0.0, 0.0, 0.0];
    for (edge_keys, solution) in &edge_keys_and_solutions {
        for edge_key in edge_keys {
            let mut edge_shape = mesh.alloc_shape_boundary_edge(edge_key)?;
            assert_eq!(edge_shape.nnode, 2);
            edge_shape.calc_boundary_normal(&mut normal, ksi)?;
            assert_vec_approx_eq!(normal.as_data(), solution, 1e-14);
        }
    }

    // find points
    let points = mesh.find_boundary_points(At::X(0.0))?;
    assert_eq!(points, &[0, 1, 2, 3, 4, 5, 6]);
    let points = mesh.find_boundary_points(At::X(1.0))?;
    assert_eq!(points, &[7, 8, 9, 10, 11, 12]);

    // find edges
    let edges = mesh.find_boundary_edges(At::X(0.0))?;
    assert_eq!(edges, &[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]);
    let edges = mesh.find_boundary_edges(At::X(1.0))?;
    assert_eq!(edges, &[(7, 8), (8, 9), (9, 10), (10, 11), (11, 12)]);

    // find faces
    let faces = mesh.find_boundary_faces(At::X(0.0))?;
    assert_eq!(faces.len(), 0);
    Ok(())
}

#[test]
fn rectangle_tris_quads() -> Result<(), StrError> {
    // read mesh
    let mesh = Mesh::from_text_file("./data/meshes/rectangle_tris_quads.msh")?;
    println!("{}", mesh);
    Ok(())
}
<|endoftext|>


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

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 structopt::StructOpt;

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

    /// Which port to listen on
    #[structopt(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 {
                    println!("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 {
                            println!("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::create_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();

    let listen_addr = format!("0.0.0.0:{}", port);
    let listener = TcpListener::bind(&listen_addr).unwrap();
    if verbose {
        println!("listening on: {}", 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) {
                    eprintln!("[ERROR] {}", e);
                }
            }
            Err(e) => {
                eprintln!("[ERROR] {}", e);
            }
        }
    }

    Ok(())
}
<commit_msg>[storescp] replace deprecated function call<commit_after>use std::{
    io::Write,
    net::{TcpListener, TcpStream},
};

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 structopt::StructOpt;

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

    /// Which port to listen on
    #[structopt(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 {
                    println!("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 {
                            println!("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();

    let listen_addr = format!("0.0.0.0:{}", port);
    let listener = TcpListener::bind(&listen_addr).unwrap();
    if verbose {
        println!("listening on: {}", 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) {
                    eprintln!("[ERROR] {}", e);
                }
            }
            Err(e) => {
                eprintln!("[ERROR] {}", e);
            }
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use clap::{Arg, App, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
    app
        .subcommand(SubCommand::with_name("status")
                   .about("Show the current status. Remind of not-yet-done habits, shows upcoming. Default if no command is passed.")
                   .version("0.1")
                   )

        .subcommand(SubCommand::with_name("create")
                   .about("Create a new Habit")
                   .version("0.1")
                   .arg(Arg::with_name("create-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the new habit"))
                   .arg(Arg::with_name("create-date")
                        .index(2)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("DATE")
                        .help("Date when the first instance should be done"))
                   .arg(Arg::with_name("create-date-recurr-spec")
                        .index(3)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("RECURRENCE-SPEC")
                        .help("Spec how the habit should recur (eg: 'weekly', 'monthly', '5days', '12hours')"))
                   .arg(Arg::with_name("create-comment")
                        .index(4)
                        .multiple(true)
                        .required(true)
                        .takes_value(true)
                        .value_name("COMMENT")
                        .help("Comment for the habit"))
                   )

        .subcommand(SubCommand::with_name("delete")
                   .about("Delete a Habit (and its instances)")
                   .version("0.1")
                   .arg(Arg::with_name("delete-instances")
                        .long("instances")
                        .short("I")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("Delete instances as well"))
                   .arg(Arg::with_name("delete-yes")
                        .long("yes")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("Do not ask for confirmation"))
                   .arg(Arg::with_name("delete-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the habit"))
                   )

        .subcommand(SubCommand::with_name("list")
                   .about("List Habits")
                   .version("0.1")
                   .arg(Arg::with_name("list-long")
                        .long("long")
                        .short("l")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("List with details (how many instances)"))
                   )

        .subcommand(SubCommand::with_name("show")
                   .about("Show a Habit and its instances")
                   .version("0.1")
                   .arg(Arg::with_name("show-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the habit to show"))
                   )

        .subcommand(SubCommand::with_name("today")
                   .about("List habits which are due today (default command)")
                   .version("0.1")
                   .arg(Arg::with_name("today-show-next-n")
                        .long("show")
                        .short("s")
                        .multiple(false)
                        .required(false)
                        .takes_value(true)
                        .value_name("N")
                        .help("Show the N next relevant entries. Default = 5"))
                   )

        .subcommand(SubCommand::with_name("done")
                    .about("Mark one or more habits (which are pending) as done")
                    .version("0.1")
                    .arg(Arg::with_name("done-name")
                        .index(1)
                        .multiple(true)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("The names of the habits to be marked as done."))
                    )
}
<commit_msg>Add more details to default command<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use clap::{Arg, App, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
    app
        .subcommand(SubCommand::with_name("status")
                   .about("Show the current status. Remind of not-yet-done habits, shows upcoming. Default if no command is passed. Also alias for 'today --future'")
                   .version("0.1")
                   )

        .subcommand(SubCommand::with_name("create")
                   .about("Create a new Habit")
                   .version("0.1")
                   .arg(Arg::with_name("create-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the new habit"))
                   .arg(Arg::with_name("create-date")
                        .index(2)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("DATE")
                        .help("Date when the first instance should be done"))
                   .arg(Arg::with_name("create-date-recurr-spec")
                        .index(3)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("RECURRENCE-SPEC")
                        .help("Spec how the habit should recur (eg: 'weekly', 'monthly', '5days', '12hours')"))
                   .arg(Arg::with_name("create-comment")
                        .index(4)
                        .multiple(true)
                        .required(true)
                        .takes_value(true)
                        .value_name("COMMENT")
                        .help("Comment for the habit"))
                   )

        .subcommand(SubCommand::with_name("delete")
                   .about("Delete a Habit (and its instances)")
                   .version("0.1")
                   .arg(Arg::with_name("delete-instances")
                        .long("instances")
                        .short("I")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("Delete instances as well"))
                   .arg(Arg::with_name("delete-yes")
                        .long("yes")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("Do not ask for confirmation"))
                   .arg(Arg::with_name("delete-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the habit"))
                   )

        .subcommand(SubCommand::with_name("list")
                   .about("List Habits")
                   .version("0.1")
                   .arg(Arg::with_name("list-long")
                        .long("long")
                        .short("l")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("List with details (how many instances)"))
                   )

        .subcommand(SubCommand::with_name("show")
                   .about("Show a Habit and its instances")
                   .version("0.1")
                   .arg(Arg::with_name("show-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the habit to show"))
                   )

        .subcommand(SubCommand::with_name("today")
                   .about("List habits which are due today (default command)")
                   .version("0.1")
                   .arg(Arg::with_name("today-show-next-n")
                        .long("show")
                        .short("s")
                        .multiple(false)
                        .required(false)
                        .takes_value(true)
                        .value_name("N")
                        .help("Show the N next relevant entries. Default = 5"))
                   )

        .subcommand(SubCommand::with_name("done")
                    .about("Mark one or more habits (which are pending) as done")
                    .version("0.1")
                    .arg(Arg::with_name("done-name")
                        .index(1)
                        .multiple(true)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("The names of the habits to be marked as done."))
                    )
}
<|endoftext|>


<commit_before>#[deriving(Eq)]
enum Value {
	List(~[Value]),
	Atom(~str),
	Str(~str),
	Num(float)
}

fn read_nows(input: &str, start: uint) -> Option<char> {
	input.iter().skip(start).skip_while(|&c| c == ' ' || c == '\t').next()
}

fn read_number(input: &str, start: uint) -> Option<(~Value, uint)> {
	let end = input.iter().skip(start).position(|c| c == ' ' || c == ')');
	let pos = match end {
		Some(end) => start+end,
		None => input.len()
	};
	let acc = input.slice(start, pos);
	match std::float::from_str(acc) {
		Some(f) => Some((~Num(f), pos)),
		None => None
	}
}

fn read_list(input: &str, start: uint) -> Option<(~Value, uint)> {
	let mut list = ~[];
	let mut i = start;
	loop {
		match read_value(input, i) {
			Some((v,new_i)) => {
				list.push(*v);
				i = new_i;
			}
			None if read_nows(input, i) == Some(')') => return Some((~List(list), i)),
			None => return None
		}
	}
}

fn read_atom(input: &str, start: uint) -> Option<(~Value, uint)> {
	let atom = std::str::from_chars(input.iter().skip(start).take_while(|&c| c != ' ' && c != ')').to_owned_vec());
	let len = atom.len();
	Some((~Atom(atom), start + len))
}

fn read_value(input: &str, start: uint) -> Option<(~Value, uint)> {
	if(start >= input.len()) {
		return None
	}

	match input[start] as char {
		' ' => read_value(input, start+1),
		'(' => read_list(input, start+1),
		')' => None,
		c if c.is_digit() || c == '.' => read_number(input, start),
		_ => read_atom(input, start)
	}
}

pub fn parse(input: &str) -> Option<Value> {
	/*do io::with_str_reader(input) |r| {
		//let c =
		println("blah: " + input + " -> " + read_token(r));
		List(~[])
	}*/
	match read_value(input, 0) {
		Some((v,_)) => Some(*v),
		None => None
	}
}

mod test {
	use super::{parse, Value, Num, List, Atom};

	fn parse_some(input: &'static str, expr: Value) {
		match parse(input) {
			Some(ref p) if p == &expr => {}
			Some(ref p) => {
				if(p != &expr) {
					fail!("Expected %?, not %?, for %?", expr, *p, input)
				}
			}
			None => fail!("Got None for %?", input)
		}
	}

	#[test]
	fn test_sexpr() {
		assert_eq!(parse(""), None);
		parse_some("123", Num(123.0));
		parse_some("()", List(~[]));
		parse_some("3.14159265358", Num(3.14159265358));
		parse_some("(hi)", List(~[Atom(~"hi")]));
		parse_some("(1)", List(~[Num(1.0)]));
		parse_some("(hi there)", List(~[Atom(~"hi"), Atom(~"there")]));
		parse_some("(hi (there))", List(~[Atom(~"hi"), List(~[Atom(~"there")])]));
		parse_some("(hi 123456)", List(~[Atom(~"hi"), Num(123456.0)]));
		parse_some("(())", List(~[List(~[])]));
		parse_some("(hi (there (fellow (human-bot!))))",
			List(~[Atom(~"hi"),
				List(~[Atom(~"there"),
					List(~[Atom(~"fellow"),
						List(~[Atom(~"human-bot!")])])])])
		);
	}

	#[test]
	fn test_whitespace() {
		// spaces
		parse_some("  (  1  )  ", List(~[Num(1.0)]));
		parse_some("  (  (  )  )  )", List(~[List(~[])]));

		// newlines
		parse_some("\n\n( \n\n )\n\n", List(~[]));
		parse_some("\n\n(\n\n123\n\n)\n\n", List(~[Num(123.0)]));
	}
}<commit_msg>fix whitespace parsing<commit_after>#[deriving(Eq)]
#[deriving(Clone)]
pub enum Value {
	List(~[Value]),
	Atom(~str),
	Str(~str),
	Num(float)
}

#[inline]
fn isws(c: char) -> bool {
	c == ' ' || c == '\t' || c == '\n'
}

fn read_nows(input: &str, start: uint) -> Option<char> {
	input.iter().skip(start).skip_while(|&c| isws(c)).next()
}

fn read_number(input: &str, start: uint) -> Option<(~Value, uint)> {
	let end = input.iter().skip(start).position(|c| isws(c) || c == ')');
	let pos = match end {
		Some(end) => start+end,
		None => input.len()
	};
	let acc = input.slice(start, pos);
	match std::float::from_str(acc) {
		Some(f) => Some((~Num(f), pos)),
		None => None
	}
}

fn read_list(input: &str, start: uint) -> Option<(~Value, uint)> {
	let mut list = ~[];
	let mut i = start;
	loop {
		match read_value(input, i) {
			Some((v,new_i)) => {
				list.push(*v);
				i = new_i;
			}
			None if read_nows(input, i) == Some(')') => return Some((~List(list), i)),
			None => return None
		}
	}
}

fn read_atom(input: &str, start: uint) -> Option<(~Value, uint)> {
	let atom = std::str::from_chars(input.iter().skip(start).take_while(|&c| !isws(c) && c != ')').to_owned_vec());
	let len = atom.len();
	Some((~Atom(atom), start + len))
}

fn read_value(input: &str, start: uint) -> Option<(~Value, uint)> {
	if(start >= input.len()) {
		return None
	}

	match input[start] as char {
		c if isws(c) => read_value(input, start+1), // ignore whitespace
		'(' => read_list(input, start+1),
		')' => None,
		c if c.is_digit() || c == '.' => read_number(input, start),
		_ => read_atom(input, start)
	}
}

pub fn parse(input: &str) -> Option<Value> {
	/*do io::with_str_reader(input) |r| {
		//let c =
		println("blah: " + input + " -> " + read_token(r));
		List(~[])
	}*/
	match read_value(input, 0) {
		Some((v,_)) => Some(*v),
		None => None
	}
}

mod test {
	use super::{parse, Value, Num, List, Atom};

	fn parse_some(input: &'static str, expr: Value) {
		match parse(input) {
			Some(ref p) if p == &expr => {}
			Some(ref p) => {
				if(p != &expr) {
					fail!("Expected %?, not %?, for %?", expr, *p, input)
				}
			}
			None => fail!("Got None for %?", input)
		}
	}

	#[test]
	fn test_sexpr() {
		assert_eq!(parse(""), None);
		parse_some("123", Num(123.0));
		parse_some("()", List(~[]));
		parse_some("3.14159265358", Num(3.14159265358));
		parse_some("(hi)", List(~[Atom(~"hi")]));
		parse_some("(1)", List(~[Num(1.0)]));
		parse_some("(hi there)", List(~[Atom(~"hi"), Atom(~"there")]));
		parse_some("(hi (there))", List(~[Atom(~"hi"), List(~[Atom(~"there")])]));
		parse_some("(hi 123456)", List(~[Atom(~"hi"), Num(123456.0)]));
		parse_some("(())", List(~[List(~[])]));
		parse_some("(hi (there (fellow (human-bot!))))",
			List(~[Atom(~"hi"),
				List(~[Atom(~"there"),
					List(~[Atom(~"fellow"),
						List(~[Atom(~"human-bot!")])])])])
		);
	}

	#[test]
	fn test_whitespace() {
		// spaces
		parse_some("  (  1  )  ", List(~[Num(1.0)]));
		parse_some("  (  (  )  )  )", List(~[List(~[])]));

		// newlines
		parse_some("\n\n( \n\n )\n\n", List(~[]));
		parse_some("\n\n(\n\n123\n\n)\n\n", List(~[Num(123.0)]));
	}
}<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::ascii::AsciiExt;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;

use radix_trie::Trie;

pub fn load_dictionary() -> Result<Vec<String>, io::Error> {
    let wordfile = try!(File::open("/usr/share/dict/words"));
    let wordreader = BufReader::new(wordfile);
    let mut wordlist = Vec::with_capacity(99171);
    for line in wordreader.lines() {
        let word = try!(line).trim().to_owned();
        if word.contains("'") {
            continue;
        }
        wordlist.push(word);
    }
    Ok(wordlist)
}

lazy_static! {
    static ref DICTIONARY: Vec<String> = load_dictionary()
        .expect("couldn't load dictionary");
}

pub struct Lexicon {
    trees: Vec<Trie<String, ()>>
}

impl Lexicon {
    pub fn build(n: usize) -> Self {
        let mut lexicon = Lexicon { trees: Vec::new() };
        for i in 0..n+1 {
            lexicon.trees.push(compile_n_prefix_tree(i));
        }
        lexicon
    }

    pub fn contains(&self, word: &[char]) -> bool {
        let key: String = word.iter().cloned().collect();
        self.trees[key.len()].get(&key).is_some()
    }
}

pub fn compile_n_prefix_tree(n: usize) -> Trie<String, ()> {
    let mut tree = Trie::new();
    for word in DICTIONARY.iter() {
        if word.len() != n {
            continue;
        }
        let normalized = word.to_ascii_uppercase();
        tree.insert(normalized, ());
    }
    tree
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::DICTIONARY;

    #[test]
    fn concerning_loading_our_dictionary() {
        // Probably some systems will have a different /usr/share/dict/words.
        // Works on my machine!
        assert_eq!(vec!["A", "AOL", "Aachen", "Aaliyah", "Aaron", "Abbas",
                        "Abbasid", "Abbott", "Abby", "Abdul"],
                   DICTIONARY[..10].to_vec());
    }

    #[test]
    fn concerning_compiling_prefix_trees() {
        let tree = compile_n_prefix_tree(6);
        assert_eq!(vec!["AACHEN", "ABACUS", "ABASED", "ABASES", "ABATED"],
                   tree.keys().take(5).collect::<Vec<_>>());
    }

    #[test]
    fn concerning_lexicon_lookup() {
        let lexicon = Lexicon::build(3);
        assert!(lexicon.contains(&['C', 'A', 'T']));
    }

}
<commit_msg>n-dictionary<commit_after>#![allow(dead_code)]

use std::ascii::AsciiExt;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;

use radix_trie::Trie;

pub fn load_dictionary() -> Result<Vec<String>, io::Error> {
    let wordfile = try!(File::open("/usr/share/dict/words"));
    let wordreader = BufReader::new(wordfile);
    let mut wordlist = Vec::with_capacity(99171);
    for line in wordreader.lines() {
        let word = try!(line).trim().to_owned();
        if word.contains("'") {
            continue;
        }
        wordlist.push(word);
    }
    Ok(wordlist)
}

lazy_static! {
    static ref DICTIONARY: Vec<String> = load_dictionary()
        .expect("couldn't load dictionary");
}

pub struct Lexicon {
    trees: Vec<Trie<String, ()>>
}

impl Lexicon {
    pub fn build(n: usize) -> Self {
        let mut lexicon = Lexicon { trees: Vec::new() };
        for i in 0..n+1 {
            lexicon.trees.push(compile_n_prefix_tree(i));
        }
        lexicon
    }

    pub fn contains(&self, word: &[char]) -> bool {
        let key: String = word.iter().cloned().collect();
        self.trees[key.len()].get(&key).is_some()
    }

    pub fn n_dictionary(&self, n: usize) -> Vec<String> {
        return self.trees[n].keys().cloned().collect()
    }
}

pub fn compile_n_prefix_tree(n: usize) -> Trie<String, ()> {
    let mut tree = Trie::new();
    for word in DICTIONARY.iter() {
        if word.len() != n {
            continue;
        }
        let normalized = word.to_ascii_uppercase();
        tree.insert(normalized, ());
    }
    tree
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::DICTIONARY;

    #[test]
    fn concerning_loading_our_dictionary() {
        // Probably some systems will have a different /usr/share/dict/words.
        // Works on my machine!
        assert_eq!(vec!["A", "AOL", "Aachen", "Aaliyah", "Aaron", "Abbas",
                        "Abbasid", "Abbott", "Abby", "Abdul"],
                   DICTIONARY[..10].to_vec());
    }

    #[test]
    fn concerning_compiling_prefix_trees() {
        let tree = compile_n_prefix_tree(6);
        assert_eq!(vec!["AACHEN", "ABACUS", "ABASED", "ABASES", "ABATED"],
                   tree.keys().take(5).collect::<Vec<_>>());
    }

    #[test]
    fn concerning_lexicon_lookup() {
        let lexicon = Lexicon::build(3);
        assert!(lexicon.contains(&['C', 'A', 'T']));
    }

    #[test]
    fn concerning_n_dictionaries() {
        let lexicon = Lexicon::build(3);
        assert_eq!(vec!["ABE", "ACE", "ACT", "ADA", "ADD"],
                   lexicon.n_dictionary(3).iter().take(5).collect::<Vec<_>>());
    }

}
<|endoftext|>


<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 libc;
use std::cmp;
use std::mem;
use std::ptr;
use std::slice;

use super::buffer::*;
use super::datatypes::*;
use super::memory::*;

/// Buffer builder with zero-copy build method
pub struct Builder<T>
where
    T: ArrowPrimitiveType,
{
    data: *mut T,
    len: usize,
    capacity: usize,
}

impl<T> Builder<T>
where
    T: ArrowPrimitiveType,
{
    /// Creates a builder with a default capacity
    pub fn new() -> Self {
        Builder::with_capacity(64)
    }

    /// Creates a builder with a fixed capacity
    pub fn with_capacity(capacity: usize) -> Self {
        let sz = mem::size_of::<T>();
        let buffer = allocate_aligned((capacity * sz) as i64).unwrap();
        Builder {
            len: 0,
            capacity,
            data: buffer as *mut T,
        }
    }

    /// Get the number of elements in the builder
    pub fn len(&self) -> usize {
        self.len
    }

    /// Get the capacity of the builder (number of elements)
    pub fn capacity(&self) -> usize {
        self.capacity
    }

    /// Get the internal byte-aligned memory buffer as a mutable slice
    pub fn slice_mut(&mut self, start: usize, end: usize) -> &mut [T] {
        assert!(
            end <= self.capacity as usize,
            "the end of the slice must be within the capacity"
        );
        assert!(
            start <= end,
            "the start of the slice cannot exceed the end of the slice"
        );
        unsafe {
            slice::from_raw_parts_mut(self.data.offset(start as isize), (end - start) as usize)
        }
    }

    /// Override the length
    pub fn set_len(&mut self, len: usize) {
        self.len = len;
    }

    /// Push a value into the builder, growing the internal buffer as needed
    pub fn push(&mut self, v: T) {
        assert!(!self.data.is_null(), "cannot push onto uninitialized data");
        if self.len == self.capacity {
            // grow capacity by 64 bytes or double the current capacity, whichever is greater
            let new_capacity = cmp::max(64, self.capacity * 2);
            self.grow(new_capacity);
        }
        assert!(self.len < self.capacity, "new length exceeds capacity");
        unsafe {
            *self.data.offset(self.len as isize) = v;
        }
        self.len += 1;
    }

    /// Set a value at a slot in the allocated memory without adjusting the length
    pub fn set(&mut self, i: usize, v: T) {
        assert!(
            !self.data.is_null(),
            "cannot set value if data is uninitialized"
        );
        assert!(i < self.capacity, "index exceeds capacity");
        unsafe {
            *self.data.offset(i as isize) = v;
        }
    }

    /// push a slice of type T, growing the internal buffer as needed
    pub fn push_slice(&mut self, slice: &[T]) {
        self.reserve(slice.len());
        let sz = mem::size_of::<T>();
        unsafe {
            libc::memcpy(
                self.data.offset(self.len() as isize) as *mut libc::c_void,
                slice.as_ptr() as *const libc::c_void,
                slice.len() * sz,
            );
        }
        self.len += slice.len();
    }

    /// Reserve memory for n elements of type T
    pub fn reserve(&mut self, n: usize) {
        if self.len + n > self.capacity {
            let new_capacity = cmp::max(self.capacity * 2, n);
            self.grow(new_capacity);
        }
    }

    /// Grow the buffer to the new size n (number of elements of type T)
    fn grow(&mut self, new_capacity: usize) {
        let sz = mem::size_of::<T>();
        let old_buffer = self.data;
        let new_buffer = allocate_aligned((new_capacity * sz) as i64).unwrap();
        unsafe {
            libc::memcpy(
                new_buffer as *mut libc::c_void,
                old_buffer as *const libc::c_void,
                self.len * sz,
            );
        }
        self.capacity = new_capacity;
        self.data = new_buffer as *mut T;
        free_aligned(old_buffer as *const u8);
    }

    /// Build a Buffer from the existing memory
    pub fn finish(&mut self) -> Buffer {
        assert!(!self.data.is_null(), "data has not been initialized");
        let p = self.data;
        self.data = ptr::null_mut(); // ensure builder cannot be re-used
        Buffer::from_raw_parts(p as *mut u8, self.len)
    }
}

impl<T> Drop for Builder<T>
where
    T: ArrowPrimitiveType,
{
    fn drop(&mut self) {
        if !self.data.is_null() {
            free_aligned(self.data as *const u8);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_builder_i32_empty() {
        let mut b: Builder<i32> = Builder::with_capacity(5);
        let a = b.finish();
        assert_eq!(0, a.len());
    }

    #[test]
    fn test_builder_i32_alloc_zero_bytes() {
        let mut b: Builder<i32> = Builder::with_capacity(0);
        b.push(123);
        let a = b.finish();
        assert_eq!(1, a.len());
    }

    #[test]
    fn test_builder_i32() {
        let mut b: Builder<i32> = Builder::with_capacity(5);
        for i in 0..5 {
            b.push(i);
        }
        let a = b.finish();
        assert_eq!(5, a.len());
    }

    #[test]
    fn test_builder_i32_grow_buffer() {
        let mut b: Builder<i32> = Builder::with_capacity(2);
        for i in 0..5 {
            b.push(i);
        }
        let a = b.finish();
        assert_eq!(5, a.len());
    }

    #[test]
    fn test_reserve() {
        let mut b: Builder<u8> = Builder::with_capacity(2);
        assert_eq!(2, b.capacity());
        b.reserve(2);
        assert_eq!(2, b.capacity());
        b.reserve(3);
        assert_eq!(4, b.capacity());
    }

    #[test]
    fn test_push_slice() {
        let mut b: Builder<u8> = Builder::new();
        b.push_slice("Hello, ".as_bytes());
        b.push_slice("World!".as_bytes());
        let buffer = b.finish();
        assert_eq!(13, buffer.len());
    }

    #[test]
    fn test_slice_empty_at_end() {
        let mut b: Builder<u8> = Builder::with_capacity(2);
        let s = b.slice_mut(2, 2);
        assert_eq!(0, s.len());
    }

    #[test]
    #[should_panic(expected = "the end of the slice must be within the capacity")]
    fn test_slice_start_out_of_bounds() {
        let mut b: Builder<u8> = Builder::with_capacity(2);
        b.slice_mut(3, 3); // should panic
    }

    #[test]
    #[should_panic(expected = "the end of the slice must be within the capacity")]
    fn test_slice_end_out_of_bounds() {
        let mut b: Builder<u8> = Builder::with_capacity(2);
        b.slice_mut(0, 3); // should panic
    }

    #[test]
    #[should_panic(expected = "the start of the slice cannot exceed the end of the slice")]
    fn test_slice_end_before_start() {
        let mut b: Builder<u8> = Builder::with_capacity(2);
        b.slice_mut(1, 0); // should panic
    }
}
<commit_msg>ARROW-3398: [Rust] Update existing Builder to use MutableBuffer internally<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.

//! Defines a `BufferBuilder` capable of creating a `Buffer` which can be used as an internal
//! buffer in an `ArrayData` object.

use std::io::Write;
use std::marker::PhantomData;
use std::mem;

use super::buffer::*;
use super::datatypes::*;
use error::{ArrowError, Result};

/// Buffer builder with zero-copy build method
pub struct BufferBuilder<T>
where
    T: ArrowPrimitiveType,
{
    buffer: MutableBuffer,
    len: i64,
    _marker: PhantomData<T>,
}

impl<T> BufferBuilder<T>
where
    T: ArrowPrimitiveType,
{
    /// Creates a builder with a fixed initial capacity
    pub fn new(capacity: i64) -> Self {
        let buffer = MutableBuffer::new(capacity as usize * mem::size_of::<T>());
        Self {
            buffer,
            len: 0,
            _marker: PhantomData,
        }
    }

    /// Returns the number of array elements (slots) in the builder
    pub fn len(&self) -> i64 {
        self.len
    }

    /// Returns the current capacity of the builder (number of elements)
    pub fn capacity(&self) -> i64 {
        let byte_capacity = self.buffer.capacity();
        (byte_capacity / mem::size_of::<T>()) as i64
    }

    /// Push a value into the builder, growing the internal buffer as needed
    pub fn push(&mut self, v: T) -> Result<()> {
        self.reserve(1)?;
        self.write_bytes(v.to_byte_slice(), 1)
    }

    /// Push a slice of type T, growing the internal buffer as needed
    pub fn push_slice(&mut self, slice: &[T]) -> Result<()> {
        let array_slots = slice.len() as i64;
        self.reserve(array_slots)?;
        self.write_bytes(slice.to_byte_slice(), array_slots)
    }

    /// Reserve memory for n elements of type T
    pub fn reserve(&mut self, n: i64) -> Result<()> {
        let new_capacity = self.len + n;
        if new_capacity > self.capacity() {
            return self.grow(new_capacity);
        }
        Ok(())
    }

    /// Grow the internal buffer to `new_capacity`, where `new_capacity` is the capacity in
    /// elements of type T
    fn grow(&mut self, new_capacity: i64) -> Result<()> {
        let byte_capacity = mem::size_of::<T>() * new_capacity as usize;
        self.buffer.resize(byte_capacity)
    }

    /// Build an immutable `Buffer` from the existing internal `MutableBuffer`'s memory
    pub fn finish(self) -> Buffer {
        self.buffer.freeze()
    }

    /// Writes a byte slice to the underlying buffer and updates the `len`, i.e. the number array
    /// elements in the builder.  Also, converts the `io::Result` required by the `Write` trait
    /// to the Arrow `Result` type.
    fn write_bytes(&mut self, bytes: &[u8], len_added: i64) -> Result<()> {
        let write_result = self.buffer.write(bytes);
        // `io::Result` has many options one of which we use, so pattern matching is overkill here
        if write_result.is_err() {
            Err(ArrowError::MemoryError(
                "Could not write to Buffer, not big enough".to_string(),
            ))
        } else {
            self.len += len_added;
            Ok(())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_builder_i32_empty() {
        let b = BufferBuilder::<i32>::new(5);
        assert_eq!(0, b.len());
        assert_eq!(16, b.capacity());
        let a = b.finish();
        assert_eq!(0, a.len());
    }

    #[test]
    fn test_builder_i32_alloc_zero_bytes() {
        let mut b = BufferBuilder::<i32>::new(0);
        b.push(123).unwrap();
        let a = b.finish();
        assert_eq!(4, a.len());
    }

    #[test]
    fn test_builder_i32() {
        let mut b = BufferBuilder::<i32>::new(5);
        for i in 0..5 {
            b.push(i).unwrap();
        }
        assert_eq!(16, b.capacity());
        let a = b.finish();
        assert_eq!(20, a.len());
    }

    #[test]
    fn test_builder_i32_grow_buffer() {
        let mut b = BufferBuilder::<i32>::new(2);
        assert_eq!(16, b.capacity());
        for i in 0..20 {
            b.push(i).unwrap();
        }
        assert_eq!(32, b.capacity());
        let a = b.finish();
        assert_eq!(80, a.len());
    }

    #[test]
    fn test_reserve() {
        let mut b = BufferBuilder::<u8>::new(2);
        assert_eq!(64, b.capacity());
        b.reserve(64).unwrap();
        assert_eq!(64, b.capacity());
        b.reserve(65).unwrap();
        assert_eq!(128, b.capacity());

        let mut b = BufferBuilder::<i32>::new(2);
        assert_eq!(16, b.capacity());
        b.reserve(16).unwrap();
        assert_eq!(16, b.capacity());
        b.reserve(17).unwrap();
        assert_eq!(32, b.capacity());
    }

    #[test]
    fn test_push_slice() {
        let mut b = BufferBuilder::<u8>::new(0);
        b.push_slice("Hello, ".as_bytes()).unwrap();
        b.push_slice("World!".as_bytes()).unwrap();
        let buffer = b.finish();
        assert_eq!(13, buffer.len());

        let mut b = BufferBuilder::<i32>::new(0);
        b.push_slice(&[32, 54]).unwrap();
        let buffer = b.finish();
        assert_eq!(8, buffer.len());
    }

    #[test]
    fn test_write_bytes() {
        let mut b = BufferBuilder::<bool>::new(4);
        let bytes = [false, true, false, true].to_byte_slice();
        b.write_bytes(bytes, 4).unwrap();
        assert_eq!(4, b.len());
        assert_eq!(64, b.capacity());
        let buffer = b.finish();
        assert_eq!(4, buffer.len());
    }

    #[test]
    #[should_panic(expected = "Could not write to Buffer, not big enough")]
    fn test_write_too_many_bytes() {
        let mut b = BufferBuilder::<bool>::new(0);
        let bytes = [false, true, false, true].to_byte_slice();
        b.write_bytes(bytes, 4).unwrap();
    }
}
<|endoftext|>