<commit_before>use nom::{Consumer, FileProducer};
use std::io::{Error, ErrorKind, Result};
use std::u32;

use metadata::{
  Block, BlockData,
  StreamInfo, CueSheet, VorbisComment, Picture,
  PictureType,
};
use metadata::types::MetaDataConsumer;

// Will return true when the unwrapped value of `$option` and `$compare`
// match or `$option` is `Option::None`, otherwise false.
#[inline]
pub fn optional_eq<T: Eq>(option: Option<T>, other: T) -> bool {
  option.map_or(true, |value| value == other)
}

// With the given filename, return all metadata blocks available.
//
// This function expects a flac file, but will return a proper `Result::Err`
// when things go wrong.
//
// # Failures
//
// * `ErrorKind::NotFound` is returned when the given filename isn't found.
// * `ErrorKind::InvalidData` is returned when the data within the file
//   isn't valid FLAC data.
pub fn get_metadata(filename: &str) -> Result<Vec<Block>> {
  FileProducer::new(filename, 1024).and_then(|mut producer| {
    let mut consumer = MetaDataConsumer::new();

    consumer.run(&mut producer);

    if !consumer.data.is_empty() {
      Ok(consumer.data)
    } else {
      let error_str = "parser: couldn't find any metadata";

      Err(Error::new(ErrorKind::InvalidData, error_str))
    }
  })
}

/// Reads and returns the `StreamInfo` metadata block of the given FLAC
/// file.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found
///   or there is no `StreamInfo` within the file.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
///
/// match metadata::get_stream_info("path/to/file.flac") {
///   Ok(stream_info) => {
///     // Use the stream_info variable...
///   }
///   Err(error)      => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors:
///
/// ```no_run
/// use flac::metadata;
///
/// let stream_info = metadata::get_stream_info("path/to/file.flac").unwrap();
/// ```
pub fn get_stream_info(filename: &str) -> Result<StreamInfo> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find StreamInfo";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    for block in blocks {
      if let BlockData::StreamInfo(stream_info) = block.data {
        result = Ok(stream_info);
        break;
      }
    }

    result
  })
}

/// Reads and returns the `VorbisComment` metadata block of the given FLAC
/// file.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found
///   or there is no `VorbisComment` within the file.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
///
/// match metadata::get_vorbis_comment("path/to/file.flac") {
///   Ok(vorbis_comment) => {
///     // Use the vorbis_comment variable...
///   }
///   Err(error)         => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors:
///
/// ```no_run
/// use flac::metadata;
///
/// let vorbis_comment =
///   metadata::get_vorbis_comment("path/to/file.flac").unwrap();
/// ```
pub fn get_vorbis_comment(filename: &str) -> Result<VorbisComment> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find VorbisComment";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    for block in blocks {
      if let BlockData::VorbisComment(vorbis_comment) = block.data {
        result = Ok(vorbis_comment);
        break;
      }
    }

    result
  })
}

/// Reads and returns the `CueSheet` metadata block of the given FLAC file.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found
///   or there is no `CueSheet` within the file.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
///
/// match metadata::get_cue_sheet("path/to/file.flac") {
///   Ok(cue_sheet) => {
///     // Use the cue_sheet variable...
///   }
///   Err(error)    => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors
///
/// ```no_run
/// use flac::metadata;
///
/// let cue_sheet = metadata::get_cue_sheet("path/to/file.flac").unwrap();
/// ```
pub fn get_cue_sheet(filename: &str) -> Result<CueSheet> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find CueSheet";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    for block in blocks {
      if let BlockData::CueSheet(cue_sheet) = block.data {
        result = Ok(cue_sheet);
        break;
      }
    }

    result
  })
}

/// Reads and returns a `Picture` metadata block of the given FLAC file.
///
/// There can be more than one `Picture` block in a file and this function
/// takes optional, that being `Option<T>`, parameters that act as
/// constraints to search within. The `Picture` with the largest area
/// matching all constraints will be returned.
///
/// Putting `None` into any of the optional constraints conveys that you
/// want any of that parameter. Otherwise it will try to look for the image
/// that matches within the given constraints.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found,
///   there is no `Picture` within the file, or no `Picture` that fits the
///   given constraints.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
/// use flac::metadata::PictureType;
///
/// let result = metadata::get_picture("path/to/file.flac",
///                                    Some(PictureType::FileIcon),
///                                    Some("image/gif"),
///                                    None, None, None,
///                                    None, None);
///
/// match result {
///   Ok(picture) => {
///     // Use the picture variable...
///   }
///   Err(error)  => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors:
///
/// ```no_run
/// use flac::metadata;
/// use flac::metadata::PictureType;
///
/// let picture = metadata::get_picture("path/to/file.flac",
///                                     Some(PictureType::FileIcon),
///                                     Some("image/gif"),
///                                     None, None, None,
///                                     None, None).unwrap();
/// ```
pub fn get_picture(filename: &str,
                   picture_type: Option<PictureType>,
                   mime_type: Option<&str>,
                   description: Option<&str>,
                   max_width: Option<u32>,
                   max_height: Option<u32>,
                   max_depth: Option<u32>,
                   max_colors: Option<u32>)
                   -> Result<Picture> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find any Picture";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    let mut max_area_seen  = 0;
    let mut max_depth_seen = 0;

    let max_value      = u32::max_value();
    let max_width_num  = max_width.unwrap_or(max_value);
    let max_height_num = max_height.unwrap_or(max_value);
    let max_depth_num  = max_depth.unwrap_or(max_value);
    let max_colors_num = max_colors.unwrap_or(max_value);

    for block in blocks {
      if let BlockData::Picture(picture) = block.data {
        let area = (picture.width as u64) * (picture.height as u64);

        if optional_eq(picture_type, picture.picture_type) &&
           optional_eq(mime_type, &picture.mime_type) &&
           optional_eq(description, &picture.description) &&
           picture.width <= max_width_num &&
           picture.height <= max_height_num &&
           picture.depth <= max_depth_num &&
           picture.colors <= max_colors_num &&
           (area > max_area_seen || (area == max_area_seen &&
                                     picture.depth > max_depth_seen)) {
          max_area_seen  = area;
          max_depth_seen = picture.depth;
          result         = Ok(picture);
        }
      }
    }

    result
  })
}

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

  #[test]
  #[should_panic]
  fn test_panic_optional_eq() {
    assert!(optional_eq(Some(1), 0));
  }

  #[test]
  fn test_optional_eq() {
    assert!(optional_eq(None, 0), "Should always return true when None");
    assert!(optional_eq(Some(0), 0), "Should return true (Some(0) == 0)");
  }

  #[test]
  fn test_get_metadata() {
    let not_found    = get_metadata("non-existent/file.txt");
    let invalid_data = get_metadata("README.md");
    let result       = get_metadata("tests/assets/input-SVAUP.flac");

    assert_eq!(not_found.unwrap_err().kind(), ErrorKind::NotFound);
    assert_eq!(invalid_data.unwrap_err().kind(), ErrorKind::InvalidData);
    assert!(result.is_ok());
  }
}
<commit_msg>Update documentation for `optional_eq`<commit_after>use nom::{Consumer, FileProducer};
use std::io::{Error, ErrorKind, Result};
use std::u32;

use metadata::{
  Block, BlockData,
  StreamInfo, CueSheet, VorbisComment, Picture,
  PictureType,
};
use metadata::types::MetaDataConsumer;

// Will return true when the unwrapped value of `option` and `other` match
// or `option` is `Option::None`, otherwise false.
#[inline]
pub fn optional_eq<T: Eq>(option: Option<T>, other: T) -> bool {
  option.map_or(true, |value| value == other)
}

// With the given filename, return all metadata blocks available.
//
// This function expects a flac file, but will return a proper `Result::Err`
// when things go wrong.
//
// # Failures
//
// * `ErrorKind::NotFound` is returned when the given filename isn't found.
// * `ErrorKind::InvalidData` is returned when the data within the file
//   isn't valid FLAC data.
pub fn get_metadata(filename: &str) -> Result<Vec<Block>> {
  FileProducer::new(filename, 1024).and_then(|mut producer| {
    let mut consumer = MetaDataConsumer::new();

    consumer.run(&mut producer);

    if !consumer.data.is_empty() {
      Ok(consumer.data)
    } else {
      let error_str = "parser: couldn't find any metadata";

      Err(Error::new(ErrorKind::InvalidData, error_str))
    }
  })
}

/// Reads and returns the `StreamInfo` metadata block of the given FLAC
/// file.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found
///   or there is no `StreamInfo` within the file.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
///
/// match metadata::get_stream_info("path/to/file.flac") {
///   Ok(stream_info) => {
///     // Use the stream_info variable...
///   }
///   Err(error)      => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors:
///
/// ```no_run
/// use flac::metadata;
///
/// let stream_info = metadata::get_stream_info("path/to/file.flac").unwrap();
/// ```
pub fn get_stream_info(filename: &str) -> Result<StreamInfo> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find StreamInfo";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    for block in blocks {
      if let BlockData::StreamInfo(stream_info) = block.data {
        result = Ok(stream_info);
        break;
      }
    }

    result
  })
}

/// Reads and returns the `VorbisComment` metadata block of the given FLAC
/// file.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found
///   or there is no `VorbisComment` within the file.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
///
/// match metadata::get_vorbis_comment("path/to/file.flac") {
///   Ok(vorbis_comment) => {
///     // Use the vorbis_comment variable...
///   }
///   Err(error)         => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors:
///
/// ```no_run
/// use flac::metadata;
///
/// let vorbis_comment =
///   metadata::get_vorbis_comment("path/to/file.flac").unwrap();
/// ```
pub fn get_vorbis_comment(filename: &str) -> Result<VorbisComment> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find VorbisComment";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    for block in blocks {
      if let BlockData::VorbisComment(vorbis_comment) = block.data {
        result = Ok(vorbis_comment);
        break;
      }
    }

    result
  })
}

/// Reads and returns the `CueSheet` metadata block of the given FLAC file.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found
///   or there is no `CueSheet` within the file.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
///
/// match metadata::get_cue_sheet("path/to/file.flac") {
///   Ok(cue_sheet) => {
///     // Use the cue_sheet variable...
///   }
///   Err(error)    => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors
///
/// ```no_run
/// use flac::metadata;
///
/// let cue_sheet = metadata::get_cue_sheet("path/to/file.flac").unwrap();
/// ```
pub fn get_cue_sheet(filename: &str) -> Result<CueSheet> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find CueSheet";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    for block in blocks {
      if let BlockData::CueSheet(cue_sheet) = block.data {
        result = Ok(cue_sheet);
        break;
      }
    }

    result
  })
}

/// Reads and returns a `Picture` metadata block of the given FLAC file.
///
/// There can be more than one `Picture` block in a file and this function
/// takes optional, that being `Option<T>`, parameters that act as
/// constraints to search within. The `Picture` with the largest area
/// matching all constraints will be returned.
///
/// Putting `None` into any of the optional constraints conveys that you
/// want any of that parameter. Otherwise it will try to look for the image
/// that matches within the given constraints.
///
/// # Failures
///
/// * `ErrorKind::NotFound` is returned when the given filename isn't found,
///   there is no `Picture` within the file, or no `Picture` that fits the
///   given constraints.
/// * `ErrorKind::InvalidData` is returned when the data within the file
///   isn't valid FLAC data.
///
/// # Examples
///
/// Handling errors might look something like this:
///
/// ```
/// use flac::metadata;
/// use flac::metadata::PictureType;
///
/// let result = metadata::get_picture("path/to/file.flac",
///                                    Some(PictureType::FileIcon),
///                                    Some("image/gif"),
///                                    None, None, None,
///                                    None, None);
///
/// match result {
///   Ok(picture) => {
///     // Use the picture variable...
///   }
///   Err(error)  => println!("{}", error),
/// }
/// ```
///
/// Or just ignore the errors:
///
/// ```no_run
/// use flac::metadata;
/// use flac::metadata::PictureType;
///
/// let picture = metadata::get_picture("path/to/file.flac",
///                                     Some(PictureType::FileIcon),
///                                     Some("image/gif"),
///                                     None, None, None,
///                                     None, None).unwrap();
/// ```
pub fn get_picture(filename: &str,
                   picture_type: Option<PictureType>,
                   mime_type: Option<&str>,
                   description: Option<&str>,
                   max_width: Option<u32>,
                   max_height: Option<u32>,
                   max_depth: Option<u32>,
                   max_colors: Option<u32>)
                   -> Result<Picture> {
  get_metadata(filename).and_then(|blocks| {
    let error_str  = "metadata: couldn't find any Picture";
    let mut result = Err(Error::new(ErrorKind::NotFound, error_str));

    let mut max_area_seen  = 0;
    let mut max_depth_seen = 0;

    let max_value      = u32::max_value();
    let max_width_num  = max_width.unwrap_or(max_value);
    let max_height_num = max_height.unwrap_or(max_value);
    let max_depth_num  = max_depth.unwrap_or(max_value);
    let max_colors_num = max_colors.unwrap_or(max_value);

    for block in blocks {
      if let BlockData::Picture(picture) = block.data {
        let area = (picture.width as u64) * (picture.height as u64);

        if optional_eq(picture_type, picture.picture_type) &&
           optional_eq(mime_type, &picture.mime_type) &&
           optional_eq(description, &picture.description) &&
           picture.width <= max_width_num &&
           picture.height <= max_height_num &&
           picture.depth <= max_depth_num &&
           picture.colors <= max_colors_num &&
           (area > max_area_seen || (area == max_area_seen &&
                                     picture.depth > max_depth_seen)) {
          max_area_seen  = area;
          max_depth_seen = picture.depth;
          result         = Ok(picture);
        }
      }
    }

    result
  })
}

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

  #[test]
  #[should_panic]
  fn test_panic_optional_eq() {
    assert!(optional_eq(Some(1), 0));
  }

  #[test]
  fn test_optional_eq() {
    assert!(optional_eq(None, 0), "Should always return true when None");
    assert!(optional_eq(Some(0), 0), "Should return true (Some(0) == 0)");
  }

  #[test]
  fn test_get_metadata() {
    let not_found    = get_metadata("non-existent/file.txt");
    let invalid_data = get_metadata("README.md");
    let result       = get_metadata("tests/assets/input-SVAUP.flac");

    assert_eq!(not_found.unwrap_err().kind(), ErrorKind::NotFound);
    assert_eq!(invalid_data.unwrap_err().kind(), ErrorKind::InvalidData);
    assert!(result.is_ok());
  }
}
<|endoftext|>


<commit_before>use std::io::{self, Write};

use stream::raw::Operation;

use zstd_safe;

// input -> [ zstd -> buffer -> writer ]

/// Implements the [`Write`] API around an [`Operation`].
///
/// This can be used to wrap a raw in-memory operation in a write-focused API.
///
/// It can be used with either compression or decompression, and forwards the
/// output to a wrapped `Write`.
pub struct Writer<W, D> {
    writer: W,
    operation: D,

    offset: usize,
    buffer: Vec<u8>,

    // When `true`, indicates that nothing should be added to the buffer.
    // All that's left if to empty the buffer.
    finished: bool,

    finished_frame: bool,
}

impl<W, D> Writer<W, D>
where
    W: Write,
    D: Operation,
{
    /// Creates a new `Writer`.
    ///
    /// All output from the given operation will be forwarded to `writer`.
    pub fn new(writer: W, operation: D) -> Self {
        Writer {
            writer,
            operation,

            offset: 0,
            // 32KB buffer? That's what flate2 uses
            buffer: Vec::with_capacity(32 * 1024),

            finished: false,
            finished_frame: false,
        }
    }

    /// Ends the stream.
    ///
    /// This *must* be called after all data has been written to finish the
    /// stream.
    ///
    /// If you forget to call this and just drop the `Writer`, you *will* have
    /// an incomplete output.
    ///
    /// Keep calling it until it returns `Ok(())`, then don't call it again.
    pub fn finish(&mut self) -> io::Result<()> {
        loop {
            // Keep trying until we're really done.
            self.write_from_offset()?;

            // At this point the buffer has been fully written out.

            if self.finished {
                return Ok(());
            }

            // Let's fill this buffer again!

            let finished_frame = self.finished_frame;
            let hint = unsafe {
                self.with_full_buffer(|dst, op| op.finish(dst, finished_frame))
            };
            self.offset = 0;
            // println!("Hint: {:?}\nOut:{:?}", hint, &self.buffer);

            // We return here if zstd had a problem.
            // Could happen with invalid data, ...
            let hint = hint?;

            if hint != 0 && self.buffer.len() == 0 {
                // This happens if we are decoding an incomplete frame.
                return Err(io::Error::new(
                    io::ErrorKind::UnexpectedEof,
                    "incomplete frame",
                ));
            }

            // println!("Finishing {}, {}", bytes_written, hint);

            self.finished = hint == 0;
        }
    }

    /// Run the given closure on `self.buffer`.
    ///
    /// Before running it, the buffer will look as big as its capacity,
    /// but the memory there may be uninitialized.
    ///
    /// It is only safe to write in this buffer, not to read from there.
    unsafe fn with_full_buffer<F, T>(&mut self, f: F) -> T
    where
        F: FnOnce(&mut zstd_safe::OutBuffer, &mut D) -> T,
    {
        let capacity = self.buffer.capacity();
        self.buffer.set_len(capacity);

        let (bytes_written, result) = {
            let mut output = zstd_safe::OutBuffer::around(&mut self.buffer);
            let result = f(&mut output, &mut self.operation);
            (output.pos, result)
        };
        self.buffer.set_len(bytes_written);
        result
    }

    /// Attempt to write `self.buffer` to the wrapped writer.
    ///
    /// Returns `Ok(())` once all the buffer has been written.
    fn write_from_offset(&mut self) -> io::Result<()> {
        // The code looks a lot like `write_all`, but keeps track of what has
        // been written in case we're interrupted.
        while self.offset < self.buffer.len() {
            match self.writer.write(&self.buffer[self.offset..]) {
                Ok(n) => self.offset += n,
                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (),
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }

    /// Return the wrapped `Writer` and `Operation`.
    ///
    /// Careful: if you call this before calling [`Writer::finish()`], the
    /// output may be incomplete.
    pub fn into_inner(self) -> (W, D) {
        (self.writer, self.operation)
    }

    /// Gives a reference to the inner writer.
    pub fn writer(&self) -> &W {
        &self.writer
    }

    /// Gives a mutable reference to the inner writer.
    pub fn writer_mut(&mut self) -> &mut W {
        &mut self.writer
    }

    /// Returns the offset in the current buffer. Only useful for debugging.
    #[cfg(test)]
    pub fn offset(&self) -> usize {
        self.offset
    }

    /// Returns the current buffer. Only useful for debugging.
    #[cfg(test)]
    pub fn buffer(&self) -> &[u8] {
        &self.buffer
    }
}

impl<W, D> Write for Writer<W, D>
where
    W: Write,
    D: Operation,
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        // Keep trying until _something_ has been consumed.
        // As soon as some input has been taken, we cannot afford
        // to take any chance: if an error occurs, the user couldn't know
        // that some data _was_ successfully written.
        loop {
            // First, write any pending data from `self.buffer`.
            self.write_from_offset()?;
            // At this point `self.buffer` can safely be discarded.

            // Support writing concatenated frames by re-initializing the
            // context.
            if self.finished_frame {
                self.operation.reinit()?;
                self.finished_frame = false;
            }

            let mut src = zstd_safe::InBuffer::around(buf);
            let hint = unsafe {
                self.with_full_buffer(|dst, op| op.run(&mut src, dst))
            };
            let bytes_read = src.pos;

            // println!("Hint: {:?}\nRead {}", hint, bytes_read);

            self.offset = 0;
            let hint = hint?;

            if hint == 0 {
                self.finished_frame = true;
            }

            // As we said, as soon as we've consumed something, return.
            if bytes_read > 0 || buf.is_empty() {
                // println!("Returning {}", bytes_read);
                return Ok(bytes_read);
            }
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        let mut finished = self.finished;
        loop {
            // If the output is blocked or has an error, return now.
            self.write_from_offset()?;

            if finished {
                return Ok(());
            }

            let hint =
                unsafe { self.with_full_buffer(|dst, op| op.flush(dst)) };

            self.offset = 0;
            let hint = hint?;

            finished = hint == 0;
        }
    }
}

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

    #[test]
    fn test_noop() {
        use stream::raw::NoOp;

        let input = b"AbcdefghAbcdefgh.";

        // Test writer
        let mut output = Vec::new();
        {
            let mut writer = Writer::new(&mut output, NoOp);
            writer.write_all(input).unwrap();
            writer.finish().unwrap();
        }
        assert_eq!(&output, input);
    }

    #[test]
    fn test_compress() {
        use stream::raw::Encoder;

        let input = b"AbcdefghAbcdefgh.";

        // Test writer
        let mut output = Vec::new();
        {
            let mut writer =
                Writer::new(&mut output, Encoder::new(1).unwrap());
            writer.write_all(input).unwrap();
            writer.finish().unwrap();
        }
        // println!("Output: {:?}", output);
        let decoded = ::decode_all(&output[..]).unwrap();
        assert_eq!(&decoded, input);
    }

    #[test]
    fn test_decompress() {
        use stream::raw::Decoder;

        let input = b"AbcdefghAbcdefgh.";
        let compressed = ::encode_all(&input[..], 1).unwrap();

        // Test writer
        let mut output = Vec::new();
        {
            let mut writer = Writer::new(&mut output, Decoder::new().unwrap());
            writer.write_all(&compressed).unwrap();
            writer.finish().unwrap();
        }
        // println!("Output: {:?}", output);
        assert_eq!(&output, input);
    }
}
<commit_msg>Fix clippy warning<commit_after>use std::io::{self, Write};

use stream::raw::Operation;

use zstd_safe;

// input -> [ zstd -> buffer -> writer ]

/// Implements the [`Write`] API around an [`Operation`].
///
/// This can be used to wrap a raw in-memory operation in a write-focused API.
///
/// It can be used with either compression or decompression, and forwards the
/// output to a wrapped `Write`.
pub struct Writer<W, D> {
    writer: W,
    operation: D,

    offset: usize,
    buffer: Vec<u8>,

    // When `true`, indicates that nothing should be added to the buffer.
    // All that's left if to empty the buffer.
    finished: bool,

    finished_frame: bool,
}

impl<W, D> Writer<W, D>
where
    W: Write,
    D: Operation,
{
    /// Creates a new `Writer`.
    ///
    /// All output from the given operation will be forwarded to `writer`.
    pub fn new(writer: W, operation: D) -> Self {
        Writer {
            writer,
            operation,

            offset: 0,
            // 32KB buffer? That's what flate2 uses
            buffer: Vec::with_capacity(32 * 1024),

            finished: false,
            finished_frame: false,
        }
    }

    /// Ends the stream.
    ///
    /// This *must* be called after all data has been written to finish the
    /// stream.
    ///
    /// If you forget to call this and just drop the `Writer`, you *will* have
    /// an incomplete output.
    ///
    /// Keep calling it until it returns `Ok(())`, then don't call it again.
    pub fn finish(&mut self) -> io::Result<()> {
        loop {
            // Keep trying until we're really done.
            self.write_from_offset()?;

            // At this point the buffer has been fully written out.

            if self.finished {
                return Ok(());
            }

            // Let's fill this buffer again!

            let finished_frame = self.finished_frame;
            let hint = unsafe {
                self.with_full_buffer(|dst, op| op.finish(dst, finished_frame))
            };
            self.offset = 0;
            // println!("Hint: {:?}\nOut:{:?}", hint, &self.buffer);

            // We return here if zstd had a problem.
            // Could happen with invalid data, ...
            let hint = hint?;

            if hint != 0 && self.buffer.is_empty() {
                // This happens if we are decoding an incomplete frame.
                return Err(io::Error::new(
                    io::ErrorKind::UnexpectedEof,
                    "incomplete frame",
                ));
            }

            // println!("Finishing {}, {}", bytes_written, hint);

            self.finished = hint == 0;
        }
    }

    /// Run the given closure on `self.buffer`.
    ///
    /// Before running it, the buffer will look as big as its capacity,
    /// but the memory there may be uninitialized.
    ///
    /// It is only safe to write in this buffer, not to read from there.
    unsafe fn with_full_buffer<F, T>(&mut self, f: F) -> T
    where
        F: FnOnce(&mut zstd_safe::OutBuffer, &mut D) -> T,
    {
        let capacity = self.buffer.capacity();
        self.buffer.set_len(capacity);

        let (bytes_written, result) = {
            let mut output = zstd_safe::OutBuffer::around(&mut self.buffer);
            let result = f(&mut output, &mut self.operation);
            (output.pos, result)
        };
        self.buffer.set_len(bytes_written);
        result
    }

    /// Attempt to write `self.buffer` to the wrapped writer.
    ///
    /// Returns `Ok(())` once all the buffer has been written.
    fn write_from_offset(&mut self) -> io::Result<()> {
        // The code looks a lot like `write_all`, but keeps track of what has
        // been written in case we're interrupted.
        while self.offset < self.buffer.len() {
            match self.writer.write(&self.buffer[self.offset..]) {
                Ok(n) => self.offset += n,
                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (),
                Err(e) => return Err(e),
            }
        }
        Ok(())
    }

    /// Return the wrapped `Writer` and `Operation`.
    ///
    /// Careful: if you call this before calling [`Writer::finish()`], the
    /// output may be incomplete.
    pub fn into_inner(self) -> (W, D) {
        (self.writer, self.operation)
    }

    /// Gives a reference to the inner writer.
    pub fn writer(&self) -> &W {
        &self.writer
    }

    /// Gives a mutable reference to the inner writer.
    pub fn writer_mut(&mut self) -> &mut W {
        &mut self.writer
    }

    /// Returns the offset in the current buffer. Only useful for debugging.
    #[cfg(test)]
    pub fn offset(&self) -> usize {
        self.offset
    }

    /// Returns the current buffer. Only useful for debugging.
    #[cfg(test)]
    pub fn buffer(&self) -> &[u8] {
        &self.buffer
    }
}

impl<W, D> Write for Writer<W, D>
where
    W: Write,
    D: Operation,
{
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        // Keep trying until _something_ has been consumed.
        // As soon as some input has been taken, we cannot afford
        // to take any chance: if an error occurs, the user couldn't know
        // that some data _was_ successfully written.
        loop {
            // First, write any pending data from `self.buffer`.
            self.write_from_offset()?;
            // At this point `self.buffer` can safely be discarded.

            // Support writing concatenated frames by re-initializing the
            // context.
            if self.finished_frame {
                self.operation.reinit()?;
                self.finished_frame = false;
            }

            let mut src = zstd_safe::InBuffer::around(buf);
            let hint = unsafe {
                self.with_full_buffer(|dst, op| op.run(&mut src, dst))
            };
            let bytes_read = src.pos;

            // println!("Hint: {:?}\nRead {}", hint, bytes_read);

            self.offset = 0;
            let hint = hint?;

            if hint == 0 {
                self.finished_frame = true;
            }

            // As we said, as soon as we've consumed something, return.
            if bytes_read > 0 || buf.is_empty() {
                // println!("Returning {}", bytes_read);
                return Ok(bytes_read);
            }
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        let mut finished = self.finished;
        loop {
            // If the output is blocked or has an error, return now.
            self.write_from_offset()?;

            if finished {
                return Ok(());
            }

            let hint =
                unsafe { self.with_full_buffer(|dst, op| op.flush(dst)) };

            self.offset = 0;
            let hint = hint?;

            finished = hint == 0;
        }
    }
}

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

    #[test]
    fn test_noop() {
        use stream::raw::NoOp;

        let input = b"AbcdefghAbcdefgh.";

        // Test writer
        let mut output = Vec::new();
        {
            let mut writer = Writer::new(&mut output, NoOp);
            writer.write_all(input).unwrap();
            writer.finish().unwrap();
        }
        assert_eq!(&output, input);
    }

    #[test]
    fn test_compress() {
        use stream::raw::Encoder;

        let input = b"AbcdefghAbcdefgh.";

        // Test writer
        let mut output = Vec::new();
        {
            let mut writer =
                Writer::new(&mut output, Encoder::new(1).unwrap());
            writer.write_all(input).unwrap();
            writer.finish().unwrap();
        }
        // println!("Output: {:?}", output);
        let decoded = ::decode_all(&output[..]).unwrap();
        assert_eq!(&decoded, input);
    }

    #[test]
    fn test_decompress() {
        use stream::raw::Decoder;

        let input = b"AbcdefghAbcdefgh.";
        let compressed = ::encode_all(&input[..], 1).unwrap();

        // Test writer
        let mut output = Vec::new();
        {
            let mut writer = Writer::new(&mut output, Decoder::new().unwrap());
            writer.write_all(&compressed).unwrap();
            writer.finish().unwrap();
        }
        // println!("Output: {:?}", output);
        assert_eq!(&output, input);
    }
}
<|endoftext|>


<commit_before>
use postgres::{PostgresConnection, NoSsl};
use postgres::types::ToSql;
use std::fmt::Show;

use postgres::types::range::Range;

pub fn get_content() -> Result<~str, ~str> {
  let mut content : StrBuf = StrBuf::new();
	content.push_str("<title>Trying Rust!</title>\n");
	content.push_str("
\n");

  let conn = match PostgresConnection::connect("postgres://jdavis@localhost:5433/postgres", &NoSsl)
                   { Ok(r) => { r }, Err(e) => { return Err(format!("{}",e)) } };
  let stmt = match conn.prepare("SELECT ir FROM x")
                   { Ok(r) => { r }, Err(e) => { return Err(format!("{}",e)) } };
  let mut res = match stmt.query([])
                   { Ok(r) => { r }, Err(e) => { return Err(format!("{}",e)) } };
  for row in res {
    let val : Range<i32> = row[1];
    content.push_str(format!("
{}
\n", val));
  }

  content.push_str("
\n");
  content.push_str("\n");
  return Ok(content.into_owned());
}<commit_msg>Work with ranges.<commit_after>
use postgres::{PostgresConnection, NoSsl};
use postgres::types::ToSql;
use std::fmt::Show;

use postgres::types::range::{Range, RangeBound, Inclusive, Exclusive};

pub fn get_content() -> Result<~str, ~str> {
  let mut content : StrBuf = StrBuf::new();
	content.push_str("<title>Trying Rust!</title>\n");
	content.push_str("
\n");

  let conn = match PostgresConnection::connect("postgres://jdavis@localhost:5433/postgres", &NoSsl)
                   { Ok(r) => { r }, Err(e) => { return Err(format!("{}",e)) } };
  let stmt = match conn.prepare("SELECT ir FROM x")
                   { Ok(r) => { r }, Err(e) => { return Err(format!("{}",e)) } };
  let mut res = match stmt.query([])
                   { Ok(r) => { r }, Err(e) => { return Err(format!("{}",e)) } };

  let q = Range::new(Some(RangeBound::new(50i32, Inclusive)),
                     Some(RangeBound::new(60i32, Exclusive)));

  for row in res {
    let mut color = "green";
    let val : Range<i32> = row[1];
    if !q.intersect(&val).is_empty()
    {
       color = "red";
    }

    content.push_str(format!("
{}
\n", color, val));
  }

  content.push_str("
\n");
  content.push_str("\n");
  return Ok(content.into_owned());
}<|endoftext|>


<commit_before>use super::memory::MemSegment;
use audio::{AudioOut};

pub type Sample = i16;

const CPU_CYCLES_PER_EVEN_TICK: u64 = 7438;
const CPUCYCLES_PER_ODD_TICK: u64 = 7439;

const NES_FPS: usize = 60;
const FRAMES_PER_BUFFER : usize = 6;
pub const BUFFERS_PER_SECOND : usize = NES_FPS / FRAMES_PER_BUFFER; //must always be a positive integer

const SAMPLE_RATE: usize = 44100;
const SAMPLES_PER_FRAME: usize = (SAMPLE_RATE / NES_FPS);
pub const BUFFER_SIZE: usize = SAMPLES_PER_FRAME * FRAMES_PER_BUFFER;

static LENGTH_TABLE: [u8; 32] = [
    0x0A, 0xFE,
    0x14, 0x02,
    0x28, 0x04,
    0x50, 0x06,
    0xA0, 0x08,
    0x3C, 0x0A,
    0x0E, 0x0C,
    0x1A, 0x0E,
    0x0C, 0x10,
    0x18, 0x12,
    0x30, 0x14,
    0x60, 0x16,
    0xC0, 0x18,
    0x48, 0x1A,
    0x10, 0x1C,
    0x20, 0x1E,
];

pub struct OutputBuffer {
    pub samples: [i16; BUFFER_SIZE as usize],
}

bitflags! {
    flags Frame : u8 {
        const MODE = 0b1000_0000, //0 = 4-step, 1 = 5-step
        const IRQ  = 0b0100_0000, //0 = disabled, 1 = enabled
    }
}

trait Writable {
    fn write(&mut self, idx: u16, val: u8);
}

struct Length {
    halt_bit: usize,
    halted: bool,
    remaining: u8,
}

impl Length {
    fn write_halt(&mut self, val: u8) {
        self.halted = (val >> self.halt_bit ) & 0x01 != 0;
        if self.halted {
            self.remaining = 0;
        }
    }

    fn write_counter(&mut self, val: u8) {
        if !self.halted {
            self.remaining = LENGTH_TABLE[(val >> 3) as usize];
        }
    }

    fn is_enabled(&self) -> bool {
        self.remaining > 0
    }

    fn tick(&mut self) {
        self.remaining = self.remaining.saturating_sub(1);
    }

    fn new(halt_bit: usize) -> Length {
        Length {
            halt_bit: halt_bit,
            halted: false,
            remaining: 0,
        }
    }
}

struct Envelope {
    should_loop: bool,
    disable: bool,
    n: u8,

    divider: u8,
    counter: u8,
}

impl Envelope {
    fn new() -> Envelope {
        Envelope {
            should_loop: false,
            disable: false,
            n: 0,
            divider: 0,
            counter: 0,
        }
    }

    fn write(&mut self, val: u8) {
        self.should_loop = (val >> 5) & 0x01 != 0;
        self.disable     = (val >> 6) & 0x01 != 0;
        self.n           = val & 0x0F;
        self.divider = self.n;
        self.counter = 15;
    }

    fn tick(&mut self) {
        if self.divider == 0 {
            self.envelope_tick();
            self.divider = self.n;
        }
        else {
            self.divider -= 1;
        }
    }

    fn envelope_tick(&mut self) {
        if self.should_loop && self.counter == 0 {
            self.counter = 15;
        }
        else {
            self.counter = self.counter.saturating_sub(1);
        }
    }
}

struct Pulse {
    flags: u8,
    envelope: Envelope,
    sweep: u8,
    timer: u8,
    length: Length,
}

impl Pulse {
    fn new() -> Pulse {
        Pulse {
            flags: 0,
            envelope: Envelope::new(),
            sweep: 0,
            timer: 0,
            length: Length::new(5),
        }
    }
}

impl Writable for Pulse {
    fn write(&mut self, idx: u16, val: u8) {
        match idx % 4 {
            0 => {
                self.length.write_halt(val);
                self.envelope.write(val);
            },
            1 => (),
            2 => (),
            3 => self.length.write_counter(val),
            _ => (),
        }
    }
}

struct Triangle {
    counter: u8,
    timer: u8,
    length: Length,
}

impl Triangle {
    fn new() -> Triangle {
        Triangle {
            counter: 0,
            timer: 0,
            length: Length::new(7),
        }
    }
}

impl Writable for Triangle {
    fn write(&mut self, idx: u16, val: u8) {
        match idx % 4 {
            0 => self.length.write_halt(val),
            1 => (),
            2 => (),
            3 => self.length.write_counter(val),
            _ => (),
        }
    }
}

struct Noise {
    envelope: Envelope,
    mode: u8,
    length: Length,
}

impl Noise {
    fn new() -> Noise {
        Noise {
            envelope: Envelope::new(),
            mode: 0,
            length: Length::new(5),
        }
    }
}

impl Writable for Noise {
    fn write(&mut self, idx: u16, val: u8) {
        match idx % 4 {
            0 => {
                self.length.write_halt(val);
                self.envelope.write(val);
            },
            1 => (),
            2 => (),
            3 => self.length.write_counter(val),
            _ => (),
        }
    }
}

struct DMC {
    freq: u8,
    direct: u8,
    sample_addr: u8,
    sample_length: u8,
}

impl DMC {
    fn new() -> DMC {
        DMC {
            freq: 0,
            direct: 0,
            sample_addr: 0,
            sample_length: 0,
        }
    }
}

impl Writable for DMC {
    fn write(&mut self, idx: u16, val: u8) {

    }
}

pub struct APU {
    pulse1: Pulse,
    pulse2: Pulse,
    triangle: Triangle,
    noise: Noise,
    dmc: DMC,
    frame: Frame,
    control: u8,
    status: u8,

    device: Box<AudioOut>,

    global_cyc: u64,
    tick: u64,
    next_tick_cyc: u64,
}

impl APU {
    pub fn new( device: Box<AudioOut> ) -> APU {
        APU {
            pulse1: Pulse::new(),
            pulse2: Pulse::new(),
            triangle: Triangle::new(),
            noise: Noise::new(),
            dmc: DMC::new(),
            frame: Frame::empty(),
            control: 0,
            status: 0,

            device: device,

            global_cyc: 0,
            tick: 0,
            next_tick_cyc: 0,
        }
    }

    pub fn run_to(&mut self, cpu_cycle: u64) {
        while self.global_cyc < cpu_cycle {
            if self.global_cyc == self.next_tick_cyc {
                self.tick();
                self.tick += 1;
                self.next_tick_cyc += if self.tick %2 == 0 {
                    CPU_CYCLES_PER_EVEN_TICK
                }
                else {
                    CPUCYCLES_PER_ODD_TICK
                }
            }
            self.global_cyc += 1;
        }
    }

    ///Represents the 240Hz output of the frame sequencer's divider
    fn tick(&mut self) {
        if !self.frame.contains(MODE) {
            match self.tick % 4 {
                0 => { self.envelope_tick(); },
                1 => { self.envelope_tick(); self.length_tick(); },
                2 => { self.envelope_tick(); },
                3 => { self.envelope_tick(); self.length_tick(); self.raise_irq(); },
                _ => (),
            }
        }
        else {
            match self.tick % 5 {
                0 => { self.envelope_tick(); self.length_tick() },
                1 => { self.envelope_tick(); },
                2 => { self.envelope_tick(); self.length_tick() },
                3 => { self.envelope_tick(); },
                4 => (),
                _ => (),
            }
        }
    }

    fn envelope_tick(&mut self) {

    }

    fn length_tick(&mut self) {
        self.pulse1.length.tick();
        self.pulse2.length.tick();
        self.triangle.length.tick();
        self.noise.length.tick();
    }

    fn raise_irq(&mut self) {

    }

    pub fn play(&mut self) {

    }
}

impl MemSegment for APU {
    fn read(&mut self, idx: u16) -> u8 {
        match idx % 0x20 {
            0x0015 => self.status,
            _ => 0,
        }
    }

    fn write(&mut self, idx: u16, val: u8) {
        match idx % 0x20 {
            x @ 0x00...0x03 => self.pulse1.write(x, val),
            x @ 0x04...0x07 => self.pulse2.write(x, val),
            x @ 0x08...0x0B => self.triangle.write(x, val),
            x @ 0x0C...0x0F => self.noise.write(x, val),
            x @ 0x10...0x13 => self.dmc.write(x, val),
            0x0014 => (),
            0x0015 => self.control = val,
            0x0016 => (),
            0x0017 => {
                self.frame = Frame::from_bits_truncate(val);
                self.tick = 0;
                if self.frame.contains( MODE ) {
                    //Trigger a tick immediately
                    self.next_tick_cyc = self.global_cyc
                }
                else {
                    //Reset the tick divider
                    self.next_tick_cyc = self.global_cyc + CPU_CYCLES_PER_EVEN_TICK
                }
            },
            _ => (),
        }
    }
}<commit_msg>Implemented the sweep and timer units.<commit_after>use super::memory::MemSegment;
use audio::{AudioOut};

pub type Sample = i16;

const CPU_CYCLES_PER_EVEN_TICK: u64 = 7438;
const CPUCYCLES_PER_ODD_TICK: u64 = 7439;

const NES_FPS: usize = 60;
const FRAMES_PER_BUFFER : usize = 6;
pub const BUFFERS_PER_SECOND : usize = NES_FPS / FRAMES_PER_BUFFER; //must always be a positive integer

const SAMPLE_RATE: usize = 44100;
const SAMPLES_PER_FRAME: usize = (SAMPLE_RATE / NES_FPS);
pub const BUFFER_SIZE: usize = SAMPLES_PER_FRAME * FRAMES_PER_BUFFER;

static LENGTH_TABLE: [u8; 32] = [
    0x0A, 0xFE,
    0x14, 0x02,
    0x28, 0x04,
    0x50, 0x06,
    0xA0, 0x08,
    0x3C, 0x0A,
    0x0E, 0x0C,
    0x1A, 0x0E,
    0x0C, 0x10,
    0x18, 0x12,
    0x30, 0x14,
    0x60, 0x16,
    0xC0, 0x18,
    0x48, 0x1A,
    0x10, 0x1C,
    0x20, 0x1E,
];

pub struct OutputBuffer {
    pub samples: [i16; BUFFER_SIZE as usize],
}

bitflags! {
    flags Frame : u8 {
        const MODE = 0b1000_0000, //0 = 4-step, 1 = 5-step
        const IRQ  = 0b0100_0000, //0 = disabled, 1 = enabled
    }
}

trait Writable {
    fn write(&mut self, idx: u16, val: u8);
}

struct Length {
    halt_bit: usize,
    halted: bool,
    remaining: u8,
}

impl Length {
    fn write_halt(&mut self, val: u8) {
        self.halted = (val >> self.halt_bit ) & 0x01 != 0;
        if self.halted {
            self.remaining = 0;
        }
    }

    fn write_counter(&mut self, val: u8) {
        if !self.halted {
            self.remaining = LENGTH_TABLE[(val >> 3) as usize];
        }
    }

    fn is_enabled(&self) -> bool {
        self.remaining > 0
    }

    fn tick(&mut self) {
        self.remaining = self.remaining.saturating_sub(1);
    }

    fn new(halt_bit: usize) -> Length {
        Length {
            halt_bit: halt_bit,
            halted: false,
            remaining: 0,
        }
    }
}

struct Envelope {
    should_loop: bool,
    disable: bool,
    n: u8,

    divider: u8,
    counter: u8,
}

impl Envelope {
    fn new() -> Envelope {
        Envelope {
            should_loop: false,
            disable: false,
            n: 0,
            divider: 0,
            counter: 0,
        }
    }

    fn write(&mut self, val: u8) {
        self.should_loop = (val >> 5) & 0x01 != 0;
        self.disable     = (val >> 6) & 0x01 != 0;
        self.n           = val & 0x0F;
        self.divider = self.n;
        self.counter = 15;
    }

    fn tick(&mut self) {
        if self.divider == 0 {
            self.envelope_tick();
            self.divider = self.n;
        }
        else {
            self.divider -= 1;
        }
    }

    fn envelope_tick(&mut self) {
        if self.should_loop && self.counter == 0 {
            self.counter = 15;
        }
        else {
            self.counter = self.counter.saturating_sub(1);
        }
    }
}

struct Timer {
    period: u16,
    current_step: u32,

    //The timer is clocked for every sample, so the period logic is in the Pulse.play function
}

impl Timer {
    fn new() -> Timer {
        Timer{
            period: 0,
            current_step: 0,
        }
    }

    fn write_low(&mut self, val: u8) {
        self.period = ( self.period & 0xFF00 ) | val as u16;
    }

    fn write_high(&mut self, val: u8) {
        self.period = ( self.period & 0x00FF ) | (val & 0x0007) as u16;
    }

    fn add_period_shift(&mut self, shift: i16) {
        let new_period = (self.period as i16).wrapping_add( shift );
        self.period = new_period as u16;
    }
}

struct Sweep {
    enable: bool,
    period: u8,
    negate: bool,
    shift: u8,

    is_pulse2: bool,
    divider: u8,
    reload: bool,
}

impl Sweep {
    fn new(is_pulse2: bool) -> Sweep {
        Sweep {
            enable: false,
            period: 0,
            negate: false,
            shift: 0,

            is_pulse2: is_pulse2,
            divider: 0,
            reload: false,
        }
    }

    fn write(&mut self, val: u8) {
        self.enable = (val & 0b1000_0000) != 0;
        self.period = (val & 0b0111_0000) >> 4;
        self.negate = (val & 0b0000_1000) != 0;
        self.shift  =  val & 0b0000_0111;
        self.reload = true;
    }

    fn tick(&mut self, timer: &mut Timer) {
        if !self.enable {
            return;
        }

        self.divider = self.divider.saturating_sub(1);
        if self.divider == 0 {
            self.divider = self.period;
            let period_shift = self.period_shift(timer);
            timer.add_period_shift( period_shift );
        }

        if self.reload {
            self.divider = self.period;
            self.reload = false;
        }
    }

    fn period_shift(&self, timer: &Timer) -> i16 {
        let mut shift = timer.period as i16;
        shift = shift >> self.shift;
        if self.negate {
            shift = -shift;
            if self.is_pulse2 {
                shift = shift + 1;
            }
        }
        shift
    }
}

struct Pulse {
    envelope: Envelope,
    sweep: Sweep,
    timer: Timer,
    length: Length,
}

impl Pulse {
    fn new(is_pulse2: bool) -> Pulse {
        Pulse {
            envelope: Envelope::new(),
            sweep: Sweep::new(is_pulse2),
            timer: Timer::new(),
            length: Length::new(5),
        }
    }

    fn length_tick(&mut self) {
        self.length.tick();
        let timer = &mut self.timer;
        self.sweep.tick(timer)
    }

    fn envelope_tick(&mut self) {
        self.envelope.tick();
    }
}

impl Writable for Pulse {
    fn write(&mut self, idx: u16, val: u8) {
        match idx % 4 {
            0 => {
                self.length.write_halt(val);
                self.envelope.write(val);
            },
            1 => self.sweep.write(val),
            2 => self.timer.write_low(val),
            3 => {
                self.length.write_counter(val);
                self.timer.write_high(val);
            },
            _ => (),
        }
    }
}

struct Triangle {
    counter: u8,
    timer: u8,
    length: Length,
}

impl Triangle {
    fn new() -> Triangle {
        Triangle {
            counter: 0,
            timer: 0,
            length: Length::new(7),
        }
    }

    fn length_tick(&mut self) {
        self.length.tick();
    }

    fn envelope_tick(&mut self) {
        //Nothing yet
    }
}

impl Writable for Triangle {
    fn write(&mut self, idx: u16, val: u8) {
        match idx % 4 {
            0 => self.length.write_halt(val),
            1 => (),
            2 => (),
            3 => self.length.write_counter(val),
            _ => (),
        }
    }
}

struct Noise {
    envelope: Envelope,
    mode: u8,
    length: Length,
}

impl Noise {
    fn new() -> Noise {
        Noise {
            envelope: Envelope::new(),
            mode: 0,
            length: Length::new(5),
        }
    }

    fn length_tick(&mut self) {
        self.length.tick();
    }
}

impl Writable for Noise {
    fn write(&mut self, idx: u16, val: u8) {
        match idx % 4 {
            0 => {
                self.length.write_halt(val);
                self.envelope.write(val);
            },
            1 => (),
            2 => (),
            3 => self.length.write_counter(val),
            _ => (),
        }
    }
}

struct DMC {
    freq: u8,
    direct: u8,
    sample_addr: u8,
    sample_length: u8,
}

impl DMC {
    fn new() -> DMC {
        DMC {
            freq: 0,
            direct: 0,
            sample_addr: 0,
            sample_length: 0,
        }
    }
}

impl Writable for DMC {
    fn write(&mut self, idx: u16, val: u8) {

    }
}

pub struct APU {
    pulse1: Pulse,
    pulse2: Pulse,
    triangle: Triangle,
    noise: Noise,
    dmc: DMC,
    frame: Frame,
    control: u8,
    status: u8,

    device: Box<AudioOut>,

    global_cyc: u64,
    tick: u64,
    next_tick_cyc: u64,
}

impl APU {
    pub fn new( device: Box<AudioOut> ) -> APU {
        APU {
            pulse1: Pulse::new(false),
            pulse2: Pulse::new(true),
            triangle: Triangle::new(),
            noise: Noise::new(),
            dmc: DMC::new(),
            frame: Frame::empty(),
            control: 0,
            status: 0,

            device: device,

            global_cyc: 0,
            tick: 0,
            next_tick_cyc: 0,
        }
    }

    pub fn run_to(&mut self, cpu_cycle: u64) {
        while self.global_cyc < cpu_cycle {
            if self.global_cyc == self.next_tick_cyc {
                self.tick();
                self.tick += 1;
                self.next_tick_cyc += if self.tick %2 == 0 {
                    CPU_CYCLES_PER_EVEN_TICK
                }
                else {
                    CPUCYCLES_PER_ODD_TICK
                }
            }
            self.global_cyc += 1;
        }
    }

    ///Represents the 240Hz output of the frame sequencer's divider
    fn tick(&mut self) {
        if !self.frame.contains(MODE) {
            match self.tick % 4 {
                0 => { self.envelope_tick(); },
                1 => { self.envelope_tick(); self.length_tick(); },
                2 => { self.envelope_tick(); },
                3 => { self.envelope_tick(); self.length_tick(); self.raise_irq(); },
                _ => (),
            }
        }
        else {
            match self.tick % 5 {
                0 => { self.envelope_tick(); self.length_tick() },
                1 => { self.envelope_tick(); },
                2 => { self.envelope_tick(); self.length_tick() },
                3 => { self.envelope_tick(); },
                4 => (),
                _ => (),
            }
        }
    }

    fn envelope_tick(&mut self) {
        self.pulse1.envelope_tick();
        self.pulse2.envelope_tick();
        self.triangle.envelope_tick();
    }

    fn length_tick(&mut self) {
        self.pulse1.length_tick();
        self.pulse2.length_tick();
        self.triangle.length_tick();
        self.noise.length_tick();
    }

    fn raise_irq(&mut self) {

    }

    pub fn play(&mut self) {

    }
}

impl MemSegment for APU {
    fn read(&mut self, idx: u16) -> u8 {
        match idx % 0x20 {
            0x0015 => self.status,
            _ => 0,
        }
    }

    fn write(&mut self, idx: u16, val: u8) {
        match idx % 0x20 {
            x @ 0x00...0x03 => self.pulse1.write(x, val),
            x @ 0x04...0x07 => self.pulse2.write(x, val),
            x @ 0x08...0x0B => self.triangle.write(x, val),
            x @ 0x0C...0x0F => self.noise.write(x, val),
            x @ 0x10...0x13 => self.dmc.write(x, val),
            0x0014 => (),
            0x0015 => self.control = val,
            0x0016 => (),
            0x0017 => {
                self.frame = Frame::from_bits_truncate(val);
                self.tick = 0;
                if self.frame.contains( MODE ) {
                    //Trigger a tick immediately
                    self.next_tick_cyc = self.global_cyc
                }
                else {
                    //Reset the tick divider
                    self.next_tick_cyc = self.global_cyc + CPU_CYCLES_PER_EVEN_TICK
                }
            },
            _ => (),
        }
    }
}<|endoftext|>


<commit_before>#![warn(missing_docs)]

extern crate scout;
extern crate docopt;

use std::env;
use std::process;
use std::io::{self, Read, Write};

use docopt::Docopt;
use scout::errors::Error;

const USAGE: &'static str = "
Scout: Small fuzzy finder

This program expects a list of items in the standard input,
so it is better to use it with pipes.

Usage:
  scout [options]

Options:
  -h --help     Show this screen.
  -v --version  Show version.

Supported keys:
   * ^U to delete the entire line
   * ^N or Arrow key down to select the next match
   * ^P or Arrow key up to select the previous match
   * ESC to quit without selecting a match

Example:
  $ find * -type f | scout
";

pub fn main() {
    Docopt::new(USAGE)
        .and_then(|doc| {
            doc.argv(env::args())
                .version(Some(scout::version()))
                .parse()
        })
        .unwrap_or_else(|e| e.exit());;

    // Collect initial input
    let mut buffer = String::new();
    let stdin = io::stdin();
    match stdin.lock().read_to_string(&mut buffer) {
        Ok(_) => {}
        Err(error) => fatal(&error.into()),
    };

    let list: Vec<&str> = buffer
        .split('\n')
        .map(|s| s.trim())
        .filter(|s| !s.is_empty())
        .collect();

    match scout::start(list) {
        Ok(result) => println!("{}", result),
        Err(error) => fatal(&error),
    }
}

fn fatal(error: &Error) {
    let stderr = io::stderr();
    writeln!(stderr.lock(), "ERROR: {}", error).expect("ERROR while writting to STDERR");

    process::exit(1);
}
<commit_msg>Add docs to bin.rs<commit_after>#![warn(missing_docs)]

//! The command line entry point.
//!
//! It reads the STDIN and writes to STDOUT the choice selected. In
//! case of error, it will print it to STDERR.

extern crate scout;
extern crate docopt;

use std::env;
use std::process;
use std::io::{self, Read, Write};

use docopt::Docopt;
use scout::errors::Error;

const USAGE: &'static str = "
Scout: Small fuzzy finder

This program expects a list of items in the standard input,
so it is better to use it with pipes.

Usage:
  scout [options]

Options:
  -h --help     Show this screen.
  -v --version  Show version.

Supported keys:
   * ^U to delete the entire line
   * ^N or Arrow key down to select the next match
   * ^P or Arrow key up to select the previous match
   * ESC to quit without selecting a match

Example:
  $ find * -type f | scout
";

/// Start the CLI.
pub fn main() {
    Docopt::new(USAGE)
        .and_then(|doc| {
            doc.argv(env::args())
                .version(Some(scout::version()))
                .parse()
        })
        .unwrap_or_else(|e| e.exit());;

    // Collect initial input
    let mut buffer = String::new();
    let stdin = io::stdin();
    match stdin.lock().read_to_string(&mut buffer) {
        Ok(_) => {}
        Err(error) => fatal(&error.into()),
    };

    let list: Vec<&str> = buffer
        .split('\n')
        .map(|s| s.trim())
        .filter(|s| !s.is_empty())
        .collect();

    match scout::start(list) {
        Ok(result) => println!("{}", result),
        Err(error) => fatal(&error),
    }
}

/// Print the error to STDERR and stop the program in a non zero exit status.
fn fatal(error: &Error) {
    let stderr = io::stderr();
    writeln!(stderr.lock(), "ERROR: {}", error).expect("ERROR while writting to STDERR");

    process::exit(1);
}
<|endoftext|>


<commit_before>use std::cmp;
use std::sync::Arc;
use rand::{XorShiftRng, SeedableRng};
use player::Player;
use config;
use config::Solver;
use zobrist::Zobrist;
use field;
use field::Field;
use uct::UctRoot;
use heuristic;
use minimax;
use patterns::Patterns;

const BOT_STR: &'static str = "bot";

const MIN_COMPLEXITY: u32 = 0;

const MAX_COMPLEXITY: u32 = 100;

const MIN_UCT_ITERATIONS: usize = 0;

const MAX_UCT_ITERATIONS: usize = 500000;

const MIN_MINIMAX_DEPTH: u32 = 0;

const MAX_MINIMAX_DEPTH: u32 = 8;

pub struct Bot {
  rng: XorShiftRng,
  patterns: Arc<Patterns>,
  zobrist: Arc<Zobrist>,
  field: Field,
  uct: UctRoot
}

impl Bot {
  pub fn new(width: u32, height: u32, seed: u64, patterns: Arc<Patterns>) -> Bot {
    info!(target: BOT_STR, "Initialization with width {0}, height {1}, seed {2}.", width, height, seed);
    let length = field::length(width, height);
    let seed_array = [3, seed as u32, 7, (seed >> 32) as u32];
    let mut rng = XorShiftRng::from_seed(seed_array);
    let zobrist = Arc::new(Zobrist::new(length * 2, &mut rng));
    let field_zobrist = zobrist.clone();
    Bot {
      rng: rng,
      patterns: patterns,
      zobrist: zobrist,
      field: Field::new(width, height, field_zobrist),
      uct: UctRoot::new(length)
    }
  }

  pub fn initial_move(&self) -> Option<(u32, u32)> {
    match self.field.moves_count() {
      0 => Some((self.field.width() / 2, self.field.height() / 2)),
      1 => {
        let width = self.field.width();
        let height = self.field.height();
        let pos = self.field.points_seq()[0];
        let x = self.field.to_x(pos);
        let y = self.field.to_y(pos);
        if x == 0 || x == width - 1 || y == 0 || y == height - 1 {
          Some((width / 2, height / 2))
        } else if cmp::min(x, width - x - 1) < cmp::min(y, height - y - 1) {
          if x < width - x - 1 {
            Some((x + 1, y))
          } else {
            Some((x - 1, y))
          }
        } else if cmp::min(x, width - x - 1) > cmp::min(y, height - y - 1) {
          if y < height - y - 1 {
            Some((x, y + 1))
          } else {
            Some((x, y - 1))
          }
        } else {
          let dx = x as i32 - (width / 2) as i32;
          let dy = y as i32 - (height / 2) as i32;
          if dx.abs() > dy.abs() {
            if dx < 0 {
              Some((x + 1, y))
            } else {
              Some((x - 1, y))
            }
          } else {
            if dy < 0 {
              Some((x, y + 1))
            } else {
              Some((x, y - 1))
            }
          }
        }
      },
      _ => None
    }
  }

  pub fn best_move(&mut self, player: Player) -> Option<(u32, u32)> {
    self.best_move_with_complexity(player, (MAX_COMPLEXITY - MIN_COMPLEXITY) / 2 + MIN_COMPLEXITY)
  }

  pub fn best_move_with_time(&mut self, player: Player, time: u32) -> Option<(u32, u32)> {
    if self.field.width() < 3 || self.field.height() < 3 {
      return None;
    }
    if let Some(m) = self.initial_move() {
      return Some(m);
    }
    if let Some(pos) = self.patterns.find_rand(&self.field, player, false, &mut self.rng) {
      return Some((self.field.to_x(pos), self.field.to_y(pos)));
    }
    match config::solver() {
      Solver::Uct => {
        self.uct.best_move_with_time(&self.field, player, &mut self.rng, time - config::time_gap())
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Minimax => {
        minimax::minimax_with_time(&mut self.field, player, &mut self.rng, time)
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Heuristic => {
        heuristic::heuristic(&self.field, player).map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      }
    }
  }

  pub fn best_move_with_complexity(&mut self, player: Player, complexity: u32) -> Option<(u32, u32)> {
    if self.field.width() < 3 || self.field.height() < 3 {
      return None;
    }
    if let Some(m) = self.initial_move() {
      return Some(m);
    }
    if let Some(pos) = self.patterns.find_rand(&self.field, player, false, &mut self.rng) {
      return Some((self.field.to_x(pos), self.field.to_y(pos)));
    }
    match config::solver() {
      Solver::Uct => {
        let iterations_count = (complexity - MIN_COMPLEXITY) as usize * (MAX_UCT_ITERATIONS - MIN_UCT_ITERATIONS) / (MAX_COMPLEXITY - MIN_COMPLEXITY) as usize + MIN_UCT_ITERATIONS;
        self.uct.best_move_with_iterations_count(&self.field, player, &mut self.rng, iterations_count)
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Minimax => {
        let depth = (complexity - MIN_COMPLEXITY) * (MAX_MINIMAX_DEPTH - MIN_MINIMAX_DEPTH) / (MAX_COMPLEXITY - MIN_COMPLEXITY) + MIN_MINIMAX_DEPTH;
        minimax::minimax(&mut self.field, player, &mut self.rng, depth)
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Heuristic => {
        heuristic::heuristic(&self.field, player).map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      }
    }
  }

  pub fn put_point(&mut self, x: u32, y: u32, player: Player) -> bool {
    let pos = self.field.to_pos(x, y);
    self.field.put_point(pos, player)
  }

  pub fn undo(&mut self) -> bool {
    self.field.undo()
  }
}
<commit_msg>Add check if the field is occupied.<commit_after>use std::cmp;
use std::sync::Arc;
use rand::{XorShiftRng, SeedableRng};
use player::Player;
use config;
use config::Solver;
use zobrist::Zobrist;
use field;
use field::Field;
use uct::UctRoot;
use heuristic;
use minimax;
use patterns::Patterns;

const BOT_STR: &'static str = "bot";

const MIN_COMPLEXITY: u32 = 0;

const MAX_COMPLEXITY: u32 = 100;

const MIN_UCT_ITERATIONS: usize = 0;

const MAX_UCT_ITERATIONS: usize = 500000;

const MIN_MINIMAX_DEPTH: u32 = 0;

const MAX_MINIMAX_DEPTH: u32 = 8;

pub struct Bot {
  rng: XorShiftRng,
  patterns: Arc<Patterns>,
  zobrist: Arc<Zobrist>,
  field: Field,
  uct: UctRoot
}

impl Bot {
  pub fn new(width: u32, height: u32, seed: u64, patterns: Arc<Patterns>) -> Bot {
    info!(target: BOT_STR, "Initialization with width {0}, height {1}, seed {2}.", width, height, seed);
    let length = field::length(width, height);
    let seed_array = [3, seed as u32, 7, (seed >> 32) as u32];
    let mut rng = XorShiftRng::from_seed(seed_array);
    let zobrist = Arc::new(Zobrist::new(length * 2, &mut rng));
    let field_zobrist = zobrist.clone();
    Bot {
      rng: rng,
      patterns: patterns,
      zobrist: zobrist,
      field: Field::new(width, height, field_zobrist),
      uct: UctRoot::new(length)
    }
  }

  pub fn initial_move(&self) -> Option<(u32, u32)> {
    match self.field.moves_count() {
      0 => Some((self.field.width() / 2, self.field.height() / 2)),
      1 => {
        let width = self.field.width();
        let height = self.field.height();
        let pos = self.field.points_seq()[0];
        let x = self.field.to_x(pos);
        let y = self.field.to_y(pos);
        if x == 0 || x == width - 1 || y == 0 || y == height - 1 {
          Some((width / 2, height / 2))
        } else if cmp::min(x, width - x - 1) < cmp::min(y, height - y - 1) {
          if x < width - x - 1 {
            Some((x + 1, y))
          } else {
            Some((x - 1, y))
          }
        } else if cmp::min(x, width - x - 1) > cmp::min(y, height - y - 1) {
          if y < height - y - 1 {
            Some((x, y + 1))
          } else {
            Some((x, y - 1))
          }
        } else {
          let dx = x as i32 - (width / 2) as i32;
          let dy = y as i32 - (height / 2) as i32;
          if dx.abs() > dy.abs() {
            if dx < 0 {
              Some((x + 1, y))
            } else {
              Some((x - 1, y))
            }
          } else {
            if dy < 0 {
              Some((x, y + 1))
            } else {
              Some((x, y - 1))
            }
          }
        }
      },
      _ => None
    }
  }

  fn is_field_occupied(field: &Field) -> bool {
    for pos in field.min_pos() .. field.max_pos() + 1 {
      if field.is_putting_allowed(pos) {
        return false;
      }
    }
    true
  }

  pub fn best_move(&mut self, player: Player) -> Option<(u32, u32)> {
    self.best_move_with_complexity(player, (MAX_COMPLEXITY - MIN_COMPLEXITY) / 2 + MIN_COMPLEXITY)
  }

  pub fn best_move_with_time(&mut self, player: Player, time: u32) -> Option<(u32, u32)> {
    if self.field.width() < 3 || self.field.height() < 3 || Bot::is_field_occupied(&self.field) {
      return None;
    }
    if let Some(m) = self.initial_move() {
      return Some(m);
    }
    if let Some(pos) = self.patterns.find_rand(&self.field, player, false, &mut self.rng) {
      return Some((self.field.to_x(pos), self.field.to_y(pos)));
    }
    match config::solver() {
      Solver::Uct => {
        self.uct.best_move_with_time(&self.field, player, &mut self.rng, time - config::time_gap())
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Minimax => {
        minimax::minimax_with_time(&mut self.field, player, &mut self.rng, time)
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Heuristic => {
        heuristic::heuristic(&self.field, player).map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      }
    }
  }

  pub fn best_move_with_complexity(&mut self, player: Player, complexity: u32) -> Option<(u32, u32)> {
    if self.field.width() < 3 || self.field.height() < 3 || Bot::is_field_occupied(&self.field) {
      return None;
    }
    if let Some(m) = self.initial_move() {
      return Some(m);
    }
    if let Some(pos) = self.patterns.find_rand(&self.field, player, false, &mut self.rng) {
      return Some((self.field.to_x(pos), self.field.to_y(pos)));
    }
    match config::solver() {
      Solver::Uct => {
        let iterations_count = (complexity - MIN_COMPLEXITY) as usize * (MAX_UCT_ITERATIONS - MIN_UCT_ITERATIONS) / (MAX_COMPLEXITY - MIN_COMPLEXITY) as usize + MIN_UCT_ITERATIONS;
        self.uct.best_move_with_iterations_count(&self.field, player, &mut self.rng, iterations_count)
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Minimax => {
        let depth = (complexity - MIN_COMPLEXITY) * (MAX_MINIMAX_DEPTH - MIN_MINIMAX_DEPTH) / (MAX_COMPLEXITY - MIN_COMPLEXITY) + MIN_MINIMAX_DEPTH;
        minimax::minimax(&mut self.field, player, &mut self.rng, depth)
          .or_else(|| heuristic::heuristic(&self.field, player))
          .map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      },
      Solver::Heuristic => {
        heuristic::heuristic(&self.field, player).map(|pos| (self.field.to_x(pos), self.field.to_y(pos)))
      }
    }
  }

  pub fn put_point(&mut self, x: u32, y: u32, player: Player) -> bool {
    let pos = self.field.to_pos(x, y);
    self.field.put_point(pos, player)
  }

  pub fn undo(&mut self) -> bool {
    self.field.undo()
  }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::cell::{RefCell, RefMut};

use reqwest::{Response};

use errors::*;
use client::MatrixClient;
use matrix_types::Event;

pub struct BotEvent<'a> {
    user_bot_power: u32,
    room: &'a str,
    raw_event: Event,
}

pub struct Bot <'a, 'b> {
    client: RefCell<&'b mut MatrixClient>,
    root_services: Vec<&'a str>,
    all_services: HashMap<&'a str, RefCell<Box<Node<'a>>>>,

    //rooms: RefCell<Vec<&'a str>>,
}

impl<'a, 'b> Bot<'a, 'b> {
    pub fn new(client: &'b mut MatrixClient) -> Self{
        Bot {
            client: RefCell::new(client),
            root_services: Vec::new(),
            all_services: HashMap::new(),
            //rooms: RefCell::new(Vec::new()),
        }
    }

    pub fn join(&self, room_id: &str) -> Result<Response, RustixError>{
        //self.rooms.borrow_mut().push(room_id);
        self.client.borrow().join(room_id)
    }

    pub fn say(&self, room_id: &str, message: &str) -> Result<Response, RustixError> {
        self.client.borrow_mut().send_msg(room_id, message)
    }

    /*
    pub fn reply(&self, event: Event, message: &str) {
    }

    pub fn action(&self, room_id: &str, action: &str) {
    }

    pub fn set_name(&self, name: &str) {
    }
    */

    pub fn register_service(&mut self, name: &'a str, service: Box<Node<'a>>) {
        match service.parent() {
            Some(p) => {
                self.all_services.get_mut(p).unwrap().borrow_mut().register_child(name)
            },
            None => self.root_services.push(name),
        };

        self.all_services.insert(name, RefCell::new(service));
    }

    pub fn get_service(&self, name: &str) -> RefMut<Box<Node<'a>>> {
        self.all_services.get(name).unwrap().borrow_mut()
    }

    pub fn propagate_event(&self, event: &Event) {
        for service in &self.root_services {
            self.all_services.get(service).unwrap()
                .borrow_mut().handle(self, event.clone());
        }
    }

    pub fn run(&mut self) {
        let monitor_room;
        match self.client.borrow().get_public_room_id("test") {
            Some(room_id) => {
                self.join(&room_id);
                println!("Room id: {}", &room_id);
                monitor_room = room_id;
            },
            None => panic!(),
        };

        self.say(&monitor_room, "Hello world from rust!");

        if let Some(rid) = self.client.borrow().get_public_room_id("#geeks") {
            self.join(&rid);
        }

        let mut next_batch;
        match self.client.borrow().sync(None) {
            Ok(res) => next_batch = res.next_batch,
            Err(e) => panic!(e),
        }

        loop {
            let sync_data;
            if let Ok(res) = self.client.borrow().sync(Some(&next_batch)) {
                sync_data = res;
            } else {
                continue;
            }

                /*
                if let Ok(x) = serde_json::to_string_pretty(&res.rooms.join) {
                    println!("{}", x);
                }
                */
                if let Some(room) = sync_data.rooms.join.get(&monitor_room) {
                    for event in &room.timeline.events {
                        self.propagate_event(event);
                    }
                }

                next_batch = sync_data.next_batch;
        }
    }
}

pub trait Node<'a> {
    fn parent(&self) -> Option<&str>;

    fn children(&self) -> &Vec<&'a str>;

    fn register_child(&mut self, name: &'a str);

    fn propagate_event(&self, bot: &Bot, event: Event) {
        for child in self.children() {
            bot.get_service(child).handle(bot, event.clone());
        }
    }

    fn handle(&mut self, bot: &Bot, event: Event) {
        self.propagate_event(bot, event);
    }

    fn on_load(&mut self) { }

    fn on_exit(&self) { }
}
<commit_msg>Clean up bot.run<commit_after>use std::collections::HashMap;
use std::cell::{RefCell, RefMut};

use reqwest::{Response};

use errors::*;
use client::MatrixClient;
use matrix_types::Event;

pub struct BotEvent<'a> {
    user_bot_power: u32,
    room: &'a str,
    raw_event: Event,
}

pub struct Bot <'a, 'b> {
    client: RefCell<&'b mut MatrixClient>,
    root_services: Vec<&'a str>,
    all_services: HashMap<&'a str, RefCell<Box<Node<'a>>>>,

    //rooms: RefCell<Vec<&'a str>>,
}

impl<'a, 'b> Bot<'a, 'b> {
    pub fn new(client: &'b mut MatrixClient) -> Self{
        Bot {
            client: RefCell::new(client),
            root_services: Vec::new(),
            all_services: HashMap::new(),
            //rooms: RefCell::new(Vec::new()),
        }
    }

    pub fn join(&self, room_id: &str) -> Result<Response, RustixError>{
        println!("Joining room with id: {}", &room_id);
        self.client.borrow().join(room_id)

        //self.rooms.borrow_mut().push(room_id);
    }

    pub fn say(&self, room_id: &str, message: &str) -> Result<Response, RustixError> {
        self.client.borrow_mut().send_msg(room_id, message)
    }

    /*
    pub fn reply(&self, event: Event, message: &str) {
    }

    pub fn action(&self, room_id: &str, action: &str) {
    }

    pub fn set_name(&self, name: &str) {
    }
    */

    pub fn register_service(&mut self, name: &'a str, service: Box<Node<'a>>) {
        match service.parent() {
            Some(p) => {
                self.all_services.get_mut(p).unwrap().borrow_mut().register_child(name)
            },
            None => self.root_services.push(name),
        };

        self.all_services.insert(name, RefCell::new(service));
    }

    pub fn get_service(&self, name: &str) -> RefMut<Box<Node<'a>>> {
        self.all_services.get(name).unwrap().borrow_mut()
    }

    pub fn propagate_event(&self, event: &Event) {
        for service in &self.root_services {
            self.all_services.get(service).unwrap()
                .borrow_mut().handle(self, event.clone());
        }
    }

    pub fn run(&mut self) {
        let monitor_room = self.client.borrow().get_public_room_id("test").unwrap();

        self.join(&monitor_room);
        self.say(&monitor_room, "Hello world from rust!");

        if let Some(rid) = self.client.borrow().get_public_room_id("#geeks") {
            self.join(&rid);
        }

        let mut next_batch;
        match self.client.borrow().sync(None) {
            Ok(res) => next_batch = res.next_batch,
            Err(e) => panic!(e),
        }

        loop {
            let sync_data;
            if let Ok(res) = self.client.borrow().sync(Some(&next_batch)) {
                sync_data = res;
            } else {
                continue;
            }

            if let Some(room) = sync_data.rooms.join.get(&monitor_room) {
                for event in &room.timeline.events {
                    self.propagate_event(event);
                }
            }

            next_batch = sync_data.next_batch;
        }
    }
}

pub trait Node<'a> {
    fn parent(&self) -> Option<&str>;

    fn children(&self) -> &Vec<&'a str>;

    fn register_child(&mut self, name: &'a str);

    fn propagate_event(&self, bot: &Bot, event: Event) {
        for child in self.children() {
            bot.get_service(child).handle(bot, event.clone());
        }
    }

    fn handle(&mut self, bot: &Bot, event: Event) {
        self.propagate_event(bot, event);
    }

    fn on_load(&mut self) { }

    fn on_exit(&self) { }
}

/*
if let Ok(x) = serde_json::to_string_pretty(&res.rooms.join) {
    println!("{}", x);
} */
<|endoftext|>


<commit_before>pub use self::imp::*;

#[cfg(not(dox))]
mod imp {
    pub use core::option::Option;
    pub use core::clone::Clone;
    pub use core::marker::Copy;
    pub use core::mem;
}

#[cfg(dox)]
mod imp {
    pub enum Option<T> {
        Some(T),
        None,
    }
    impl<T: Copy> Copy for Option<T> {}
    impl<T: Clone> Clone for Option<T> {
        fn clone(&self) -> Option<T> { loop {} }
    }

    pub trait Clone {
        fn clone(&self) -> Self;
    }

    #[lang = "copy"]
    pub trait Copy {}

    #[lang = "sync"]
    pub trait Sync {}
    impl<T> Sync for T {}

    #[lang = "sized"]
    pub trait Sized {}

    macro_rules! each_int {
        ($mac:ident) => (
            $mac!(u8);
            $mac!(u16);
            $mac!(u32);
            $mac!(u64);
            $mac!(usize);
            $mac!(i8);
            $mac!(i16);
            $mac!(i32);
            $mac!(i64);
            $mac!(isize);
        )
    }

    #[lang = "div"]
    pub trait Div<RHS> {
        type Output;
        fn div(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_div {
        ($($i:ident)*) => ($(
            impl Div<$i> for $i {
                type Output = $i;
                fn div(self, rhs: $i) -> $i { self / rhs }
            }
        )*)
    }
    each_int!(impl_div);

    #[lang = "shl"]
    pub trait Shl<RHS> {
        type Output;
        fn shl(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_shl {
        ($($i:ident)*) => ($(
            impl Shl<$i> for $i {
                type Output = $i;
                fn shl(self, rhs: $i) -> $i { self << rhs }
            }
        )*)
    }
    each_int!(impl_shl);

    #[lang = "mul"]
    pub trait Mul<RHS=Self> {
        type Output;
        fn mul(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_mul {
        ($($i:ident)*) => ($(
            impl Mul for $i {
                type Output = $i;
                fn mul(self, rhs: $i) -> $i { self * rhs }
            }
        )*)
    }
    each_int!(impl_mul);

    #[lang = "sub"]
    pub trait Sub<RHS=Self> {
        type Output;
        fn sub(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_sub {
        ($($i:ident)*) => ($(
            impl Sub for $i {
                type Output = $i;
                fn sub(self, rhs: $i) -> $i { self - rhs }
            }
        )*)
    }
    each_int!(impl_sub);

    #[lang = "bitor"]
    pub trait Bitor<RHS=Self> {
        type Output;
        fn bitor(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_bitor {
        ($($i:ident)*) => ($(
            impl Bitor for $i {
                type Output = $i;
                fn bitor(self, rhs: $i) -> $i { self | rhs }
            }
        )*)
    }
    each_int!(impl_bitor);

    pub mod mem {
        pub fn size_of_val<T>(_: &T) -> usize { 4 }
    }
}
<commit_msg>Auto merge of #484 - eddyb:dox-unops, r=alexcrichton<commit_after>pub use self::imp::*;

#[cfg(not(dox))]
mod imp {
    pub use core::option::Option;
    pub use core::clone::Clone;
    pub use core::marker::Copy;
    pub use core::mem;
}

#[cfg(dox)]
mod imp {
    pub enum Option<T> {
        Some(T),
        None,
    }
    impl<T: Copy> Copy for Option<T> {}
    impl<T: Clone> Clone for Option<T> {
        fn clone(&self) -> Option<T> { loop {} }
    }

    pub trait Clone {
        fn clone(&self) -> Self;
    }

    #[lang = "copy"]
    pub trait Copy {}

    #[lang = "sync"]
    pub trait Sync {}
    impl<T> Sync for T {}

    #[lang = "sized"]
    pub trait Sized {}

    macro_rules! each_int {
        ($mac:ident) => (
            $mac!(u8);
            $mac!(u16);
            $mac!(u32);
            $mac!(u64);
            $mac!(usize);
            each_signed_int!($mac);
        )
    }

    macro_rules! each_signed_int {
        ($mac:ident) => (
            $mac!(i8);
            $mac!(i16);
            $mac!(i32);
            $mac!(i64);
            $mac!(isize);
        )
    }

    #[lang = "div"]
    pub trait Div<RHS> {
        type Output;
        fn div(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_div {
        ($($i:ident)*) => ($(
            impl Div<$i> for $i {
                type Output = $i;
                fn div(self, rhs: $i) -> $i { self / rhs }
            }
        )*)
    }
    each_int!(impl_div);

    #[lang = "shl"]
    pub trait Shl<RHS> {
        type Output;
        fn shl(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_shl {
        ($($i:ident)*) => ($(
            impl Shl<$i> for $i {
                type Output = $i;
                fn shl(self, rhs: $i) -> $i { self << rhs }
            }
        )*)
    }
    each_int!(impl_shl);

    #[lang = "mul"]
    pub trait Mul<RHS=Self> {
        type Output;
        fn mul(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_mul {
        ($($i:ident)*) => ($(
            impl Mul for $i {
                type Output = $i;
                fn mul(self, rhs: $i) -> $i { self * rhs }
            }
        )*)
    }
    each_int!(impl_mul);

    #[lang = "sub"]
    pub trait Sub<RHS=Self> {
        type Output;
        fn sub(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_sub {
        ($($i:ident)*) => ($(
            impl Sub for $i {
                type Output = $i;
                fn sub(self, rhs: $i) -> $i { self - rhs }
            }
        )*)
    }
    each_int!(impl_sub);

    #[lang = "bitor"]
    pub trait Bitor<RHS=Self> {
        type Output;
        fn bitor(self, rhs: RHS) -> Self::Output;
    }

    macro_rules! impl_bitor {
        ($($i:ident)*) => ($(
            impl Bitor for $i {
                type Output = $i;
                fn bitor(self, rhs: $i) -> $i { self | rhs }
            }
        )*)
    }
    each_int!(impl_bitor);

    #[lang = "neg"]
    pub trait Neg {
        type Output;
        fn neg(self) -> Self::Output;
    }

    macro_rules! impl_neg {
        ($($i:ident)*) => ($(
            impl Neg for $i {
                type Output = $i;
                fn neg(self) -> $i { -self }
            }
        )*)
    }
    each_signed_int!(impl_neg);

    #[lang = "not"]
    pub trait Not {
        type Output;
        fn not(self) -> Self::Output;
    }

    macro_rules! impl_not {
        ($($i:ident)*) => ($(
            impl Not for $i {
                type Output = $i;
                fn not(self) -> $i { !self }
            }
        )*)
    }
    each_int!(impl_not);

    pub mod mem {
        pub fn size_of_val<T>(_: &T) -> usize { 4 }
    }
}
<|endoftext|>


<commit_before>// -*- flycheck-rust-crate-root: "lib.rs" -*-
use libc::{c_char, c_int, c_double, c_void, c_ushort};
use std::ptr;
use std::ffi::CString;

#[repr(C)]
pub struct Document;
#[repr(C)]
pub struct Context;
#[allow(dead_code)]
#[repr(C)]
pub struct XPathObject {
    xpath_type: c_ushort,
    pub node_set: *const NodeSet,
    bool_val: c_int,
    float_val: c_double,
    string_val: *const c_char,
    user: *const c_void,
    index: c_int,
    user2: *const c_void,
    index2: c_int
}
/// The nodeset
#[allow(dead_code)]
#[repr(C)]
pub struct NodeSet {
    node_nr: c_int,
    node_max: c_int,
    node_tab: *mut Node
}

/// A node from the nodeset
#[allow(dead_code)]
#[repr(C)]
pub struct Node {
    private: *const c_void,
    element_type: c_ushort,
    name: *const c_char,
    children: *const Node,
    last: *const Node,
    parent: *const Node,
    next: *const Node,
    prev: *const Node,
    doc: *const Document,
    namespace: *const Namespace,
    content: *const c_char,
    properties: *const Attribute,
    namespace_def: *const Namespace,
    psvi: *const c_void,
    line: c_ushort,
    extra: c_ushort
}
#[repr(C)]
pub struct Namespace;
#[repr(C)]
pub struct Attribute;

#[link(name = "xml2")]
extern {
    pub fn xmlParseDoc(body: *const c_char) -> *const Document;
    pub fn xmlParseFile(filename: *const c_char) -> *const Document;
    pub fn xmlFreeDoc(doc: *const Document);

    pub fn xmlXPathNewContext(doc: *const Document) -> *const Context;
    pub fn xmlXPathFreeContext(context: *const Context);

    pub fn xmlXPathEvalExpression(xpath: *const c_char, context: *const Context)
                                  -> *const XPathObject;
    pub fn xmlXPathFreeObject(object: *const XPathObject);
}

#[inline]
fn xml_xpath_node_set_is_empty(ns: *const NodeSet) -> bool {
    unsafe {
        ns.is_null() || (*ns).node_nr==0 || (*ns).node_tab.is_null()
    }
}

impl XPathObject {
    pub fn from_context(context: *const Context,
                        xpath: &str) -> *const XPathObject
    {
        unsafe {
            let result = xmlXPathEvalExpression(CString::from_slice(xpath.as_bytes()).as_ptr(),
                                                context);
            if result.is_null() {
                ptr::null()
            } else if xml_xpath_node_set_is_empty((*result).node_set) {
                xmlXPathFreeObject(result);
                ptr::null()
            } else {
                result
            }
        }
    }
}

impl Copy for Node {}

impl Copy for NodeSet {}

impl<'a> NodeSet {
    /// Gets a vector of nodes from the NodeSet
    pub fn get_nodes(&'a self) -> Vec<&'a Node> {
        unsafe {
            let node_ptr = self.node_tab;
            if node_ptr.is_null() {
                vec![]
            } else {
                range(0, self.node_nr).map(
                    |off| &*self.node_tab.clone().offset(off as int)).collect()
            }
        }
    }
}
<commit_msg>int → isize<commit_after>// -*- flycheck-rust-crate-root: "lib.rs" -*-
use libc::{c_char, c_int, c_double, c_void, c_ushort};
use std::ptr;
use std::ffi::CString;

#[repr(C)]
pub struct Document;
#[repr(C)]
pub struct Context;
#[allow(dead_code)]
#[repr(C)]
pub struct XPathObject {
    xpath_type: c_ushort,
    pub node_set: *const NodeSet,
    bool_val: c_int,
    float_val: c_double,
    string_val: *const c_char,
    user: *const c_void,
    index: c_int,
    user2: *const c_void,
    index2: c_int
}
/// The nodeset
#[allow(dead_code)]
#[repr(C)]
pub struct NodeSet {
    node_nr: c_int,
    node_max: c_int,
    node_tab: *mut Node
}

/// A node from the nodeset
#[allow(dead_code)]
#[repr(C)]
pub struct Node {
    private: *const c_void,
    element_type: c_ushort,
    name: *const c_char,
    children: *const Node,
    last: *const Node,
    parent: *const Node,
    next: *const Node,
    prev: *const Node,
    doc: *const Document,
    namespace: *const Namespace,
    content: *const c_char,
    properties: *const Attribute,
    namespace_def: *const Namespace,
    psvi: *const c_void,
    line: c_ushort,
    extra: c_ushort
}
#[repr(C)]
pub struct Namespace;
#[repr(C)]
pub struct Attribute;

#[link(name = "xml2")]
extern {
    pub fn xmlParseDoc(body: *const c_char) -> *const Document;
    pub fn xmlParseFile(filename: *const c_char) -> *const Document;
    pub fn xmlFreeDoc(doc: *const Document);

    pub fn xmlXPathNewContext(doc: *const Document) -> *const Context;
    pub fn xmlXPathFreeContext(context: *const Context);

    pub fn xmlXPathEvalExpression(xpath: *const c_char, context: *const Context)
                                  -> *const XPathObject;
    pub fn xmlXPathFreeObject(object: *const XPathObject);
}

#[inline]
fn xml_xpath_node_set_is_empty(ns: *const NodeSet) -> bool {
    unsafe {
        ns.is_null() || (*ns).node_nr==0 || (*ns).node_tab.is_null()
    }
}

impl XPathObject {
    pub fn from_context(context: *const Context,
                        xpath: &str) -> *const XPathObject
    {
        unsafe {
            let result = xmlXPathEvalExpression(CString::from_slice(xpath.as_bytes()).as_ptr(),
                                                context);
            if result.is_null() {
                ptr::null()
            } else if xml_xpath_node_set_is_empty((*result).node_set) {
                xmlXPathFreeObject(result);
                ptr::null()
            } else {
                result
            }
        }
    }
}

impl Copy for Node {}

impl Copy for NodeSet {}

impl<'a> NodeSet {
    /// Gets a vector of nodes from the NodeSet
    pub fn get_nodes(&'a self) -> Vec<&'a Node> {
        unsafe {
            let node_ptr = self.node_tab;
            if node_ptr.is_null() {
                vec![]
            } else {
                range(0, self.node_nr).map(
                    |off| &*self.node_tab.clone().offset(off as isize)).collect()
            }
        }
    }
}
<|endoftext|>