<commit_before>use std::io::BufReader;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::env;

fn main() {
    let tab: Vec<_> = env::args().collect();

    println!("{:?}", &tab[1..]);

    assert_ne!(tab.len(), 2);

    let mut f = File::open(&tab[0]).unwrap();
    let mut f = BufReader::new(f);
    let mut f2 = File::open(&tab[1]).unwrap();
    let mut f2 = BufReader::new(f);
    let mut counter = 0;
    for line in f.lines() {
        if line != f2.lines() {
            counter +=1;
        }
    }
    println!("{} of differences between {:?}", counter, &tab[1..]);
}
<commit_msg>use difference crate<commit_after>extern crate difference;
use difference::Changeset;
use std::fs::File;
use std::io::prelude::*;
use std::env;

fn main() {
    let tab: Vec<_> = env::args().collect();

    println!("{:?}", &tab[1..]);

    assert_ne!(tab.len(), 2);

    let mut f = File::open(&tab[0]).unwrap();
    let mut buffer = String::new();
    f.read_to_string(&mut buffer).unwrap();
    let mut f2 = File::open(&tab[1]).unwrap();
    let mut buffer2 = String::new();
    f2.read_to_string(&mut buffer2).unwrap();

    let changeset = Changeset::new(buffer.as_ref(), buffer2.as_ref(), "");

    println!("{}", changeset);
}
<|endoftext|>


<commit_before>// Global participant list.
//
// The global participant list is an intrustive list in which items are lazily removed on traversal
// (after being "logically" deleted by becoming inactive).

use std::{ops, mem};
use std::sync::atomic;

use epoch::{Atomic, Guard};
use epoch::participant::Participant;
use CachePadded;

/// A participant node.
///
/// The data is cache padded to avoid cache line racing.
#[derive(Debug)]
pub struct ParticipantNode(CachePadded<Participant>);

impl Default for ParticipantNode {
    fn default() -> ParticipantNode {
        ParticipantNode(CachePadded::new(Participant::default()))
    }
}

impl ops::Deref for ParticipantNode {
    type Target = Participant;
    fn deref(&self) -> &Participant {
        &self.0
    }
}

impl ops::DerefMut for ParticipantNode {
    fn deref_mut(&mut self) -> &mut Participant {
        &mut self.0
    }
}

/// A thread-safe list of threads participating in epoch management.
///
/// Currently implemented like a Treiber stack.
#[derive(Debug, Default)]
pub struct Participants {
    /// The head node.
    head: Atomic<ParticipantNode>,
}

impl Participants {
    // TODO: Remove this cfg when `const fn` is stabilized.
    /// Create an empty list of participants.
    #[cfg(feature = "nightly")]
    pub const fn new() -> Participants {
        Participants { head: Atomic::null() }
    }

    /// Enroll the current thread into the list.
    ///
    /// This adds the current thread to the list in epoch management by adding a new `Particpant`
    /// record to the global list.
    pub fn enroll(&self) -> *const Participant {
        // The new list.
        let mut participant = Box::new(ParticipantNode::default());

        // We ultimately use epoch tracking to free `Participant` nodes, but we can't actually
        // enter an epoch here, so fake it; we know the node can't be removed until marked inactive
        // anyway.
        let fake_guard = ();
        let guard: &'static Guard = unsafe { mem::transmute(&fake_guard) };

        loop {
            // Load the head of the participant list we're traversing.
            let head = self.head.load(atomic::Ordering::Relaxed, guard);
            // Move the head to the tail of the new list, which we will store.
            participant.next.store_shared(head, atomic::Ordering::Relaxed);

            // To solve the ABA problem, we must use CAS, testing against the loaded head.
            match self.head.compare_and_set_ref(head, participant, atomic::Ordering::Release, guard) {
                Ok(shared) => {
                    // It succeeded and the new list is now placed at `self`.

                    // We cast to `Participant` when we return.
                    // FIXME: This is an ugly ugly hack.
                    let shared: &Participant = &shared;
                    return shared;
                }
                Err(owned) => {
                    // It failed. Put back the value and retry.
                    participant = owned;
                }
            }
        }
    }

    /// Get an iterator over the participants.
    // FIXME: For some reason, removing these lifetimes breaks the code.
    pub fn iter<'a>(&'a self, g: &'a Guard) -> Iter<'a> {
        Iter {
            guard: g,
            next: &self.head,
            first: true,
        }
    }
}

/// An iterator over items of a participant list.
#[derive(Debug)]
pub struct Iter<'a> {
    // Pin to an epoch.
    //
    // This ensures that we can free inactive nodes.
    guard: &'a Guard,
    /// The next node.
    next: &'a Atomic<ParticipantNode>,
    // Has `self.next()` **not** been called before?
    first: bool,
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a Participant;
    fn next(&mut self) -> Option<&'a Participant> {
        // Load the next node.
        let mut cur = self.next.load(if self.first {
            // an Acquire read is needed only for the first read, due to release
            // sequences
            atomic::Ordering::Acquire
        } else { atomic::Ordering::Relaxed }, self.guard);

        // Find the next available. node
        while let Some(n) = cur {
            // Attempt to clean up inactive nodes.
            if !n.active.load(atomic::Ordering::Relaxed) {
                // Go to the next node and repeat.
                cur = n.next.load(atomic::Ordering::Relaxed, self.guard);

                // TODO: Actually reclaim inactive participants!
            } else {
                // Go to the next node.
                self.next = &n.next;

                return Some(&n);
            }
        }

        // If the loop was finished without returning, no more nodes are to be found.
        None
    }
}
<commit_msg>Fix bug in `participants::Participant::Iter<'a>` noticed by dbaupp.<commit_after>// Global participant list.
//
// The global participant list is an intrustive list in which items are lazily removed on traversal
// (after being "logically" deleted by becoming inactive).

use std::{ops, mem};
use std::sync::atomic;

use epoch::{Atomic, Guard};
use epoch::participant::Participant;
use CachePadded;

/// A participant node.
///
/// The data is cache padded to avoid cache line racing.
#[derive(Debug)]
pub struct ParticipantNode(CachePadded<Participant>);

impl Default for ParticipantNode {
    fn default() -> ParticipantNode {
        ParticipantNode(CachePadded::new(Participant::default()))
    }
}

impl ops::Deref for ParticipantNode {
    type Target = Participant;
    fn deref(&self) -> &Participant {
        &self.0
    }
}

impl ops::DerefMut for ParticipantNode {
    fn deref_mut(&mut self) -> &mut Participant {
        &mut self.0
    }
}

/// A thread-safe list of threads participating in epoch management.
///
/// Currently implemented like a Treiber stack.
#[derive(Debug, Default)]
pub struct Participants {
    /// The head node.
    head: Atomic<ParticipantNode>,
}

impl Participants {
    // TODO: Remove this cfg when `const fn` is stabilized.
    /// Create an empty list of participants.
    #[cfg(feature = "nightly")]
    pub const fn new() -> Participants {
        Participants { head: Atomic::null() }
    }

    /// Enroll the current thread into the list.
    ///
    /// This adds the current thread to the list in epoch management by adding a new `Particpant`
    /// record to the global list.
    pub fn enroll(&self) -> *const Participant {
        // The new list.
        let mut participant = Box::new(ParticipantNode::default());

        // We ultimately use epoch tracking to free `Participant` nodes, but we can't actually
        // enter an epoch here, so fake it; we know the node can't be removed until marked inactive
        // anyway.
        let fake_guard = ();
        let guard: &'static Guard = unsafe { mem::transmute(&fake_guard) };

        loop {
            // Load the head of the participant list we're traversing.
            let head = self.head.load(atomic::Ordering::Relaxed, guard);
            // Move the head to the tail of the new list, which we will store.
            participant.next.store_shared(head, atomic::Ordering::Relaxed);

            // To solve the ABA problem, we must use CAS, testing against the loaded head.
            match self.head.compare_and_set_ref(head, participant, atomic::Ordering::Release, guard) {
                Ok(shared) => {
                    // It succeeded and the new list is now placed at `self`.

                    // We cast to `Participant` when we return.
                    // FIXME: This is an ugly ugly hack.
                    let shared: &Participant = &shared;
                    return shared;
                }
                Err(owned) => {
                    // It failed. Put back the value and retry.
                    participant = owned;
                }
            }
        }
    }

    /// Get an iterator over the participants.
    // FIXME: For some reason, removing these lifetimes breaks the code.
    pub fn iter<'a>(&'a self, g: &'a Guard) -> Iter<'a> {
        Iter {
            guard: g,
            next: &self.head,
            first: true,
        }
    }
}

/// An iterator over items of a participant list.
#[derive(Debug)]
pub struct Iter<'a> {
    // Pin to an epoch.
    //
    // This ensures that we can free inactive nodes.
    guard: &'a Guard,
    /// The next node.
    next: &'a Atomic<ParticipantNode>,
    // Has `self.next()` **not** been called before?
    first: bool,
}

impl<'a> Iterator for Iter<'a> {
    type Item = &'a Participant;
    fn next(&mut self) -> Option<&'a Participant> {
        // Load the next node.
        let mut cur = self.next.load(if self.first {
            // Now that the method has been called, it should no longer be `true`.
            self.first = false;
            // An `Acquire` read is needed only for the first read, due to release sequences.
            atomic::Ordering::Acquire
        } else { atomic::Ordering::Relaxed }, self.guard);

        // Find the next available. node
        while let Some(n) = cur {
            // Attempt to clean up inactive nodes.
            if !n.active.load(atomic::Ordering::Relaxed) {
                // Go to the next node and repeat.
                cur = n.next.load(atomic::Ordering::Relaxed, self.guard);

                // TODO: Actually reclaim inactive participants!
            } else {
                // Go to the next node.
                self.next = &n.next;

                return Some(&n);
            }
        }

        // If the loop was finished without returning, no more nodes are to be found.
        None
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! FastQ reading and writing.
//!
//! # Example
//!
//! ```
//! use std::io;
//! use bio::io::fastq;
//! let reader = fastq::Reader::new(io::stdin());
//! ```

use std::io;
use std::io::prelude::*;
use std::ascii::AsciiExt;
use std::fs;
use std::fmt;
use std::path::Path;
use std::convert::AsRef;

use utils::TextSlice;

/// A FastQ reader.
pub struct Reader<R: io::Read> {
    reader: io::BufReader<R>,
    sep_line: String,
}

impl Reader<fs::File> {
    /// Read from a given file.
    pub fn from_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        fs::File::open(path).map(Reader::new)
    }
}

impl<R: io::Read> Reader<R> {
    /// Read from a given `io::Read`.
    pub fn new(reader: R) -> Self {
        Reader {
            reader: io::BufReader::new(reader),
            sep_line: String::new(),
        }
    }

    /// Read into a given record.
    /// Returns an error if the record in incomplete or syntax is violated.
    /// The content of the record can be checked via the record object.
    pub fn read(&mut self, record: &mut Record) -> io::Result<()> {
        record.clear();
        try!(self.reader.read_line(&mut record.header));

        if !record.header.is_empty() {
            if !record.header.starts_with('@') {
                return Err(io::Error::new(io::ErrorKind::Other, "Expected @ at record start."));
            }
            try!(self.reader.read_line(&mut record.seq));
            try!(self.reader.read_line(&mut self.sep_line));
            try!(self.reader.read_line(&mut record.qual));
            if record.qual.is_empty() {
                return Err(io::Error::new(io::ErrorKind::Other,
                                          "Incomplete record. Each FastQ record has to consist \
                                           of 4 lines: header, sequence, separator and \
                                           qualities."));
            }
        }

        Ok(())
    }

    /// Return an iterator over the records of this FastQ file.
    pub fn records(self) -> Records<R> {
        Records { reader: self }
    }
}

/// A FastQ record.
#[derive(Debug, Clone, Default)]
pub struct Record {
    header: String,
    seq: String,
    qual: String,
}

impl Record {
    /// Create a new, empty FastQ record.
    pub fn new() -> Self {
        Record {
            header: String::new(),
            seq: String::new(),
            qual: String::new(),
        }
    }

    /// Check if record is empty.
    pub fn is_empty(&self) -> bool {
        self.header.is_empty() && self.seq.is_empty() && self.qual.is_empty()
    }

    /// Check validity of FastQ record.
    pub fn check(&self) -> Result<(), &str> {
        if self.id().is_none() {
            return Err("Expecting id for FastQ record.");
        }
        if !self.seq.is_ascii() {
            return Err("Non-ascii character found in sequence.");
        }
        if !self.qual.is_ascii() {
            return Err("Non-ascii character found in qualities.");
        }
        if self.seq().len() != self.qual().len() {
            return Err("Unequal length of sequence an qualities.");
        }

        Ok(())
    }

    /// Return the id of the record.
    pub fn id(&self) -> Option<&str> {
        self.header[1..].trim_right().splitn(2, ' ').nth(0)
    }

    /// Return descriptions if present.
    pub fn desc(&self) -> Option<&str> {
        self.header[1..].trim_right().splitn(2, ' ').nth(1)
    }

    /// Return the sequence of the record.
    pub fn seq(&self) -> TextSlice {
        self.seq.trim_right().as_bytes()
    }

    /// Return the base qualities of the record.
    pub fn qual(&self) -> &[u8] {
        self.qual.trim_right().as_bytes()
    }

    /// Clear the record.
    fn clear(&mut self) {
        self.header.clear();
        self.seq.clear();
        self.qual.clear();
    }
}

impl fmt::Display for Record {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "@{}\n{}\n+\n{}", self.header, self.seq, self.qual)
    }
}

/// An iterator over the records of a FastQ file.
pub struct Records<R: io::Read> {
    reader: Reader<R>,
}

impl<R: io::Read> Iterator for Records<R> {
    type Item = io::Result<Record>;

    fn next(&mut self) -> Option<io::Result<Record>> {
        let mut record = Record::new();
        match self.reader.read(&mut record) {
            Ok(()) if record.is_empty() => None,
            Ok(()) => Some(Ok(record)),
            Err(err) => Some(Err(err)),
        }
    }
}

/// A FastQ writer.
pub struct Writer<W: io::Write> {
    writer: io::BufWriter<W>,
}

impl Writer<fs::File> {
    /// Write to a given file path.
    pub fn to_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        fs::File::create(path).map(Writer::new)
    }
}

impl<W: io::Write> Writer<W> {
    /// Write to a given `io::Write`.
    pub fn new(writer: W) -> Self {
        Writer { writer: io::BufWriter::new(writer) }
    }

    /// Directly write a FastQ record.
    pub fn write_record(&mut self, record: &Record) -> io::Result<()> {
        self.write(record.id().unwrap_or(""),
                   record.desc(),
                   record.seq(),
                   record.qual())
    }

    /// Write a FastQ record with given id, optional description, sequence and qualities.
    pub fn write(&mut self,
                 id: &str,
                 desc: Option<&str>,
                 seq: TextSlice,
                 qual: &[u8])
                 -> io::Result<()> {
        try!(self.writer.write_all(b"@"));
        try!(self.writer.write_all(id.as_bytes()));
        if desc.is_some() {
            try!(self.writer.write_all(b" "));
            try!(self.writer.write_all(desc.unwrap().as_bytes()));
        }
        try!(self.writer.write_all(b"\n"));
        try!(self.writer.write_all(seq));
        try!(self.writer.write_all(b"\n+\n"));
        try!(self.writer.write_all(qual));
        try!(self.writer.write_all(b"\n"));

        Ok(())
    }

    /// Flush the writer, ensuring that everything is written.
    pub fn flush(&mut self) -> io::Result<()> {
        self.writer.flush()
    }
}

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

    const FASTQ_FILE: &'static [u8] = b"@id desc
ACCGTAGGCTGA
+
IIIIIIJJJJJJ
";

    #[test]
    fn test_reader() {
        let reader = Reader::new(FASTQ_FILE);
        let records: Vec<io::Result<Record>> = reader.records().collect();
        assert!(records.len() == 1);
        for res in records {
            let record = res.ok().unwrap();
            assert_eq!(record.check(), Ok(()));
            assert_eq!(record.id(), Some("id"));
            assert_eq!(record.desc(), Some("desc"));
            assert_eq!(record.seq(), b"ACCGTAGGCTGA");
            assert_eq!(record.qual(), b"IIIIIIJJJJJJ");
        }
    }

    #[test]
    fn test_writer() {
        let mut writer = Writer::new(Vec::new());
        writer
            .write("id", Some("desc"), b"ACCGTAGGCTGA", b"IIIIIIJJJJJJ")
            .ok()
            .expect("Expected successful write");
        writer.flush().ok().expect("Expected successful write");
        assert_eq!(writer.writer.get_ref(), &FASTQ_FILE);
    }
}
<commit_msg>Test refactor of fastq parser<commit_after>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! FastQ reading and writing.
//!
//! # Example
//!
//! ```
//! use std::io;
//! use bio::io::fastq;
//! let reader = fastq::Reader::new(io::stdin());
//! ```

use std::io;
use std::io::prelude::*;
use std::ascii::AsciiExt;
use std::fs;
use std::fmt;
use std::path::Path;
use std::convert::AsRef;

use utils::TextSlice;

/// A FastQ reader.
pub struct Reader<R: io::Read> {
    reader: io::BufReader<R>,
    sep_line: String,
}

impl Reader<fs::File> {
    /// Read from a given file.
    pub fn from_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        fs::File::open(path).map(Reader::new)
    }
}

impl<R: io::Read> Reader<R> {
    /// Read from a given `io::Read`.
    pub fn new(reader: R) -> Self {
        Reader {
            reader: io::BufReader::new(reader),
            sep_line: String::new(),
        }
    }

    /// Read into a given record.
    /// Returns an error if the record in incomplete or syntax is violated.
    /// The content of the record can be checked via the record object.
    pub fn read(&mut self, record: &mut Record) -> io::Result<()> {
        record.clear();

        let mut header = String::new();
        try!(self.reader.read_line(&mut header));

        if !header.is_empty() {
            if !header.starts_with('@') {
                return Err(io::Error::new(io::ErrorKind::Other, "Expected @ at record start."));
            }
            record.id = header[1..]
                .trim_right()
                .splitn(2, ' ')
                .nth(0)
                .unwrap_or_default()
                .to_owned();
            record.desc = header[1..]
                .trim_right()
                .splitn(2, ' ')
                .nth(1)
                .unwrap_or_default()
                .to_owned();
            try!(self.reader.read_line(&mut record.seq));
            try!(self.reader.read_line(&mut self.sep_line));
            try!(self.reader.read_line(&mut record.qual));
            if record.qual.is_empty() {
                return Err(io::Error::new(io::ErrorKind::Other,
                                          "Incomplete record. Each FastQ record has to consist \
                                           of 4 lines: header, sequence, separator and \
                                           qualities."));
            }
        }

        Ok(())
    }

    /// Return an iterator over the records of this FastQ file.
    pub fn records(self) -> Records<R> {
        Records { reader: self }
    }
}

/// A FastQ record.
#[derive(Debug, Clone, Default)]
pub struct Record {
    pub id: String,
    pub desc: String,
    pub seq: String,
    pub qual: String,
}

impl Record {
    /// Create a new, empty FastQ record.
    pub fn new() -> Self {
        Record {
            id: String::new(),
            desc: String::new(),
            seq: String::new(),
            qual: String::new(),
        }
    }

    /// Create a new FastQ record from given attributes.
    pub fn from_attrs(id: &str, desc: Option<&str>, seq: TextSlice, qual: &[u8]) -> Self {
        let desc = match desc {
            Some(desc) => desc.to_owned(),
            _ => String::new(),
        };
        Record {
            id: id.to_owned(),
            desc: desc,
            seq: String::from_utf8(seq.to_vec()).unwrap(),
            qual: String::from_utf8(qual.to_vec()).unwrap(),
        }
    }

    /// Check if record is empty.
    pub fn is_empty(&self) -> bool {
        self.id.is_empty() && self.desc.is_empty() && self.seq.is_empty() && self.qual.is_empty()
    }

    /// Check validity of FastQ record.
    pub fn check(&self) -> Result<(), &str> {
        if self.id().is_none() {
            return Err("Expecting id for FastQ record.");
        }
        if !self.seq.is_ascii() {
            return Err("Non-ascii character found in sequence.");
        }
        if !self.qual.is_ascii() {
            return Err("Non-ascii character found in qualities.");
        }
        if self.seq().len() != self.qual().len() {
            return Err("Unequal length of sequence an qualities.");
        }

        Ok(())
    }

    /// Return the id of the record.
    pub fn id(&self) -> Option<&str> {
        Some(&self.id)
        // self.header[1..].trim_right().splitn(2, ' ').nth(0)
    }

    /// Return descriptions if present.
    pub fn desc(&self) -> Option<&str> {
        Some(&self.desc)
        // self.header[1..].trim_right().splitn(2, ' ').nth(1)
    }

    /// Return the sequence of the record.
    pub fn seq(&self) -> TextSlice {
        self.seq.trim_right().as_bytes()
    }

    /// Return the base qualities of the record.
    pub fn qual(&self) -> &[u8] {
        self.qual.trim_right().as_bytes()
    }

    /// Clear the record.
    fn clear(&mut self) {
        self.id.clear();
        self.desc.clear();
        self.seq.clear();
        self.qual.clear();
    }
}

impl fmt::Display for Record {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f,
               "@{} {}\n{}\n+\n{}",
               self.id,
               self.desc,
               self.seq,
               self.qual)
    }
}

/// An iterator over the records of a FastQ file.
pub struct Records<R: io::Read> {
    reader: Reader<R>,
}

impl<R: io::Read> Iterator for Records<R> {
    type Item = io::Result<Record>;

    fn next(&mut self) -> Option<io::Result<Record>> {
        let mut record = Record::new();
        match self.reader.read(&mut record) {
            Ok(()) if record.is_empty() => None,
            Ok(()) => Some(Ok(record)),
            Err(err) => Some(Err(err)),
        }
    }
}

/// A FastQ writer.
pub struct Writer<W: io::Write> {
    writer: io::BufWriter<W>,
}

impl Writer<fs::File> {
    /// Write to a given file path.
    pub fn to_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        fs::File::create(path).map(Writer::new)
    }
}

impl<W: io::Write> Writer<W> {
    /// Write to a given `io::Write`.
    pub fn new(writer: W) -> Self {
        Writer { writer: io::BufWriter::new(writer) }
    }

    /// Directly write a FastQ record.
    pub fn write_record(&mut self, record: &Record) -> io::Result<()> {
        self.write(record.id().unwrap_or(""),
                   record.desc(),
                   record.seq(),
                   record.qual())
    }

    /// Write a FastQ record with given id, optional description, sequence and qualities.
    pub fn write(&mut self,
                 id: &str,
                 desc: Option<&str>,
                 seq: TextSlice,
                 qual: &[u8])
                 -> io::Result<()> {
        try!(self.writer.write_all(b"@"));
        try!(self.writer.write_all(id.as_bytes()));
        if desc.is_some() {
            try!(self.writer.write_all(b" "));
            try!(self.writer.write_all(desc.unwrap().as_bytes()));
        }
        try!(self.writer.write_all(b"\n"));
        try!(self.writer.write_all(seq));
        try!(self.writer.write_all(b"\n+\n"));
        try!(self.writer.write_all(qual));
        try!(self.writer.write_all(b"\n"));

        Ok(())
    }

    /// Flush the writer, ensuring that everything is written.
    pub fn flush(&mut self) -> io::Result<()> {
        self.writer.flush()
    }
}

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

    const FASTQ_FILE: &'static [u8] = b"@id desc
ACCGTAGGCTGA
+
IIIIIIJJJJJJ
";

    #[test]
    fn test_reader() {
        let reader = Reader::new(FASTQ_FILE);
        let records: Vec<io::Result<Record>> = reader.records().collect();
        assert!(records.len() == 1);
        for res in records {
            let record = res.ok().unwrap();
            assert_eq!(record.check(), Ok(()));
            assert_eq!(record.id(), Some("id"));
            assert_eq!(record.desc(), Some("desc"));
            assert_eq!(record.seq(), b"ACCGTAGGCTGA");
            assert_eq!(record.qual(), b"IIIIIIJJJJJJ");
        }
    }

    #[test]
    fn test_writer() {
        let mut writer = Writer::new(Vec::new());
        writer
            .write("id", Some("desc"), b"ACCGTAGGCTGA", b"IIIIIIJJJJJJ")
            .ok()
            .expect("Expected successful write");
        writer.flush().ok().expect("Expected successful write");
        assert_eq!(writer.writer.get_ref(), &FASTQ_FILE);
    }
}
<|endoftext|>


<commit_before>///
/// Tests `TarjanSCC`
///

use crate::mock_graph::arbitrary::{ArbVertexIn, ArbConnectedGraph};
use graphene::core::{Directed, Graph};
use graphene::algo::TarjanSCC;
use crate::mock_graph::utilities::unordered_equivalent_lists_equal;

///
/// Tests that if the graph is made up of a single component, it is found.
///
#[quickcheck]
fn finds_single_component(ArbVertexIn(graph, v): ArbVertexIn<ArbConnectedGraph<Directed>>)
	-> bool
{
	let sccs = TarjanSCC::new(&graph.0, v).collect::<Vec<_>>();

	sccs.len() == 1 &&
		unordered_equivalent_lists_equal( &sccs[0].all_vertices().collect(),
										  &graph.0.all_vertices().collect())
}

<commit_msg>Tested TarjanSCC.<commit_after>///
/// Tests `TarjanSCC`: Tarjan's algorithm for finding strongly connected components.
///

use graphene::{
	algo::{TarjanSCC},
	core::{
		Directed, Graph, Constrainer,
		constraint::{ConnectedGraph, Subgraph},
	},
};
use crate::mock_graph::{
	MockGraph,
	arbitrary::{ArbVertexIn},
};

///
/// Tests that no produced SCC is empty
///
#[quickcheck]
fn produces_non_empty_components(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>) -> bool
{
	for scc in TarjanSCC::new(&graph, v) {
		if scc.all_vertices().count() == 0 {
			return false;
		}
	}
	true
}

///
/// Tests that any SCC returned is actually strongly connected.
///
#[quickcheck]
fn produces_connected_components(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>) -> bool
{
	for scc in TarjanSCC::new(&graph, v) {
		if ConnectedGraph::constrain_single(scc).is_err() {
			return false
		}
	}
	true
}

///
/// Tests that for any SCC pair produced, they are not strongly connected.
///
#[quickcheck]
fn produces_disconnected_components(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>) -> bool
{
	let sccs = TarjanSCC::new(&graph, v).collect::<Vec<_>>();
	let mut scc_iter = sccs.iter();

	while let Some(scc) = scc_iter.next() {
		for scc2 in scc_iter.clone() {
			if scc.reaches(scc2).is_some() {
				if scc2.reaches(scc).is_some() {
					return false;
				}
			}
		}
	}
	true
}

///
/// Tests that all vertices are put inside some produced SCC.
///
#[quickcheck]
fn produces_all_vertices(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>) -> bool
{
	// We simply count the vertices since we have another test
	// for checking that no vertex is reused
	let mut vertex_count = 0;
	for scc in TarjanSCC::new(&graph, v) {
		vertex_count += scc.all_vertices().count();
	}
	vertex_count == graph.all_vertices().count()
}

///
/// Tests that all vertices in the components are from the original graph.
///
#[quickcheck]
fn produces_only_valid_vertices(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>) -> bool
{
	for scc in TarjanSCC::new(&graph, v) {
		for v in scc.all_vertices() {
			if !graph.contains_vertex(v) {
				return false;
			}
		}
	}
	true
}

///
/// Tests that no two produced SCCs share any vertices
///
#[quickcheck]
fn produces_vertex_disjoint_components(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>)
	-> bool
{
	let sccs = TarjanSCC::new(&graph, v).collect::<Vec<_>>();
	let mut scc_iter = sccs.iter();

	while let Some(scc) = scc_iter.next() {
		for scc2 in scc_iter.clone() {
			for v in scc.all_vertices() {
				if scc2.contains_vertex(v) {
					return false;
				}
			}
		}
	}
	true
}

///
/// Tests that the SCCs are produced in some reverse topological order.
/// This is a guarantee of Tarjan's algorithm, which means if we don't do that,
/// we are not implementing it correctly.
///
#[quickcheck]
fn produces_reverse_topological_ordering(ArbVertexIn(graph, v): ArbVertexIn<MockGraph<Directed>>) -> bool
{
	// To test the ordering, we simply check that an earlier-produced component can't reach any
	// later one.
	let sccs = TarjanSCC::new(&graph, v).collect::<Vec<_>>();
	let mut scc_iter = sccs.iter();

	while let Some(scc) = scc_iter.next() {
		for scc2 in scc_iter.clone() {
			if scc.reaches(scc2).is_some() {
				return false;
			}
		}
	}
	true
}
<|endoftext|>


<commit_before>// xfail-test
// error-pattern:ran out of stack
fn main() {
    eat(move ~0);
}

fn eat(
    +a: ~int
) {
    // Prevent this from being optimized to nothing
    eat(move a)
}
<commit_msg>Remove bogus comment<commit_after>// xfail-test
// error-pattern:ran out of stack
fn main() {
    eat(move ~0);
}

fn eat(
    +a: ~int
) {
    eat(move a)
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate num;

use std::mem::replace;
use test::Bencher;
use num::{BigUint, Zero, One, FromPrimitive};

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

fn fib(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        let f2 = f0 + &f1;
        f0 = replace(&mut f1, f2);
    }
    f0
}

#[bench]
fn factorial_100(b: &mut Bencher) {
    b.iter(|| {
        factorial(100);
    });
}

#[bench]
fn fib_100(b: &mut Bencher) {
    b.iter(|| {
        fib(100);
    });
}

#[bench]
fn to_string(b: &mut Bencher) {
    let fac = factorial(100);
    let fib = fib(100);
    b.iter(|| {
        fac.to_string();
    });
    b.iter(|| {
        fib.to_string();
    });
}

#[bench]
fn shr(b: &mut Bencher) {
    let n = { let one : BigUint = One::one(); one << 1000 };
    b.iter(|| {
        let mut m = n.clone();
        for _ in 0..10 {
            m = m >> 1;
        }
    })
}
<commit_msg>Add multiplication/division benchmarks<commit_after>#![feature(test)]

extern crate test;
extern crate num;
extern crate rand;

use std::mem::replace;
use test::Bencher;
use num::{BigUint, Zero, One, FromPrimitive};
use num::bigint::RandBigInt;
use rand::{SeedableRng, StdRng};

fn multiply_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let seed: &[_] = &[1, 2, 3, 4];
    let mut rng: StdRng = SeedableRng::from_seed(seed);

    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x * &y);
}

fn divide_bench(b: &mut Bencher, xbits: usize, ybits: usize) {
    let seed: &[_] = &[1, 2, 3, 4];
    let mut rng: StdRng = SeedableRng::from_seed(seed);

    let x = rng.gen_bigint(xbits);
    let y = rng.gen_bigint(ybits);

    b.iter(|| &x / &y);
}

fn factorial(n: usize) -> BigUint {
    let mut f: BigUint = One::one();
    for i in 1..(n+1) {
        let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
        f = f * bu;
    }
    f
}

fn fib(n: usize) -> BigUint {
    let mut f0: BigUint = Zero::zero();
    let mut f1: BigUint = One::one();
    for _ in 0..n {
        let f2 = f0 + &f1;
        f0 = replace(&mut f1, f2);
    }
    f0
}

#[bench]
fn multiply_0(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 8);
}

#[bench]
fn multiply_1(b: &mut Bencher) {
    multiply_bench(b, 1 << 8, 1 << 16);
}

#[bench]
fn multiply_2(b: &mut Bencher) {
    multiply_bench(b, 1 << 16, 1 << 16);
}

#[bench]
fn divide_0(b: &mut Bencher) {
    divide_bench(b, 1 << 8, 1 << 6);
}

#[bench]
fn divide_1(b: &mut Bencher) {
    divide_bench(b, 1 << 12, 1 << 8);
}

#[bench]
fn divide_2(b: &mut Bencher) {
    divide_bench(b, 1 << 16, 1 << 12);
}

#[bench]
fn factorial_100(b: &mut Bencher) {
    b.iter(|| {
        factorial(100);
    });
}

#[bench]
fn fib_100(b: &mut Bencher) {
    b.iter(|| {
        fib(100);
    });
}

#[bench]
fn to_string(b: &mut Bencher) {
    let fac = factorial(100);
    let fib = fib(100);
    b.iter(|| {
        fac.to_string();
    });
    b.iter(|| {
        fib.to_string();
    });
}

#[bench]
fn shr(b: &mut Bencher) {
    let n = { let one : BigUint = One::one(); one << 1000 };
    b.iter(|| {
        let mut m = n.clone();
        for _ in 0..10 {
            m = m >> 1;
        }
    })
}
<|endoftext|>


<commit_before>#![cfg(test)]

use super::ray_naive::{bishop_attacks_from_sq, rook_attacks_from_sq};
use bb::*;
use square;
use square::*;
use test;

pub fn test_bishop_attacks_from_bb<F: Fn(BB, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_bb(bishop_attacks_from_sq, 0.3);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn test_bishop_attacks_from_sq<F: Fn(Square, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_sq(bishop_attacks_from_sq, 0.3);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn test_rook_attacks_from_bb<F: Fn(BB, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_bb(rook_attacks_from_sq, 0.3);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn test_rook_attacks_from_sq<F: Fn(Square, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_sq(rook_attacks_from_sq, 0.3);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn bench_attacks_from_sq<F: Fn(Square, BB) -> BB>(b: &mut test::Bencher, gen: F) {
    let cases = random_occupancies_from_sq(640, 0.3);

    b.iter(|| -> BB {
        let mut ret = EMPTY;
        for &(sq, occupied) in cases.iter() {
            ret ^= gen(sq, occupied);
        }
        ret
    });
}

pub fn bench_attacks_from_bb<F: Fn(BB, BB) -> BB>(b: &mut test::Bencher, gen: F) {
    let cases = random_occupancies_from_bb(640, 0.3);
    b.iter(|| -> BB {
        let mut ret = EMPTY;

        for &(from, occupied) in cases.iter() {
            ret = ret ^ gen(from, occupied);
        }

        ret
    });
}

fn random_occupancies_from_bb(size: isize, density: f64) -> Vec<(BB, BB)> {
    let mut ret = Vec::new();
    for _ in 0..size {
        let sq1 = Square::random();
        let sq2 = Square::random();
        let from = BB::new(sq1) | BB::new(sq2);
        let occupied = BB::random(density) | from;
        ret.push((from, occupied));
    }
    ret
}

fn random_occupancies_from_sq(size: usize, density: f64) -> Vec<(Square, BB)> {
    let mut ret = Vec::new();
    for i in 0..size {
        let from = Square((i % 64) as square::Internal);
        let occupied = BB::random(density) | BB::new(from);
        ret.push((from, occupied));
    }
    ret
}

fn generate_test_cases_from_sq<F: Fn(Square, BB) -> BB>(
    gen: F,
    density: f64,
) -> Vec<(Square, BB, BB)> {
    let mut cases = Vec::new();
    for i in 0..64 {
        let from = Square::new(i);
        let occupied = BB::random(density) | BB::new(from);
        let expected = gen(from, occupied);
        cases.push((from, occupied, expected));
    }
    cases
}

fn generate_test_cases_from_bb<F: Fn(Square, BB) -> BB>(gen: F, density: f64) -> Vec<(BB, BB, BB)> {
    let mut cases = Vec::new();
    for i in 0..64 {
        let from_a = Square::new(i);
        let from_b = Square::random();
        let from = BB::new(from_a) | BB::new(from_b);
        let occupied = BB::random(density) | from;
        let expected = gen(from_a, occupied) | gen(from_b, occupied);
        cases.push((from, occupied, expected));
    }
    cases
}
<commit_msg>extract TEST_CASE_BOARD_DENSITY as var<commit_after>#![cfg(test)]

use super::ray_naive::{bishop_attacks_from_sq, rook_attacks_from_sq};
use bb::*;
use square;
use square::*;
use test;

const TEST_CASE_BOARD_DENSITY: f64 = 0.3;

pub fn test_bishop_attacks_from_bb<F: Fn(BB, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_bb(bishop_attacks_from_sq, TEST_CASE_BOARD_DENSITY);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn test_bishop_attacks_from_sq<F: Fn(Square, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_sq(bishop_attacks_from_sq, TEST_CASE_BOARD_DENSITY);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn test_rook_attacks_from_bb<F: Fn(BB, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_bb(rook_attacks_from_sq, TEST_CASE_BOARD_DENSITY);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn test_rook_attacks_from_sq<F: Fn(Square, BB) -> BB>(gen: F) {
    let cases = generate_test_cases_from_sq(rook_attacks_from_sq, TEST_CASE_BOARD_DENSITY);

    for (from, occupied, expected) in cases {
        let actual = gen(from, occupied);
        assert_eq!(actual, expected);
    }
}

pub fn bench_attacks_from_sq<F: Fn(Square, BB) -> BB>(b: &mut test::Bencher, gen: F) {
    let cases = random_occupancies_from_sq(640, TEST_CASE_BOARD_DENSITY);

    b.iter(|| -> BB {
        let mut ret = EMPTY;
        for &(sq, occupied) in cases.iter() {
            ret ^= gen(sq, occupied);
        }
        ret
    });
}

pub fn bench_attacks_from_bb<F: Fn(BB, BB) -> BB>(b: &mut test::Bencher, gen: F) {
    let cases = random_occupancies_from_bb(640, TEST_CASE_BOARD_DENSITY);
    b.iter(|| -> BB {
        let mut ret = EMPTY;

        for &(from, occupied) in cases.iter() {
            ret = ret ^ gen(from, occupied);
        }

        ret
    });
}

fn random_occupancies_from_bb(size: isize, density: f64) -> Vec<(BB, BB)> {
    let mut ret = Vec::new();
    for _ in 0..size {
        let sq1 = Square::random();
        let sq2 = Square::random();
        let from = BB::new(sq1) | BB::new(sq2);
        let occupied = BB::random(density) | from;
        ret.push((from, occupied));
    }
    ret
}

fn random_occupancies_from_sq(size: usize, density: f64) -> Vec<(Square, BB)> {
    let mut ret = Vec::new();
    for i in 0..size {
        let from = Square((i % 64) as square::Internal);
        let occupied = BB::random(density) | BB::new(from);
        ret.push((from, occupied));
    }
    ret
}

fn generate_test_cases_from_sq<F: Fn(Square, BB) -> BB>(
    gen: F,
    density: f64,
) -> Vec<(Square, BB, BB)> {
    let mut cases = Vec::new();
    for i in 0..64 {
        let from = Square::new(i);
        let occupied = BB::random(density) | BB::new(from);
        let expected = gen(from, occupied);
        cases.push((from, occupied, expected));
    }
    cases
}

fn generate_test_cases_from_bb<F: Fn(Square, BB) -> BB>(gen: F, density: f64) -> Vec<(BB, BB, BB)> {
    let mut cases = Vec::new();
    for i in 0..64 {
        let from_a = Square::new(i);
        let from_b = Square::random();
        let from = BB::new(from_a) | BB::new(from_b);
        let occupied = BB::random(density) | from;
        let expected = gen(from_a, occupied) | gen(from_b, occupied);
        cases.push((from, occupied, expected));
    }
    cases
}
<|endoftext|>


<commit_before>// perfect_number.rs
// Calulate perfect numbers in Rust
//
// vim: ft=rust sw=4 ts=4
//

// predicate to check for a perfect number
pub fn is_perfect(n: u64) -> bool {
    let mut sum = 0;
    for i in 1..n {
        if (n % i) == 0 {
            sum += i;
        }
    }

    sum == n
}
pub fn is_perfect_opt(n: u64) -> Option<u64> {
    if is_perfect(n) {
        Some(n)
    } else {
        None
    }
}

// calculate all perfect numbers up to given limit
pub fn perfect_numbers(limit: u64) -> Vec<u64> {
    use std::iter::FromIterator;

    let pn: Vec<u64> = Vec::from_iter((1..limit).filter(|&i| is_perfect(i)));

    pn
}
pub fn perfect_numbers_rayon(limit: u64) -> Vec<u64> {
    use rayon::prelude::{IntoParallelIterator, ParallelIterator};

    let res: Vec<_> = (1..limit)
        .into_par_iter()
        .map(is_perfect_opt)
        .filter_map(|i| i)
        .collect();

    res
}

// use an iterator for perfect numbers
pub fn perfect_number_iter(count: usize) -> Vec<u64> {
    use std::iter::FromIterator;

    let pn: Vec<u64> = Vec::from_iter(PerfectNumber::new().take(count));

    pn
}

// Iterator for perfect numbers
pub struct PerfectNumber {
    current: u64,
}

impl PerfectNumber {
    pub fn new() -> PerfectNumber {
        PerfectNumber { current: 0 }
    }
}

impl Iterator for PerfectNumber {
    type Item = u64;

    fn next(&mut self) -> Option<u64> {
        loop {
            self.current += 1;
            if is_perfect(self.current) {
                return Some(self.current);
            }
        }
    }
}

// unit tests
#[cfg(test)]
mod test {
    use crate::perfect_number::*;

    #[test]
    fn test_is_perfect() {
        assert_eq!(is_perfect(1), false);
        assert_eq!(is_perfect(2), false);
        assert_eq!(is_perfect(6), true);
        assert_eq!(is_perfect(7), false);
        assert_eq!(is_perfect(27), false);
        assert_eq!(is_perfect(28), true);
    }

    #[test]
    fn test_is_perfect_opt() {
        assert_eq!(is_perfect_opt(1), None);
        assert_eq!(is_perfect_opt(2), None);
        assert_eq!(is_perfect_opt(6), Some(6));
        assert_eq!(is_perfect_opt(7), None);
        assert_eq!(is_perfect_opt(27), None);
        assert_eq!(is_perfect_opt(28), Some(28));
    }

    #[test]
    fn test_perfect_numbers() {
        assert_eq!(perfect_numbers(100), vec!(6, 28));
        assert_eq!(perfect_number_iter(2), vec!(6, 28));
        assert_eq!(perfect_numbers_rayon(100), vec!(6, 28));
    }
}
<commit_msg>simplify multithreaded variant<commit_after>// perfect_number.rs
// Calulate perfect numbers in Rust
//
// vim: ft=rust sw=4 ts=4
//

// predicate to check for a perfect number
pub fn is_perfect(n: u64) -> bool {
    let mut sum = 0;
    for i in 1..n {
        if (n % i) == 0 {
            sum += i;
        }
    }

    sum == n
}
#[allow(dead_code)]
pub fn is_perfect_opt(n: u64) -> Option<u64> {
    if is_perfect(n) {
        Some(n)
    } else {
        None
    }
}

// calculate all perfect numbers up to given limit
pub fn perfect_numbers(limit: u64) -> Vec<u64> {
    use std::iter::FromIterator;

    let pn: Vec<u64> = Vec::from_iter((1..limit).filter(|&i| is_perfect(i)));

    pn
}
pub fn perfect_numbers_rayon(limit: u64) -> Vec<u64> {
    use rayon::prelude::{IntoParallelIterator, ParallelIterator};

    (1..limit)
        .into_par_iter()
        .filter(|i| is_perfect(*i))
        .collect()
}

// use an iterator for perfect numbers
pub fn perfect_number_iter(count: usize) -> Vec<u64> {
    use std::iter::FromIterator;

    let pn: Vec<u64> = Vec::from_iter(PerfectNumber::new().take(count));

    pn
}

// Iterator for perfect numbers
pub struct PerfectNumber {
    current: u64,
}

impl PerfectNumber {
    pub fn new() -> PerfectNumber {
        PerfectNumber { current: 0 }
    }
}

impl Iterator for PerfectNumber {
    type Item = u64;

    fn next(&mut self) -> Option<u64> {
        loop {
            self.current += 1;
            if is_perfect(self.current) {
                return Some(self.current);
            }
        }
    }
}

// unit tests
#[cfg(test)]
mod test {
    use crate::perfect_number::*;

    #[test]
    fn test_is_perfect() {
        assert_eq!(is_perfect(1), false);
        assert_eq!(is_perfect(2), false);
        assert_eq!(is_perfect(6), true);
        assert_eq!(is_perfect(7), false);
        assert_eq!(is_perfect(27), false);
        assert_eq!(is_perfect(28), true);
    }

    #[test]
    fn test_is_perfect_opt() {
        assert_eq!(is_perfect_opt(1), None);
        assert_eq!(is_perfect_opt(2), None);
        assert_eq!(is_perfect_opt(6), Some(6));
        assert_eq!(is_perfect_opt(7), None);
        assert_eq!(is_perfect_opt(27), None);
        assert_eq!(is_perfect_opt(28), Some(28));
    }

    #[test]
    fn test_perfect_numbers() {
        assert_eq!(perfect_numbers(100), vec!(6, 28));
        assert_eq!(perfect_number_iter(2), vec!(6, 28));
        assert_eq!(perfect_numbers_rayon(100), vec!(6, 28));
    }
}
<|endoftext|>


<commit_before>//! Defines the `FrameBuilder` trait and some default implementations of the trait.

use std::io;
use http::frame::{
    FrameHeader,
    pack_header,
};

/// A trait that provides additional methods for serializing HTTP/2 frames.
///
/// All methods have a default implementation in terms of the `io::Write` API, but types can
/// provide specialized more efficient implementations if possible. This is effectively a
/// workaround for specialization not existing yet in Rust.
pub trait FrameBuilder: io::Write + io::Seek {
    /// Write the given frame header as the next octets (i.e. without moving the cursor to the
    /// beginning of the buffer).
    fn write_header(&mut self, header: FrameHeader) -> io::Result<()> {
        self.write_all(&pack_header(&header))
    }

    /// Overwrite the previously written header, assuming it's the first byte sequence of the
    /// buffer.
    ///
    /// The default implementation seeks to the beginning of the buffer, writes the header, and
    /// then moves the cursor back to its previos position (i.e. offset from the beginning).
    fn overwrite_header(&mut self, header: FrameHeader) -> io::Result<()> {
        let current = try!(self.seek(io::SeekFrom::Current(0)));
        try!(self.seek(io::SeekFrom::Start(0)));
        try!(self.write_header(header));
        try!(self.seek(io::SeekFrom::Start(current)));
        Ok(())
    }

    /// Copy all available bytes from the given `io::Read` instance.
    ///
    /// This method allows poor man's specialization for types that can implement the copy more
    /// efficiently than the `io::copy` function does (i.e. without the intermediate read into a
    /// stack-allocated buffer).
    fn copy_bytes_from(&mut self, provider: &mut io::Read) -> io::Result<u64> {
        io::copy(provider, self)
    }

    /// Write the given number of padding octets.
    ///
    /// The default implementation invokes the underlying Writer's `write` method `padding_length`
    /// times.
    ///
    /// Other `FrameBuilder` implementations could implement it more efficiently (e.g. if it is
    /// known that the `FrameBuilder` is backed by a zeroed buffer, there's no need to write
    /// anything, only increment a cursor/offset).
    fn write_padding(&mut self, padding_length: u8) -> io::Result<()> {
        for _ in 0..padding_length { try!(self.write_all(&[0])); }
        Ok(())
    }
}

impl FrameBuilder for io::Cursor<Vec<u8>> {}

#[cfg(test)]
mod tests {
    use super::FrameBuilder;
    use std::io::{self, Write};
    use http::frame::{pack_header};

    #[test]
    fn test_write_header_empty_buffer() {
        let mut buf = io::Cursor::new(Vec::new());
        let header = (10, 0x1, 0x0, 3);
        let expected = pack_header(&header);

        buf.write_header(header).unwrap();

        let frame = buf.into_inner();
        assert_eq!(frame, expected);
    }

    #[test]
    fn test_write_header_and_payload_empty() {
        let mut buf = io::Cursor::new(Vec::new());
        let header = (10, 0x1, 0x0, 3);
        let expected = {
            let mut buf = Vec::new();
            buf.extend(pack_header(&header).to_vec());
            buf.extend(vec![1, 2, 3, 4]);
            buf
        };

        buf.write_header(header).unwrap();
        buf.write_all(&[1, 2, 3, 4]).unwrap();

        let frame = buf.into_inner();
        assert_eq!(frame, expected);
    }

    #[test]
    fn test_rewrite_header_after_payload() {
        let mut buf = io::Cursor::new(Vec::new());
        let original_header = (10, 0x1, 0x0, 3);
        let actual_header = (5, 0x0, 0x0, 5);
        let expected = {
            let mut buf = Vec::new();
            buf.extend(pack_header(&actual_header).to_vec());
            buf.extend(vec![1, 2, 3, 4]);
            buf
        };

        // Sanity check for the test: the two headers must be different!
        assert!(original_header != actual_header);
        // First one header...
        buf.write_header(original_header).unwrap();
        // Then some payload...
        buf.write_all(&[1, 2, 3]).unwrap();
        // Now change the header!
        buf.overwrite_header(actual_header).unwrap();
        // ...and add some more data to the end
        buf.write_all(&[4]).unwrap();

        let frame = buf.into_inner();
        assert_eq!(frame, expected);
    }

    #[test]
    fn test_write_padding() {
        let mut buf = io::Cursor::new(Vec::new());
        buf.write_padding(5).unwrap();

        assert_eq!(buf.into_inner(), vec![0; 5]);
    }
}
<commit_msg>FrameBuilder: Add `write_u32` method<commit_after>//! Defines the `FrameBuilder` trait and some default implementations of the trait.

use std::io;
use http::frame::{
    FrameHeader,
    pack_header,
};

/// A trait that provides additional methods for serializing HTTP/2 frames.
///
/// All methods have a default implementation in terms of the `io::Write` API, but types can
/// provide specialized more efficient implementations if possible. This is effectively a
/// workaround for specialization not existing yet in Rust.
pub trait FrameBuilder: io::Write + io::Seek {
    /// Write the given frame header as the next octets (i.e. without moving the cursor to the
    /// beginning of the buffer).
    fn write_header(&mut self, header: FrameHeader) -> io::Result<()> {
        self.write_all(&pack_header(&header))
    }

    /// Overwrite the previously written header, assuming it's the first byte sequence of the
    /// buffer.
    ///
    /// The default implementation seeks to the beginning of the buffer, writes the header, and
    /// then moves the cursor back to its previos position (i.e. offset from the beginning).
    fn overwrite_header(&mut self, header: FrameHeader) -> io::Result<()> {
        let current = try!(self.seek(io::SeekFrom::Current(0)));
        try!(self.seek(io::SeekFrom::Start(0)));
        try!(self.write_header(header));
        try!(self.seek(io::SeekFrom::Start(current)));
        Ok(())
    }

    /// Copy all available bytes from the given `io::Read` instance.
    ///
    /// This method allows poor man's specialization for types that can implement the copy more
    /// efficiently than the `io::copy` function does (i.e. without the intermediate read into a
    /// stack-allocated buffer).
    fn copy_bytes_from(&mut self, provider: &mut io::Read) -> io::Result<u64> {
        io::copy(provider, self)
    }

    /// Write the given number of padding octets.
    ///
    /// The default implementation invokes the underlying Writer's `write` method `padding_length`
    /// times.
    ///
    /// Other `FrameBuilder` implementations could implement it more efficiently (e.g. if it is
    /// known that the `FrameBuilder` is backed by a zeroed buffer, there's no need to write
    /// anything, only increment a cursor/offset).
    fn write_padding(&mut self, padding_length: u8) -> io::Result<()> {
        for _ in 0..padding_length { try!(self.write_all(&[0])); }
        Ok(())
    }

    /// Write the given unsigned 32 bit integer to the underlying stream. The integer is written as
    /// four bytes in network endian style.
    fn write_u32(&mut self, num: u32) -> io::Result<()> {
        self.write_all(&[
            (((num >> 24) & 0x000000FF) as u8),
            (((num >> 16) & 0x000000FF) as u8),
            (((num >>  8) & 0x000000FF) as u8),
            (((num >>  0) & 0x000000FF) as u8),
        ])
    }
}

impl FrameBuilder for io::Cursor<Vec<u8>> {}

#[cfg(test)]
mod tests {
    use super::FrameBuilder;
    use std::io::{self, Write};
    use http::frame::{pack_header};

    #[test]
    fn test_write_header_empty_buffer() {
        let mut buf = io::Cursor::new(Vec::new());
        let header = (10, 0x1, 0x0, 3);
        let expected = pack_header(&header);

        buf.write_header(header).unwrap();

        let frame = buf.into_inner();
        assert_eq!(frame, expected);
    }

    #[test]
    fn test_write_header_and_payload_empty() {
        let mut buf = io::Cursor::new(Vec::new());
        let header = (10, 0x1, 0x0, 3);
        let expected = {
            let mut buf = Vec::new();
            buf.extend(pack_header(&header).to_vec());
            buf.extend(vec![1, 2, 3, 4]);
            buf
        };

        buf.write_header(header).unwrap();
        buf.write_all(&[1, 2, 3, 4]).unwrap();

        let frame = buf.into_inner();
        assert_eq!(frame, expected);
    }

    #[test]
    fn test_rewrite_header_after_payload() {
        let mut buf = io::Cursor::new(Vec::new());
        let original_header = (10, 0x1, 0x0, 3);
        let actual_header = (5, 0x0, 0x0, 5);
        let expected = {
            let mut buf = Vec::new();
            buf.extend(pack_header(&actual_header).to_vec());
            buf.extend(vec![1, 2, 3, 4]);
            buf
        };

        // Sanity check for the test: the two headers must be different!
        assert!(original_header != actual_header);
        // First one header...
        buf.write_header(original_header).unwrap();
        // Then some payload...
        buf.write_all(&[1, 2, 3]).unwrap();
        // Now change the header!
        buf.overwrite_header(actual_header).unwrap();
        // ...and add some more data to the end
        buf.write_all(&[4]).unwrap();

        let frame = buf.into_inner();
        assert_eq!(frame, expected);
    }

    #[test]
    fn test_write_padding() {
        let mut buf = io::Cursor::new(Vec::new());
        buf.write_padding(5).unwrap();

        assert_eq!(buf.into_inner(), vec![0; 5]);
    }

    #[test]
    fn test_write_u32() {
        fn get_written(num: u32) -> Vec<u8> {
            let mut buf = io::Cursor::new(Vec::new());
            buf.write_u32(num).unwrap();
            buf.into_inner()
        }

        assert_eq!(get_written(0x0), vec![0, 0, 0, 0]);
        assert_eq!(get_written(0x1), vec![0, 0, 0, 1]);
        assert_eq!(get_written(0x10), vec![0, 0, 0, 0x10]);
        assert_eq!(get_written(0x10AB00CC), vec![0x10, 0xAB, 0, 0xCC]);
        assert_eq!(get_written(0xFFFFFFFF), vec![0xFF, 0xFF, 0xFF, 0xFF]);
        assert_eq!(get_written(0xEFFFFFFF), vec![0xEF, 0xFF, 0xFF, 0xFF]);
        assert_eq!(get_written(0x7FFFFFFF), vec![0x7F, 0xFF, 0xFF, 0xFF]);
        assert_eq!(get_written(0xFFFFFF7F), vec![0xFF, 0xFF, 0xFF, 0x7F]);
    }
}
<|endoftext|>


<commit_before>import vbuf = rustrt.vbuf;
import op = util.operator;

native "rust" mod rustrt {
  type vbuf;
  fn vec_buf[T](vec[T] v) -> vbuf;
  fn vec_len[T](vec[T] v) -> uint;
  /* The T in vec_alloc[T, U] is the type of the vec to allocate.  The
   * U is the type of an element in the vec.  So to allocate a vec[U] we
   * want to invoke this as vec_alloc[vec[U], U]. */
  fn vec_alloc[T, U](uint n_elts) -> vec[U];
  fn refcount[T](vec[T] v) -> uint;
}

fn alloc[T](uint n_elts) -> vec[T] {
  ret rustrt.vec_alloc[vec[T], T](n_elts);
}

type init_op[T] = fn(uint i) -> T;

fn init_fn[T](&init_op[T] op, uint n_elts) -> vec[T] {
  let vec[T] v = alloc[T](n_elts);
  let uint i = n_elts;
  while (i > 0u) {
    i -= 1u;
    v += vec(op(i));
  }
  ret v;
}

fn init_elt[T](&T t, uint n_elts) -> vec[T] {
  /**
   * FIXME (issue #81): should be:
   *
   * fn elt_op[T](&T x, uint i) -> T { ret x; }
   * let init_op[T] inner = bind elt_op[T](t, _);
   * ret init_fn[T](inner, n_elts);
   */
  let vec[T] v = alloc[T](n_elts);
  let uint i = n_elts;
  while (i > 0u) {
    i -= 1u;
    v += vec(t);
  }
  ret v;
}

fn len[T](vec[T] v) -> uint {
  ret rustrt.vec_len[T](v);
}

fn buf[T](vec[T] v) -> vbuf {
  ret rustrt.vec_buf[T](v);
}

// Returns elements from [start..end) from v.
fn slice[T](vec[T] v, int start, int end) -> vec[T] {
  check(0 <= start);
  check(start <= end);
  // FIXME #108: This doesn't work yet.
  //check(end <= int(len[T](v)));
  auto result = alloc[T]((end - start) as uint);
  let mutable int i = start;
  while (i < end) {
    result += vec(v.(i));
    i += 1;
  }
  ret result;
}

// Ought to take mutable &vec[T] v and just mutate it instead of copy
// and return.  Blocking on issue #89 for this.
fn grow[T](mutable vec[T] v, int n, &T initval) -> vec[T] {
  let int i = n;
  while (i > 0) {
    i -= 1;
    v += vec(initval);
  }
  ret v;
}

fn map[T,U](&op[T,U] f, &vec[T] v) -> vec[U] {
  // FIXME: should be
  // let vec[U] u = alloc[U](len[T](v));
  // but this does not work presently.
  let vec[U] u = vec();
  for (T ve in v) {
    u += vec(f(ve));
  }
  ret u;
}

<commit_msg>Address _vec.grow FIXME, as issue #89 has been closed.<commit_after>import vbuf = rustrt.vbuf;
import op = util.operator;

native "rust" mod rustrt {
  type vbuf;
  fn vec_buf[T](vec[T] v) -> vbuf;
  fn vec_len[T](vec[T] v) -> uint;
  /* The T in vec_alloc[T, U] is the type of the vec to allocate.  The
   * U is the type of an element in the vec.  So to allocate a vec[U] we
   * want to invoke this as vec_alloc[vec[U], U]. */
  fn vec_alloc[T, U](uint n_elts) -> vec[U];
  fn refcount[T](vec[T] v) -> uint;
}

fn alloc[T](uint n_elts) -> vec[T] {
  ret rustrt.vec_alloc[vec[T], T](n_elts);
}

type init_op[T] = fn(uint i) -> T;

fn init_fn[T](&init_op[T] op, uint n_elts) -> vec[T] {
  let vec[T] v = alloc[T](n_elts);
  let uint i = n_elts;
  while (i > 0u) {
    i -= 1u;
    v += vec(op(i));
  }
  ret v;
}

fn init_elt[T](&T t, uint n_elts) -> vec[T] {
  /**
   * FIXME (issue #81): should be:
   *
   * fn elt_op[T](&T x, uint i) -> T { ret x; }
   * let init_op[T] inner = bind elt_op[T](t, _);
   * ret init_fn[T](inner, n_elts);
   */
  let vec[T] v = alloc[T](n_elts);
  let uint i = n_elts;
  while (i > 0u) {
    i -= 1u;
    v += vec(t);
  }
  ret v;
}

fn len[T](vec[T] v) -> uint {
  ret rustrt.vec_len[T](v);
}

fn buf[T](vec[T] v) -> vbuf {
  ret rustrt.vec_buf[T](v);
}

// Returns elements from [start..end) from v.
fn slice[T](vec[T] v, int start, int end) -> vec[T] {
  check(0 <= start);
  check(start <= end);
  // FIXME #108: This doesn't work yet.
  //check(end <= int(len[T](v)));
  auto result = alloc[T]((end - start) as uint);
  let mutable int i = start;
  while (i < end) {
    result += vec(v.(i));
    i += 1;
  }
  ret result;
}

fn grow[T](&mutable vec[T] v, int n, &T initval) {
  let int i = n;
  while (i > 0) {
    i -= 1;
    v += vec(initval);
  }
}

fn map[T,U](&op[T,U] f, &vec[T] v) -> vec[U] {
  // FIXME: should be
  // let vec[U] u = alloc[U](len[T](v));
  // but this does not work presently.
  let vec[U] u = vec();
  for (T ve in v) {
    u += vec(f(ve));
  }
  ret u;
}

<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::io;

pub struct MMU
{
    pub mem_map: Vec<u8>,
    pub memory_banks: Vec<Vec<u8>>,
    pub cartridge_type: u8,
    pub rom_size: u8,
    pub ram_size: u8,
    pub rom_bank: u8,
    pub banking_mode: u8,
}

impl MMU
{
    pub fn new() -> MMU
    {
        return MMU
        {
            mem_map: vec![0; 0x10000],
            memory_banks: vec![vec![0; 0x4000]; 0x100],
            cartridge_type: 0,
            rom_size: 0x00,
            ram_size: 0x00,
            rom_bank: 1,
            banking_mode: 0,
        }
    }

    pub fn set_to_memory(&mut self, location: usize, value: u8, masked_set: bool)
    {
        let mut rom_flag = false;
        if masked_set
        {
            match self.cartridge_type
            {
                0x00 => (),
                0x01 => rom_flag = self.mbc1_parse(location, value),
                _ => (),
            }
        }
        if !rom_flag
        {
            self.mem_map[location] = value;
        }
    }

    pub fn get_from_memory(&self, location: usize, masked_read: bool) -> u8
    {
        // if masked_read == true && location < 0x8000
        // {
        //     println!("DEBUG: Masked Read Location-{:04x}", location);
        // }
        return self.mem_map[location];
    }

    fn mbc1_parse(&mut self, location: usize, value: u8) -> bool
    {

        match location
        {
            0x0000...0x1FFF =>
            {
                println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                println!("DEBUG: ram enable` {}", value);
                return true;
            },
            0x2000...0x3FFF =>
            {
            //     for i in 0..0x4000
            //     {
            //         self.memory_banks[self.rom_bank as usize][i] = self.mem_map[(i as usize) + 0x4000];
            //     }
            println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                let mut bank = value & 0x1F;
                if bank == 0
                {
                    bank += 1;
                }
                self.rom_bank &= 0xE0;
                self.rom_bank |= bank;
                self.update_rom_bank();
                return true;
            },
            0x4000...0x5FFF =>
            {
                // for i in 0..0x4000
                // {
                //     self.memory_banks[self.rom_bank as usize][i] = self.mem_map[(i as usize) + 0x4000];
                // }
                println!("Value: 0x{:02X} -- {} Location: 0x{:04X}", value, (value & 0x03) << 5 ,location);
                self.rom_bank &= 0x1F;
                if self.banking_mode == 0{
                    self.rom_bank |= ((value & 0x03) << 5);
                }
                self.update_rom_bank();
                return true;
            },
            0x6000...0x7FFF =>
            {
                println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                println!("DEBUG: mode {}", value);
                self.banking_mode = value;
                return true;
            },
            _ =>
            {
                 //println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                 //io::stdin().read_line(&mut String::new());
                 return false;
            },
        }
    }

    fn update_rom_bank(&mut self)
    {
        let bank = self.rom_bank as usize;
        println!("Rom-bank switch: 0x{:02x}", bank);
        for i in 0..0x4000
        {
            self.mem_map[(i as usize) + 0x4000] = self.memory_banks[bank][i];
        }
    }

    pub fn read_gb_file(&self, file_name: &str) -> Vec<u8>
    {
    let mut buffer : Vec<u8> = vec![0; 0x10000];
    let file = File::open(file_name);
    if file.is_ok()
    {
        if file.unwrap().read(&mut buffer).is_ok()
        {
            return buffer;
        }
    }
    return buffer;
    }

    pub fn initialize_cartridge(&mut self, file_name: &str)
    {
        let mut buffer: Vec<u8> = Vec::new();
        let file = File::open(file_name);
        if file.is_ok()
        {
            if file.unwrap().read_to_end(&mut buffer).is_ok()
            {
                self.memory_banks[0] = buffer[0..0x4000].to_vec();
                self.cartridge_type = self.memory_banks[0][0x0147];
                let rom_tag = self.memory_banks[0][0x0148];
                self.rom_size = self.parse_rom_size(rom_tag);
                let ram_tag = self.memory_banks[0][0x0149];
                self.ram_size = self.parse_ram_size(ram_tag);
                if self.rom_size == 0
                {
                    self.memory_banks[1] = buffer[0x4000..0x8000].to_vec();
                }
                else
                {
                    for i in 1..self.rom_size
                    {
                        let start: usize = 0x4000 * (i as usize);
                        let end: usize = 0x4000 * ((i as usize) + 1);
                        self.memory_banks[i as usize] = buffer[start..end].to_vec();
                    }
                }
                for i in 0..0x4000
                {
                    self.mem_map[i] = self.memory_banks[0][i];
                    self.mem_map[(i as usize) + 0x4000] = self.memory_banks[1][i];
                }

            }
        }
    }

    fn parse_rom_size(&mut self, rom_tag: u8) -> u8
    {
        match rom_tag
        {
            0x00 => return 0,
            0x01 => return 4,
            0x02 => return 8,
            0x03 => return 16,
            0x04 => return 32,
            0x05 => return 64,
            0x06 => return 128,
            0x07 => return 256,
            0x52 => return 72,
            0x53 => return 80,
            0x54 => return 96,
            _ => return 0,
        }
    }

    fn parse_ram_size(&mut self, ram_tag: u8) -> u8
    {
        match ram_tag
        {
            0x00 => return 0,
            0x01 => return 2,
            0x02 => return 8,
            0x03 => return 32,
            _ => return 0,
        }
    }
}

#[cfg(test)]
mod mmu_tests
{
    use MMU;

    #[test]
    fn get_and_set_legal_memory_test() {
        let mut mmu = MMU::new();
        mmu.set_to_memory(0x1234, 0xFF, false);
        assert_eq!(mmu.mem_map[0x1234], 0xFF);
        assert_eq!(mmu.get_from_memory(0x1234, false), 0xFF);
    }

    //#[test]
    fn mbc1_test() {
        let mut mmu = MMU::new();
        mmu.cartridge_type = 0x01;

        let memory_locations: Vec<usize> = vec![0x00, 0x2000, 0x3000, 0x3FFF, 0x4000];
        let values: Vec<u8> = vec![0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x03];
        let rom_bank_values: Vec<u8> = vec![0x01, 0x1F, 0x01, 0x1F, 0x61];
        let mem_loc_values: Vec<u8> = vec![0xFF, 0x00, 0x00, 0x00, 0x00];

        for i in 0..memory_locations.len()
        {
            mmu.rom_bank = 0x01;
            mmu.mem_map[memory_locations[i]] = 0;
            mmu.set_to_memory(memory_locations[i], values[i], true);
            assert_eq!(mmu.rom_bank, rom_bank_values[i]);
            assert_eq!(mmu.mem_map[memory_locations[i]], mem_loc_values[i]);
        }
    }

    #[test]
    fn passing_bad_filename_to_read_gb_file_return_empty_vec()
    {
        let mut mmu = MMU::new();
        let return_vector : Vec<u8> = mmu.read_gb_file("");
        assert_eq!(return_vector, vec![0;0x10000]);
    }

    #[test]
    fn initialize_catridge_test()
    {
        let mut mmu = MMU::new();
        mmu.initialize_cartridge("roms/cpu_instrs.gb");
        assert_eq!(mmu.rom_size, 4);
        assert_eq!(mmu.ram_size, 0);
        assert_eq!(mmu.cartridge_type, 1);
        assert_eq!(mmu.memory_banks[0][0x0000], 0x3C);
        assert_eq!(mmu.memory_banks[1][0x0000], 0xC3);
        assert_eq!(mmu.memory_banks[2][0x0000], 0xC3);
        assert_eq!(mmu.memory_banks[3][0x0000], 0xC3);
    }

    #[test]
    fn rom_bank_switch_test()
    {
        let mut mmu = MMU::new();
        mmu.initialize_cartridge("roms/cpu_instrs.gb");
        assert_eq!(mmu.rom_size, 4);
        assert_eq!(mmu.ram_size, 0);
        assert_eq!(mmu.cartridge_type, 1);
        assert_eq!(mmu.mem_map[0x0000], 0x3C);
        assert_eq!(mmu.mem_map[0x4300], 0x3E);
        mmu.mbc1_parse(0x2000, 0x00);
        assert_eq!(mmu.mem_map[0x4300], 0x3E);
        mmu.mbc1_parse(0x2000, 0x02);
        assert_eq!(mmu.mem_map[0x4300], 0xE0);
        mmu.mbc1_parse(0x2000, 0x03);
        assert_eq!(mmu.mem_map[0x4900], 0x72);
        mmu.mbc1_parse(0x2000, 0x00);
        assert_eq!(mmu.mem_map[0x4300], 0x3E);
    }
}<commit_msg>oam dma transfer<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::io;

pub struct MMU
{
    pub mem_map: Vec<u8>,
    pub memory_banks: Vec<Vec<u8>>,
    pub cartridge_type: u8,
    pub rom_size: u8,
    pub ram_size: u8,
    pub rom_bank: u8,
    pub banking_mode: u8,
}

impl MMU
{
    pub fn new() -> MMU
    {
        return MMU
        {
            mem_map: vec![0; 0x10000],
            memory_banks: vec![vec![0; 0x4000]; 0x100],
            cartridge_type: 0,
            rom_size: 0x00,
            ram_size: 0x00,
            rom_bank: 1,
            banking_mode: 0,
        }
    }

    pub fn set_to_memory(&mut self, location: usize, value: u8, masked_set: bool)
    {
        let mut rom_flag = false;
        if masked_set
        {
            if location == 0xFF46
            {
                self.oam_dma_transfer(value);
            }
            match self.cartridge_type
            {
                0x00 => (),
                0x01 => rom_flag = self.mbc1_parse(location, value),
                _ => (),
            }
        }
        if !rom_flag
        {
            self.mem_map[location] = value;
        }
    }

    fn oam_dma_transfer(&mut self, value: u8)
    {
        let start_address = ((value as u16) << 8) as usize;
        for i in 0..0xA0
        {
            self.mem_map[0xFE00 + i] = self.mem_map[start_address + i];
        }
    }

    pub fn get_from_memory(&self, location: usize, masked_read: bool) -> u8
    {
        // if masked_read == true && location < 0x8000
        // {
        //     println!("DEBUG: Masked Read Location-{:04x}", location);
        // }
        return self.mem_map[location];
    }

    fn mbc1_parse(&mut self, location: usize, value: u8) -> bool
    {

        match location
        {
            0x0000...0x1FFF =>
            {
                println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                println!("DEBUG: ram enable` {}", value);
                return true;
            },
            0x2000...0x3FFF =>
            {
            //     for i in 0..0x4000
            //     {
            //         self.memory_banks[self.rom_bank as usize][i] = self.mem_map[(i as usize) + 0x4000];
            //     }
            println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                let mut bank = value & 0x1F;
                if bank == 0
                {
                    bank += 1;
                }
                self.rom_bank &= 0xE0;
                self.rom_bank |= bank;
                self.update_rom_bank();
                return true;
            },
            0x4000...0x5FFF =>
            {
                // for i in 0..0x4000
                // {
                //     self.memory_banks[self.rom_bank as usize][i] = self.mem_map[(i as usize) + 0x4000];
                // }
                println!("Value: 0x{:02X} -- {} Location: 0x{:04X}", value, (value & 0x03) << 5 ,location);
                self.rom_bank &= 0x1F;
                if self.banking_mode == 0{
                    self.rom_bank |= ((value & 0x03) << 5);
                }
                self.update_rom_bank();
                return true;
            },
            0x6000...0x7FFF =>
            {
                println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                println!("DEBUG: mode {}", value);
                self.banking_mode = value;
                return true;
            },
            _ =>
            {
                 //println!("Value: 0x{:02X} Location: 0x{:04X}", value, location);
                 //io::stdin().read_line(&mut String::new());
                 return false;
            },
        }
    }

    fn update_rom_bank(&mut self)
    {
        let bank = self.rom_bank as usize;
        println!("Rom-bank switch: 0x{:02x}", bank);
        for i in 0..0x4000
        {
            self.mem_map[(i as usize) + 0x4000] = self.memory_banks[bank][i];
        }
    }

    pub fn read_gb_file(&self, file_name: &str) -> Vec<u8>
    {
    let mut buffer : Vec<u8> = vec![0; 0x10000];
    let file = File::open(file_name);
    if file.is_ok()
    {
        if file.unwrap().read(&mut buffer).is_ok()
        {
            return buffer;
        }
    }
    return buffer;
    }

    pub fn initialize_cartridge(&mut self, file_name: &str)
    {
        let mut buffer: Vec<u8> = Vec::new();
        let file = File::open(file_name);
        if file.is_ok()
        {
            if file.unwrap().read_to_end(&mut buffer).is_ok()
            {
                self.memory_banks[0] = buffer[0..0x4000].to_vec();
                self.cartridge_type = self.memory_banks[0][0x0147];
                let rom_tag = self.memory_banks[0][0x0148];
                self.rom_size = self.parse_rom_size(rom_tag);
                let ram_tag = self.memory_banks[0][0x0149];
                self.ram_size = self.parse_ram_size(ram_tag);
                if self.rom_size == 0
                {
                    self.memory_banks[1] = buffer[0x4000..0x8000].to_vec();
                }
                else
                {
                    for i in 1..self.rom_size
                    {
                        let start: usize = 0x4000 * (i as usize);
                        let end: usize = 0x4000 * ((i as usize) + 1);
                        self.memory_banks[i as usize] = buffer[start..end].to_vec();
                    }
                }
                for i in 0..0x4000
                {
                    self.mem_map[i] = self.memory_banks[0][i];
                    self.mem_map[(i as usize) + 0x4000] = self.memory_banks[1][i];
                }

            }
        }
    }

    fn parse_rom_size(&mut self, rom_tag: u8) -> u8
    {
        match rom_tag
        {
            0x00 => return 0,
            0x01 => return 4,
            0x02 => return 8,
            0x03 => return 16,
            0x04 => return 32,
            0x05 => return 64,
            0x06 => return 128,
            0x07 => return 256,
            0x52 => return 72,
            0x53 => return 80,
            0x54 => return 96,
            _ => return 0,
        }
    }

    fn parse_ram_size(&mut self, ram_tag: u8) -> u8
    {
        match ram_tag
        {
            0x00 => return 0,
            0x01 => return 2,
            0x02 => return 8,
            0x03 => return 32,
            _ => return 0,
        }
    }
}

#[cfg(test)]
mod mmu_tests
{
    use MMU;

    #[test]
    fn get_and_set_legal_memory_test() {
        let mut mmu = MMU::new();
        mmu.set_to_memory(0x1234, 0xFF, false);
        assert_eq!(mmu.mem_map[0x1234], 0xFF);
        assert_eq!(mmu.get_from_memory(0x1234, false), 0xFF);
    }

    //#[test]
    fn mbc1_test() {
        let mut mmu = MMU::new();
        mmu.cartridge_type = 0x01;

        let memory_locations: Vec<usize> = vec![0x00, 0x2000, 0x3000, 0x3FFF, 0x4000];
        let values: Vec<u8> = vec![0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x03];
        let rom_bank_values: Vec<u8> = vec![0x01, 0x1F, 0x01, 0x1F, 0x61];
        let mem_loc_values: Vec<u8> = vec![0xFF, 0x00, 0x00, 0x00, 0x00];

        for i in 0..memory_locations.len()
        {
            mmu.rom_bank = 0x01;
            mmu.mem_map[memory_locations[i]] = 0;
            mmu.set_to_memory(memory_locations[i], values[i], true);
            assert_eq!(mmu.rom_bank, rom_bank_values[i]);
            assert_eq!(mmu.mem_map[memory_locations[i]], mem_loc_values[i]);
        }
    }

    #[test]
    fn passing_bad_filename_to_read_gb_file_return_empty_vec()
    {
        let mut mmu = MMU::new();
        let return_vector : Vec<u8> = mmu.read_gb_file("");
        assert_eq!(return_vector, vec![0;0x10000]);
    }

    #[test]
    fn initialize_catridge_test()
    {
        let mut mmu = MMU::new();
        mmu.initialize_cartridge("roms/cpu_instrs.gb");
        assert_eq!(mmu.rom_size, 4);
        assert_eq!(mmu.ram_size, 0);
        assert_eq!(mmu.cartridge_type, 1);
        assert_eq!(mmu.memory_banks[0][0x0000], 0x3C);
        assert_eq!(mmu.memory_banks[1][0x0000], 0xC3);
        assert_eq!(mmu.memory_banks[2][0x0000], 0xC3);
        assert_eq!(mmu.memory_banks[3][0x0000], 0xC3);
    }

    #[test]
    fn rom_bank_switch_test()
    {
        let mut mmu = MMU::new();
        mmu.initialize_cartridge("roms/cpu_instrs.gb");
        assert_eq!(mmu.rom_size, 4);
        assert_eq!(mmu.ram_size, 0);
        assert_eq!(mmu.cartridge_type, 1);
        assert_eq!(mmu.mem_map[0x0000], 0x3C);
        assert_eq!(mmu.mem_map[0x4300], 0x3E);
        mmu.mbc1_parse(0x2000, 0x00);
        assert_eq!(mmu.mem_map[0x4300], 0x3E);
        mmu.mbc1_parse(0x2000, 0x02);
        assert_eq!(mmu.mem_map[0x4300], 0xE0);
        mmu.mbc1_parse(0x2000, 0x03);
        assert_eq!(mmu.mem_map[0x4900], 0x72);
        mmu.mbc1_parse(0x2000, 0x00);
        assert_eq!(mmu.mem_map[0x4300], 0x3E);
    }

    #[test]
    fn oam_dma_transfer_test() {
        let mut mmu = MMU::new();
        for i in 0..0xA0
        {
            mmu.mem_map[i] = i as u8;
            mmu.mem_map[0x8000 + i] = i as u8;
        }

        mmu.set_to_memory(0xFF46, 0x00, true);
        for i in 0..0xA0
        {
            assert_eq!(mmu.mem_map[0xFE00+i], i as u8);
        }

        mmu.set_to_memory(0xFF46, 0x01, true);
        for i in 0..0xA0
        {
            assert_eq!(mmu.mem_map[0xFE00+i], 0);
        }

        mmu.set_to_memory(0xFF46, 0x80, true);
        for i in 0..0xA0
        {
            assert_eq!(mmu.mem_map[0xFE00+i], i as u8);
        }
    }
}<|endoftext|>


<commit_before>use std::io::File;
use std::mem;
use std::os;

// https://stackoverflow.com/questions/24633784/is-there-a-gzip-library-available-for-rust

fn pointer_size() -> uint {
    let tmp = 0u8;
    let boxed = box tmp;
    mem::size_of_val(&boxed)
}

fn main() {
    let args = os::args();
    if args.len() != 2 {
        println!("usage: read_blend_file /path/to/file.blend");
    } else {
        let slice: &str = args[1].as_slice();
        println!("open \"{}\" ...", slice);
        {
            // read 12 bytes from the Blender file
            let path = Path::new(slice);
            let display = path.display();
            let mut file = match File::open(&path) {
                Err(why) => fail!("couldn't open {}: {}", display, why.desc),
                Ok(file) => file,
            };
            let mut buf = [0u8, ..12];
            match file.read(buf) {
                Err(why) => println!("{}", why),
                Ok(_) => (),
            }
            // pack those 12 bytes into a string ...
            let mut header = String::new();
            for n in range(0u, 12) {
                header.push(buf[n] as char);
            }
            // ... to be able to compare them
            let slice = header.as_slice();
            let blender: &str = slice.slice(0, 7); // first 7 chars
            if blender == "BLENDER" {
                println!("INFO: a Blender file.");
                let ptr_size = pointer_size();
                println!("size of pointer in bytes: {}", ptr_size);
                println!("Header (12 chars): {}", header);
                let mut ptr_size_differs = false;
                if buf[7] as char == '_' {
                    // 32-bit pointers expected
                    if ptr_size != 4 {
                        ptr_size_differs = true;
                    }
                    println!("32-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                } else {
                    // 64-bit pointers expected
                    if ptr_size != 8 {
                        ptr_size_differs = true;
                    }
                    println!("64-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                }
                // little endian or big endian?
                let mut l_endian;
                let endian_test = 1u16; // value one stored in two bytes
                if endian_test.to_le() != endian_test {
                    l_endian = false;
                } else {
                    // if we are on a little endian machine to_le() is a no-op
                    l_endian = true;
                }
                println!("l_endian = {}", l_endian);
                let mut switch_endian;
                if buf[8] as char == 'v' {
                    // file stores little endian
                    if !l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                } else {
                    // file stores big endian
                    if l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                }
                println!("switch_endian = {}", switch_endian);
                // get the version number
                let mut num = String::new();
                for n in range(9u, 12) {
                    num.push(buf[n] as char);
                }
                println!("num = {}", num);
                // assumes 64-bit pointers (in file as well as on platform)
                loop {
                    // read_file_dna
                    let mut bhead8 = [0u8, ..24]; // 4 * int + 64-bit pointer
                    match file.read(bhead8) {
                        Err(why) => println!("{}", why),
                        Ok(_) => (),
                    }
                    // pack those 24 bytes into a string ...
                    let mut bhead = String::new();
                    for n in range(0u, 24) {
                        bhead.push(bhead8[n] as char);
                    }
                    let slice = bhead.as_slice();
                    let code: &str = slice.slice(0, 4); // first 4 chars
                    println!("code = {}", code);
                    let mut len: uint = 0;
                    len += (bhead8[4] as uint) <<  0;
                    len += (bhead8[5] as uint) <<  8;
                    len += (bhead8[6] as uint) << 16;
                    len += (bhead8[7] as uint) << 24;
                    println!("len = {}", len);
                    if code == "ENDB" && len == 0 {
                        break;
                    } else if code == "DNA1" {
                        // DNA_sdna_from_data
                        let mut counter = 0u;
                        // SDNA
                        let mut char4 = [0u8, ..4];
                        match file.read(char4) {
                            Err(why) => println!("{}", why),
                            Ok(_) => (),
                        }
                        counter += 4;
                        let mut str4 = String::new();
                        for n in range(0u, 4) {
                            str4.push(char4[n] as char);
                        }
                        let slice = str4.as_slice();
                        let code: &str = slice.slice(0, 4);
                        println!("  code = {}", code);
                        if code == "SDNA" {
                            // NAME
                            let mut char4 = [0u8, ..4];
                            match file.read(char4) {
                                Err(why) => println!("{}", why),
                                Ok(_) => (),
                            }
                            counter += 4;
                            let mut str4 = String::new();
                            for n in range(0u, 4) {
                                str4.push(char4[n] as char);
                            }
                            let slice = str4.as_slice();
                            let code: &str = slice.slice(0, 4);
                            println!("  code = {}", code);
                            if code == "NAME" {
                                // nr_names
                                let io_result = file.read_le_u32();
                                let nr_names: u32 = io_result.unwrap();
                                counter += 4;
                                println!("  nr_names = {}", nr_names);
                            }
                        }
                        // read remaining stuff
                        let _dummy = file.read_exact(len - counter);
                    } else {
                        let _dummy = file.read_exact(len);
                    }
                }
            } else {
                println!("ERROR: not a Blender file.");
            }
        } // file gets closed here
    }
}
<commit_msg>Read and print all names found in DNA1.<commit_after>use std::io::File;
use std::mem;
use std::os;

// https://stackoverflow.com/questions/24633784/is-there-a-gzip-library-available-for-rust

fn pointer_size() -> uint {
    let tmp = 0u8;
    let boxed = box tmp;
    mem::size_of_val(&boxed)
}

fn main() {
    let args = os::args();
    if args.len() != 2 {
        println!("usage: read_blend_file /path/to/file.blend");
    } else {
        let slice: &str = args[1].as_slice();
        println!("open \"{}\" ...", slice);
        {
            // read 12 bytes from the Blender file
            let path = Path::new(slice);
            let display = path.display();
            let mut file = match File::open(&path) {
                Err(why) => fail!("couldn't open {}: {}", display, why.desc),
                Ok(file) => file,
            };
            let mut buf = [0u8, ..12];
            match file.read(buf) {
                Err(why) => println!("{}", why),
                Ok(_) => (),
            }
            // pack those 12 bytes into a string ...
            let mut header = String::new();
            for n in range(0u, 12) {
                header.push(buf[n] as char);
            }
            // ... to be able to compare them
            let slice = header.as_slice();
            let blender: &str = slice.slice(0, 7); // first 7 chars
            if blender == "BLENDER" {
                println!("INFO: a Blender file.");
                let ptr_size = pointer_size();
                println!("size of pointer in bytes: {}", ptr_size);
                println!("Header (12 chars): {}", header);
                let mut ptr_size_differs = false;
                if buf[7] as char == '_' {
                    // 32-bit pointers expected
                    if ptr_size != 4 {
                        ptr_size_differs = true;
                    }
                    println!("32-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                } else {
                    // 64-bit pointers expected
                    if ptr_size != 8 {
                        ptr_size_differs = true;
                    }
                    println!("64-bit pointers in file, pointer size differs? {}", ptr_size_differs);
                }
                // little endian or big endian?
                let mut l_endian;
                let endian_test = 1u16; // value one stored in two bytes
                if endian_test.to_le() != endian_test {
                    l_endian = false;
                } else {
                    // if we are on a little endian machine to_le() is a no-op
                    l_endian = true;
                }
                println!("l_endian = {}", l_endian);
                let mut switch_endian;
                if buf[8] as char == 'v' {
                    // file stores little endian
                    if !l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                } else {
                    // file stores big endian
                    if l_endian {
                        switch_endian = true;
                    } else {
                        switch_endian = false;
                    }
                }
                println!("switch_endian = {}", switch_endian);
                // get the version number
                let mut num = String::new();
                for n in range(9u, 12) {
                    num.push(buf[n] as char);
                }
                println!("num = {}", num);
                // assumes 64-bit pointers (in file as well as on platform)
                loop {
                    // read_file_dna
                    let mut bhead8 = [0u8, ..24]; // 4 * int + 64-bit pointer
                    match file.read(bhead8) {
                        Err(why) => println!("{}", why),
                        Ok(_) => (),
                    }
                    // pack those 24 bytes into a string ...
                    let mut bhead = String::new();
                    for n in range(0u, 24) {
                        bhead.push(bhead8[n] as char);
                    }
                    let slice = bhead.as_slice();
                    let code: &str = slice.slice(0, 4); // first 4 chars
                    println!("code = {}", code);
                    let mut len: uint = 0;
                    len += (bhead8[4] as uint) <<  0;
                    len += (bhead8[5] as uint) <<  8;
                    len += (bhead8[6] as uint) << 16;
                    len += (bhead8[7] as uint) << 24;
                    println!("len = {}", len);
                    if code == "ENDB" && len == 0 {
                        break;
                    } else if code == "DNA1" {
                        // DNA_sdna_from_data
                        let mut counter = 0u;
                        // SDNA
                        let mut char4 = [0u8, ..4];
                        match file.read(char4) {
                            Err(why) => println!("{}", why),
                            Ok(_) => (),
                        }
                        counter += 4;
                        let mut str4 = String::new();
                        for n in range(0u, 4) {
                            str4.push(char4[n] as char);
                        }
                        let slice = str4.as_slice();
                        let code: &str = slice.slice(0, 4);
                        println!("  code = {}", code);
                        if code == "SDNA" {
                            // NAME
                            let mut char4 = [0u8, ..4];
                            match file.read(char4) {
                                Err(why) => println!("{}", why),
                                Ok(_) => (),
                            }
                            counter += 4;
                            let mut str4 = String::new();
                            for n in range(0u, 4) {
                                str4.push(char4[n] as char);
                            }
                            let slice = str4.as_slice();
                            let code: &str = slice.slice(0, 4);
                            println!("  code = {}", code);
                            if code == "NAME" {
                                // nr_names
                                let io_result = file.read_le_u32();
                                let nr_names: u32 = io_result.unwrap();
                                counter += 4;
                                println!("  nr_names = {}", nr_names);
                                let mut nr = 0u32;
                                loop {
                                    let mut name = String::new();
                                    loop {
                                        // expect strings with '\0' as terminator
                                        let io_result = file.read_byte();
                                        let byte: u8 = io_result.unwrap();
                                        counter += 1;
                                        if byte != 0 {
                                            name.push(byte as char);
                                        } else {
                                            println!("    name = '{}'", name);
                                            nr += 1;
                                            break;
                                        }
                                    } // name loop
                                    if nr >= nr_names {
                                        break;
                                    }
                                } // nr_names loop
                                // assume fill bytes with '\0'
                                loop {
                                    let io_result = file.read_byte();
                                    let byte: u8 = io_result.unwrap();
                                    counter += 1;
                                    if byte != 0 {
                                        break;
                                    }
                                }
                            }
                        }
                        // read remaining stuff
                        let _dummy = file.read_exact(len - counter);
                    } else {
                        let _dummy = file.read_exact(len);
                    }
                }
            } else {
                println!("ERROR: not a Blender file.");
            }
        } // file gets closed here
    }
}
<|endoftext|>


<commit_before>//! Contains mathematical functions that operate on tensors. These functions are largely modelled
//! after what is available natively in Rust.

use tensor::Tensor;
use Numeric;
use num::traits::Float;

macro_rules! add_impl {
    ($($f:ident)*) => ($(
        pub fn $f<T: Numeric + Float>(x: Tensor<T>) -> Tensor<T> {
            //let mut y = Tensor::zeros(&x.shape());
            let mut y = x;
            for i in 0..y.size() {
                y[i] = y[i].$f();
            }
            y
        }
    )*)
}

add_impl! { ln log10 log2 sin cos tan asin acos atan exp_m1 exp exp2
            ln_1p sinh cosh tanh asinh acosh atanh sqrt
            floor ceil round trunc fract abs signum }

pub fn log<T: Numeric + Float>(x: Tensor<T>, base: T) -> Tensor<T> {
    let mut y = x;
    for i in 0..y.size() {
        y[i] = y[i].log(base);
    }
    y
}

macro_rules! add_impl_to_bool {
    ($($f:ident)*) => ($(
        pub fn $f<T: Numeric + Float>(x: &Tensor<T>) -> Tensor<bool> {
            let mut y = Tensor::empty(&x.shape());
            for i in 0..y.size() {
                y[i] = x[i].$f();
            }
            y
        }
    )*)
}

add_impl_to_bool! { is_nan is_finite is_infinite is_normal is_sign_positive is_sign_negative }
<commit_msg>Moved function in file<commit_after>//! Contains mathematical functions that operate on tensors. These functions are largely modelled
//! after what is available natively in Rust.

use tensor::Tensor;
use Numeric;
use num::traits::Float;

macro_rules! add_impl {
    ($($f:ident)*) => ($(
        pub fn $f<T: Numeric + Float>(x: Tensor<T>) -> Tensor<T> {
            //let mut y = Tensor::zeros(&x.shape());
            let mut y = x;
            for i in 0..y.size() {
                y[i] = y[i].$f();
            }
            y
        }
    )*)
}

add_impl! { ln log10 log2 sin cos tan asin acos atan exp_m1 exp exp2
            ln_1p sinh cosh tanh asinh acosh atanh sqrt
            floor ceil round trunc fract abs signum }

macro_rules! add_impl_to_bool {
    ($($f:ident)*) => ($(
        pub fn $f<T: Numeric + Float>(x: &Tensor<T>) -> Tensor<bool> {
            let mut y = Tensor::empty(&x.shape());
            for i in 0..y.size() {
                y[i] = x[i].$f();
            }
            y
        }
    )*)
}

add_impl_to_bool! { is_nan is_finite is_infinite is_normal is_sign_positive is_sign_negative }

pub fn log<T: Numeric + Float>(x: Tensor<T>, base: T) -> Tensor<T> {
    let mut y = x;
    for i in 0..y.size() {
        y[i] = y[i].log(base);
    }
    y
}

<|endoftext|>