<commit_before>#![cfg(target_os = "windows")]

extern crate libc;
extern crate image;

extern crate winapi;
extern crate kernel32;
extern crate user32;
extern crate shell32;
extern crate gdi32;

mod win32;
mod bitmap;

pub use bitmap::*;

use std::cell::RefCell;
use std::result::Result;
use std::cmp;
use std::time::{Instant, Duration};
use std::thread;

#[derive(Copy, Clone, PartialEq)]
pub enum Key {
    Left = 37,
    Right = 39,
    Up = 38,
    Down = 40,
    Space = 32,
    Escape = 27,
    Ctrl = 17,
    Shift = 16,
    Enter = 13,
    Backspace = 8,
    Period = 188,
    Point = 190,
    Minus = 189,
    Num0 = 48,
    Num1 = 49,
    Num2 = 50,
    Num3 = 51,
    Num4 = 52,
    Num5 = 53,
    Num6 = 54,
    Num7 = 55,
    Num8 = 56,
    Num9 = 57,
    A = 65,
    B = 66,
    C = 67,
    D = 68,
    E = 69,
    F = 70,
    G = 71,
    H = 72,
    I = 73,
    J = 74,
    K = 75,
    L = 76,
    M = 77,
    N = 78,
    O = 79,
    P = 80,
    Q = 81,
    R = 82,
    S = 83,
    T = 84,
    U = 85,
    V = 86,
    W = 87,
    X = 88,
    Y = 89,
    Z = 90
}

#[derive(Copy, Clone, PartialEq)]
pub struct Rect {
   pub left: i32,
   pub right: i32,
   pub top: i32,
   pub bottom: i32,
}

impl Rect {
   pub fn new(left: i32, top: i32, right: i32, bottom: i32) -> Rect {
      Rect {
         left: left,
         right: right,
         top: top,
         bottom: bottom,
      }
   }

   pub fn new_size(x: i32, y: i32, w: i32, h: i32) -> Rect {
      Rect {
         left: x,
         right: x + w,
         top: y,
         bottom: y + h,
      }
   }

   #[inline]
   pub fn inside(&self, x: i32, y: i32) -> bool {
       self.left <= x && x <= self.right && self.top <= y && y <= self.bottom
   }

   pub fn intersect(&self, r: Rect) -> Rect {
       Rect {
           left: cmp::min(r.right, cmp::max(self.left, r.left)),
           right: cmp::max(r.left, cmp::min(self.right, r.right)),
           top: cmp::min(r.bottom, cmp::max(self.top, r.top)),
           bottom: cmp::max(r.top, cmp::max(self.bottom, r.bottom)),
       }
   }

   pub fn tr(&self, x: i32, y: i32) -> Rect {
       Rect {
           left: self.left + x,
           right: self.right + x,
           top: self.top + y,
           bottom: self.bottom + y,
       }
   }

   pub fn fit(&self, x: i32, y: i32, w: i32, h: i32) -> Rect {
       Rect {
           left: cmp::max(self.left, x),
           right: cmp::min(self.right, x + w),
           top: cmp::max(self.top, y),
           bottom: cmp::min(self.bottom, y + h),
       }
   }
}

#[derive(Copy, Clone, PartialEq)]
pub struct Color {
    pub rgba: u32,
}

impl Color {
   pub fn new(r: u8, g: u8, b: u8, a: u8) -> Color {
      Color { rgba: (a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | b as u32 }
   }

   pub fn red(&self) -> u8 {
      ((self.rgba >> 16) & 0xff) as u8
   }

   pub fn green(&self) -> u8 {
      ((self.rgba >> 8) & 0xff) as u8
   }

   pub fn blue(&self) -> u8 {
      (self.rgba & 0xff) as u8
   }

   pub fn alpha(&self) -> u8 {
      ((self.rgba >> 24) & 0xff) as u8
   }
}

struct Palette {
   colors: Vec<Color>,
}

impl Palette {
   fn new() -> Palette {
      Palette {
         colors: vec![Color::new(0, 0, 0, 0), Color::new(0, 0, 0, 255), Color::new(255, 255, 255, 255)],
      }
   }

   fn add_color(&mut self, color: Color) -> u8 {
       for i in 0..self.colors.len() {
           if self.colors[i].rgba == color.rgba {
               return i as u8;
           }
       }

       self.colors.push(color);
       (self.colors.len() - 1) as u8
   }
}

pub struct Config {
   title: String,
   width: u32,
   height: u32,
   scale: u32,
}

pub trait Painter {
   fn clip_reset(&self);
   fn clip_set(&self, rect: Rect);

   fn pixel(&self, x: i32, y: i32, color: u8);

   fn clear(&self, color: u8);
   fn rect_stroke(&self, rect: Rect, color: u8);
   fn rect_fill(&self, rect: Rect, color: u8);

   fn line(&self, x1: i32, y1: i32, x2: i32, y2: i32, color: u8);
}

pub trait Application : Sized {
   fn new(ctx: &Context) -> Self;

   fn step(&mut self, ctx: &Context) -> bool { !ctx.key_pressed(Key::Escape) }
   fn paint(&self, painter: &Painter);
}

use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
static IS_TINY_CONTEXT_ALIVE: AtomicBool = ATOMIC_BOOL_INIT;

pub const TRANSPARENT: u8 = 0;
pub const BLACK: u8 = 1;
pub const WHITE: u8 = 2;

pub struct Context {
   palette: RefCell<Palette>,
   canvas: Bitmap,
   window: win32::Window,

   frame_time: f64,
   step_time: f64,
   paint_time: f64,
   blit_time: f64,
}

impl Context {
   fn new(window: win32::Window, config: &Config) -> Context {
      Context {
         palette: RefCell::new(Palette::new()),
         canvas: Bitmap::new(config.width, config.height),
         window: window,
         frame_time: 0.0,
         step_time: 0.0,
         paint_time: 0.0,
         blit_time: 0.0,
      }
   }

   pub fn palette_add(&self, color: Color) -> u8 {
       self.palette.borrow_mut().add_color(color)
   }

   pub fn key_down(&self, key: Key) -> bool {
       self.window.key_state[key as usize]
   }

   pub fn key_pressed(&self, key: Key) -> bool {
       self.window.key_state[key as usize] && self.window.key_delta[key as usize]
   }
}

fn to_milisec(duration: Duration) -> f64 {
   (duration.as_secs() as f64 * 1_000f64) + (duration.subsec_nanos() as f64 / 1_000_000f64)
}

pub fn run<T: Application>(title: &str, width: u32, height: u32, scale: u32) -> Result<(), String> {
   use std::sync::atomic::Ordering;
   let was_alive = IS_TINY_CONTEXT_ALIVE.swap(true, Ordering::Relaxed);
   if was_alive {
      return Err("Cannot initialize Tiny more than once at a time".to_owned());
   }

   let config = Config {
      title: String::from(title),
      width: width,
      height: height,
      scale: scale,
   };

   println!("Starting '{}' with resolution {}x{} at scale {}", config.title, config.width, config.height, config.scale);

   let mut context = match win32::Window::new(&config) {
      Ok(window) => Context::new(window, &config),
      Err(err) => return Err(err),
   };

   // Initialize the application
   let mut app = T::new(&context);
   context.window.show();

   let target_frame_time = 33_333_333u32; // An fps of 30Hz

   // Main loop
   'main: loop {
      let frame_now = Instant::now();

      // Handle messages
      if !context.window.pump() {
         break;
      }

      {  // Step the application
         let step_now = Instant::now();

         if !app.step(&mut context) {
             break 'main;
         }

         context.step_time = to_milisec(step_now.elapsed());
      }

      {  // Let the application paint to the canvas
         let paint_now = Instant::now();

         let p = BitmapPainter::new(&mut context.canvas);
         app.paint(&p);

         context.paint_time = to_milisec(paint_now.elapsed());
      }

      {  // Blit canvas to the window
         let blit_now = Instant::now();
         context.window.paint(&context.canvas, &context.palette.borrow_mut().colors);
         context.blit_time = to_milisec(blit_now.elapsed());
      }

      let frame_duration = frame_now.elapsed();
      context.frame_time = to_milisec(frame_duration);

      // Sleep to force the frame time to 33ms
      if frame_duration.as_secs() == 0 && frame_duration.subsec_nanos() < target_frame_time {
         thread::sleep(Duration::new(0, target_frame_time - frame_duration.subsec_nanos()));
      }
   }

   let was_alive = IS_TINY_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
   assert!(was_alive);
   Ok(())
}

#[cfg(test)]
mod tests {
   #[test]
   fn it_works() {
   }
}
<commit_msg>Fixed indentation<commit_after>#![cfg(target_os = "windows")]

extern crate libc;
extern crate image;

extern crate winapi;
extern crate kernel32;
extern crate user32;
extern crate shell32;
extern crate gdi32;

mod win32;
mod bitmap;

pub use bitmap::*;

use std::cell::RefCell;
use std::result::Result;
use std::cmp;
use std::time::{Instant, Duration};
use std::thread;

#[derive(Copy, Clone, PartialEq)]
pub enum Key {
    Left = 37,
    Right = 39,
    Up = 38,
    Down = 40,
    Space = 32,
    Escape = 27,
    Ctrl = 17,
    Shift = 16,
    Enter = 13,
    Backspace = 8,
    Period = 188,
    Point = 190,
    Minus = 189,
    Num0 = 48,
    Num1 = 49,
    Num2 = 50,
    Num3 = 51,
    Num4 = 52,
    Num5 = 53,
    Num6 = 54,
    Num7 = 55,
    Num8 = 56,
    Num9 = 57,
    A = 65,
    B = 66,
    C = 67,
    D = 68,
    E = 69,
    F = 70,
    G = 71,
    H = 72,
    I = 73,
    J = 74,
    K = 75,
    L = 76,
    M = 77,
    N = 78,
    O = 79,
    P = 80,
    Q = 81,
    R = 82,
    S = 83,
    T = 84,
    U = 85,
    V = 86,
    W = 87,
    X = 88,
    Y = 89,
    Z = 90
}

#[derive(Copy, Clone, PartialEq)]
pub struct Rect {
   pub left: i32,
   pub right: i32,
   pub top: i32,
   pub bottom: i32,
}

impl Rect {
   pub fn new(left: i32, top: i32, right: i32, bottom: i32) -> Rect {
      Rect {
         left: left,
         right: right,
         top: top,
         bottom: bottom,
      }
   }

   pub fn new_size(x: i32, y: i32, w: i32, h: i32) -> Rect {
      Rect {
         left: x,
         right: x + w,
         top: y,
         bottom: y + h,
      }
   }

   #[inline]
   pub fn inside(&self, x: i32, y: i32) -> bool {
       self.left <= x && x <= self.right && self.top <= y && y <= self.bottom
   }

   pub fn intersect(&self, r: Rect) -> Rect {
       Rect {
           left: cmp::min(r.right, cmp::max(self.left, r.left)),
           right: cmp::max(r.left, cmp::min(self.right, r.right)),
           top: cmp::min(r.bottom, cmp::max(self.top, r.top)),
           bottom: cmp::max(r.top, cmp::max(self.bottom, r.bottom)),
       }
   }

   pub fn tr(&self, x: i32, y: i32) -> Rect {
       Rect {
           left: self.left + x,
           right: self.right + x,
           top: self.top + y,
           bottom: self.bottom + y,
       }
   }

   pub fn fit(&self, x: i32, y: i32, w: i32, h: i32) -> Rect {
       Rect {
           left: cmp::max(self.left, x),
           right: cmp::min(self.right, x + w),
           top: cmp::max(self.top, y),
           bottom: cmp::min(self.bottom, y + h),
       }
   }
}

#[derive(Copy, Clone, PartialEq)]
pub struct Color {
    pub rgba: u32,
}

impl Color {
   pub fn new(r: u8, g: u8, b: u8, a: u8) -> Color {
      Color { rgba: (a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | b as u32 }
   }

   pub fn red(&self) -> u8 {
      ((self.rgba >> 16) & 0xff) as u8
   }

   pub fn green(&self) -> u8 {
      ((self.rgba >> 8) & 0xff) as u8
   }

   pub fn blue(&self) -> u8 {
      (self.rgba & 0xff) as u8
   }

   pub fn alpha(&self) -> u8 {
      ((self.rgba >> 24) & 0xff) as u8
   }
}

struct Palette {
   colors: Vec<Color>,
}

impl Palette {
   fn new() -> Palette {
      Palette {
         colors: vec![Color::new(0, 0, 0, 0), Color::new(0, 0, 0, 255), Color::new(255, 255, 255, 255)],
      }
   }

   fn add_color(&mut self, color: Color) -> u8 {
      for i in 0..self.colors.len() {
         if self.colors[i].rgba == color.rgba {
            return i as u8;
         }
      }

      self.colors.push(color);
      (self.colors.len() - 1) as u8
   }
}

pub struct Config {
   title: String,
   width: u32,
   height: u32,
   scale: u32,
}

pub trait Painter {
   fn clip_reset(&self);
   fn clip_set(&self, rect: Rect);

   fn pixel(&self, x: i32, y: i32, color: u8);

   fn clear(&self, color: u8);
   fn rect_stroke(&self, rect: Rect, color: u8);
   fn rect_fill(&self, rect: Rect, color: u8);

   fn line(&self, x1: i32, y1: i32, x2: i32, y2: i32, color: u8);
}

pub trait Application : Sized {
   fn new(ctx: &Context) -> Self;

   fn step(&mut self, ctx: &Context) -> bool { !ctx.key_pressed(Key::Escape) }
   fn paint(&self, painter: &Painter);
}

use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT};
static IS_TINY_CONTEXT_ALIVE: AtomicBool = ATOMIC_BOOL_INIT;

pub const TRANSPARENT: u8 = 0;
pub const BLACK: u8 = 1;
pub const WHITE: u8 = 2;

pub struct Context {
   palette: RefCell<Palette>,
   canvas: Bitmap,
   window: win32::Window,

   frame_time: f64,
   step_time: f64,
   paint_time: f64,
   blit_time: f64,
}

impl Context {
   fn new(window: win32::Window, config: &Config) -> Context {
      Context {
         palette: RefCell::new(Palette::new()),
         canvas: Bitmap::new(config.width, config.height),
         window: window,
         frame_time: 0.0,
         step_time: 0.0,
         paint_time: 0.0,
         blit_time: 0.0,
      }
   }

   pub fn palette_add(&self, color: Color) -> u8 {
       self.palette.borrow_mut().add_color(color)
   }

   pub fn key_down(&self, key: Key) -> bool {
       self.window.key_state[key as usize]
   }

   pub fn key_pressed(&self, key: Key) -> bool {
       self.window.key_state[key as usize] && self.window.key_delta[key as usize]
   }
}

fn to_milisec(duration: Duration) -> f64 {
   (duration.as_secs() as f64 * 1_000f64) + (duration.subsec_nanos() as f64 / 1_000_000f64)
}

pub fn run<T: Application>(title: &str, width: u32, height: u32, scale: u32) -> Result<(), String> {
   use std::sync::atomic::Ordering;
   let was_alive = IS_TINY_CONTEXT_ALIVE.swap(true, Ordering::Relaxed);
   if was_alive {
      return Err("Cannot initialize Tiny more than once at a time".to_owned());
   }

   let config = Config {
      title: String::from(title),
      width: width,
      height: height,
      scale: scale,
   };

   println!("Starting '{}' with resolution {}x{} at scale {}", config.title, config.width, config.height, config.scale);

   let mut context = match win32::Window::new(&config) {
      Ok(window) => Context::new(window, &config),
      Err(err) => return Err(err),
   };

   // Initialize the application
   let mut app = T::new(&context);
   context.window.show();

   let target_frame_time = 33_333_333u32; // An fps of 30Hz

   // Main loop
   'main: loop {
      let frame_now = Instant::now();

      // Handle messages
      if !context.window.pump() {
         break;
      }

      {  // Step the application
         let step_now = Instant::now();

         if !app.step(&mut context) {
             break 'main;
         }

         context.step_time = to_milisec(step_now.elapsed());
      }

      {  // Let the application paint to the canvas
         let paint_now = Instant::now();

         let p = BitmapPainter::new(&mut context.canvas);
         app.paint(&p);

         context.paint_time = to_milisec(paint_now.elapsed());
      }

      {  // Blit canvas to the window
         let blit_now = Instant::now();
         context.window.paint(&context.canvas, &context.palette.borrow_mut().colors);
         context.blit_time = to_milisec(blit_now.elapsed());
      }

      let frame_duration = frame_now.elapsed();
      context.frame_time = to_milisec(frame_duration);

      // Sleep to force the frame time to 33ms
      if frame_duration.as_secs() == 0 && frame_duration.subsec_nanos() < target_frame_time {
         thread::sleep(Duration::new(0, target_frame_time - frame_duration.subsec_nanos()));
      }
   }

   let was_alive = IS_TINY_CONTEXT_ALIVE.swap(false, Ordering::Relaxed);
   assert!(was_alive);
   Ok(())
}

#[cfg(test)]
mod tests {
   #[test]
   fn it_works() {
   }
}
<|endoftext|>


<commit_before>use std::mem;
use std::fmt;
use std::error::Error;

///
/// # ReadError
///
/// Returned by the Decoder on failed attempts to read
/// outside of the buffer size.
///
pub struct ReadError;

impl Error for ReadError {
    fn description(&self) -> &str {
        return "Failed to read ouf of the buffer";
    }
}

impl fmt::Display for ReadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl fmt::Debug for ReadError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

///
/// #EncodingError
///
/// Returned by the Encoder when a value fails to encode.
///
pub struct EncodingError<'a>(&'a str);

impl<'a> Error for EncodingError<'a> {
    fn description(&self) -> &str {
        return self.0;
    }
}

impl<'a> fmt::Display for EncodingError<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

impl<'a> fmt::Debug for EncodingError<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description())
    }
}

pub struct Encoder<'a> {
    chunks: Vec<Chunk<'a>>,
    capacity: usize,
}

enum Chunk<'a> {
    Uint8(u8),
    Uint16(u16),
    Uint32(u32),
    Blob(&'a [u8]),
}

impl<'a> Encoder<'a> {
    pub fn new() -> Encoder<'a> {
        Encoder {
            chunks: Vec::new(),
            capacity: 0,
        }
    }

    pub fn uint8(&'a mut self, uint8: u8) -> &'a mut Encoder {
        self.chunks.push(Chunk::Uint8(uint8));
        self.capacity += 1;
        return self;
    }

    pub fn uint16(&'a mut self, uint16: u16) -> &'a mut Encoder {
        self.chunks.push(Chunk::Uint16(uint16));
        self.capacity += 2;
        return self;
    }

    pub fn uint32(&'a mut self, uint32: u32) -> &'a mut Encoder {
        self.chunks.push(Chunk::Uint32(uint32));
        self.capacity += 4;
        return self;
    }

    pub fn int8(&'a mut self, int8: i8) -> &'a mut Encoder {
        self.uint8(unsafe { mem::transmute_copy(&int8) })
    }

    pub fn int16(&'a mut self, int16: i16) -> &'a mut Encoder {
        self.uint16(unsafe { mem::transmute_copy(&int16) })
    }

    pub fn int32(&'a mut self, int32: i32) -> &'a mut Encoder {
        self.uint32(unsafe { mem::transmute_copy(&int32) })
    }

    pub fn float32(&'a mut self, float32: f32) -> &'a mut Encoder {
        self.uint32(unsafe { mem::transmute_copy(&float32) })
    }

    pub fn float64(&'a mut self, float64: f64) -> &'a mut Encoder {
        let uint64: u64 = unsafe { mem::transmute_copy(&float64) };
        return self
            .uint32((uint64 >> 32) as u32)
            .uint32((uint64 & 0xFFFFFFFF) as u32);
    }

    pub fn size(&'a mut self, size: usize) -> &'a mut Encoder {
        if size > 0x3FFFFFFF {
            return self.uint32(0xFFFFFFFF);
        }

        // can fit on 7 bits
        if size < 0x80 {
            return self.uint8(size as u8);
        }

        // can fit on 14 bits
        if size < 0x4000 {
            return self.uint16((size as u16) | 0x8000);
        }

        // use up to 30 bits
        return self.uint32((size as u32) | 0xC0000000);
    }

    pub fn blob(&'a mut self, blob: &'a [u8]) -> &'a mut Encoder {
        let size = blob.len();
        let borrow = self.size(size);
        borrow.capacity += size;
        borrow.chunks.push(Chunk::Blob(blob));
        return borrow;
    }

    pub fn string(&'a mut self, string: &'a str) -> &'a mut Encoder {
        self.blob(string.as_bytes())
    }

    pub fn encode(&'a self) -> Result<Vec<u8>, EncodingError> {
        let mut data: Vec<u8> = Vec::with_capacity(self.capacity);

        for chunk in self.chunks.iter() {
            match chunk {
                &Chunk::Uint8(uint8) => data.push(uint8),
                &Chunk::Uint16(uint16) => {
                    data.push((uint16 >> 8) as u8);
                    data.push((uint16 & 0xFF) as u8);
                },
                &Chunk::Uint32(uint32) => {
                    data.push(((uint32) >> 24) as u8);
                    data.push((((uint32) >> 16) & 0xFF) as u8);
                    data.push((((uint32) >> 8) & 0xFF) as u8);
                    data.push(((uint32) & 0xFF) as u8);
                },
                &Chunk::Blob(blob) => {
                    if blob.len() > 0x3FFFFFFF {
                        return Err(EncodingError("Trying to encode too long data"));
                    }
                    data.extend_from_slice(blob);
                }
            }
        }

        Ok(data)
    }
}

pub struct Decoder<'a> {
    index: usize,
    length: usize,
    data: &'a[u8],
}

impl<'a> Decoder<'a> {
    pub fn new(data: &[u8]) -> Decoder {
        Decoder {
            index: 0,
            length: data.len(),
            data: data,
        }
    }

    pub fn uint8(&mut self) -> Result<u8, ReadError> {
        if self.index >= self.length {
            return Err(ReadError);
        }
        let uint8 = self.data[self.index];
        self.index += 1;
        return Ok(uint8);
    }

    pub fn uint16(&mut self) -> Result<u16, ReadError> {
        Ok(
            (try!(self.uint8()) as u16) << 8 |
            (try!(self.uint8()) as u16)
        )
    }

    pub fn uint32(&mut self) -> Result<u32, ReadError> {
        Ok(
            (try!(self.uint8()) as u32) << 24 |
            (try!(self.uint8()) as u32) << 16 |
            (try!(self.uint8()) as u32) << 8  |
            (try!(self.uint8()) as u32)
        )
    }

    pub fn int8(&mut self) -> Result<i8, ReadError> {
        let uint8 = try!(self.uint8());
        Ok(unsafe { mem::transmute_copy(&uint8) })
    }

    pub fn int16(&mut self) -> Result<i16, ReadError> {
        let uint16 = try!(self.uint16());
        Ok(unsafe { mem::transmute_copy(&uint16) })
    }

    pub fn int32(&mut self) -> Result<i32, ReadError> {
        let uint32 = try!(self.uint32());
        Ok(unsafe { mem::transmute_copy(&uint32) })
    }

    pub fn float32(&mut self) -> Result<f32, ReadError> {
        let uint32 = try!(self.uint32());
        Ok(unsafe { mem::transmute_copy(&uint32) })
    }

    pub fn float64(&mut self) -> Result<f64, ReadError> {
        let uint64 = (try!(self.uint32()) as u64) << 32 |
                     (try!(self.uint32()) as u64);
        Ok(unsafe { mem::transmute_copy(&uint64) })
    }

    pub fn size(&mut self) -> Result<usize, ReadError> {
        let mut size: usize = try!(self.uint8()) as usize;

        // 1 byte (no signature)
        if (size & 128) == 0 {
            return Ok(size);
        }

        let sig: u8 = (size as u8) >> 6;
        // remove signature from the first byte
        size = size & 63 /* 00111111 */;

        // 2 bytes (signature is 10)
        if sig == 2 {
            return Ok(size << 8 | try!(self.uint8()) as usize);
        }

        Ok(
            size << 24                          |
            (try!(self.uint8()) as usize) << 16 |
            (try!(self.uint8()) as usize) << 8  |
            (try!(self.uint8()) as usize)
        )
    }

    pub fn blob(&mut self) -> Result<Vec<u8>, ReadError> {
        let size = try!(self.size());
        if self.index + size >= self.length {
            return Err(ReadError);
        }

        let blob = self.data[self.index .. self.index + size].to_vec();

        self.index += size;

        return Ok(blob);
    }

    pub fn string(&mut self) -> Result<String, ReadError> {
        let blob = try!(self.blob());
        return match String::from_utf8(blob) {
            Ok(string) => Ok(string),
            Err(_) => Err(ReadError),
        }
    }
}
<commit_msg>Finalized errors<commit_after>use std::mem;
use std::fmt;
use std::error;

///
/// #EncodingError
///
/// Returned by the Encoder when a value fails to encode.
///
#[derive(Debug)]
pub struct Error<'a>(&'a str);

impl<'a> Error<'a> {
    pub fn out_of_bounds() -> Self {
        Error("Attempted to read out of bounds")
    }
}

impl<'a> error::Error for Error<'a> {
    fn description(&self) -> &str {
        return self.0;
    }
}

impl<'a> fmt::Display for Error<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

pub struct Encoder<'a> {
    chunks: Vec<Chunk<'a>>,
    capacity: usize,
}

enum Chunk<'a> {
    Uint8(u8),
    Uint16(u16),
    Uint32(u32),
    Blob(&'a [u8]),
    Error(&'a str),
}

impl<'a> Encoder<'a> {
    pub fn new() -> Encoder<'a> {
        Encoder {
            chunks: Vec::new(),
            capacity: 0,
        }
    }

    pub fn uint8(&'a mut self, uint8: u8) -> &'a mut Encoder {
        self.chunks.push(Chunk::Uint8(uint8));
        self.capacity += 1;
        return self;
    }

    pub fn uint16(&'a mut self, uint16: u16) -> &'a mut Encoder {
        self.chunks.push(Chunk::Uint16(uint16));
        self.capacity += 2;
        return self;
    }

    pub fn uint32(&'a mut self, uint32: u32) -> &'a mut Encoder {
        self.chunks.push(Chunk::Uint32(uint32));
        self.capacity += 4;
        return self;
    }

    pub fn int8(&'a mut self, int8: i8) -> &'a mut Encoder {
        self.uint8(unsafe { mem::transmute_copy(&int8) })
    }

    pub fn int16(&'a mut self, int16: i16) -> &'a mut Encoder {
        self.uint16(unsafe { mem::transmute_copy(&int16) })
    }

    pub fn int32(&'a mut self, int32: i32) -> &'a mut Encoder {
        self.uint32(unsafe { mem::transmute_copy(&int32) })
    }

    pub fn float32(&'a mut self, float32: f32) -> &'a mut Encoder {
        self.uint32(unsafe { mem::transmute_copy(&float32) })
    }

    pub fn float64(&'a mut self, float64: f64) -> &'a mut Encoder {
        let uint64: u64 = unsafe { mem::transmute_copy(&float64) };
        return self
            .uint32((uint64 >> 32) as u32)
            .uint32((uint64 & 0xFFFFFFFF) as u32);
    }

    pub fn size(&'a mut self, size: usize) -> &'a mut Encoder {
        if size > 0x3FFFFFFF {
            self.chunks.push(Chunk::Error("[size] value is too large"));
        }

        // can fit on 7 bits
        if size < 0x80 {
            return self.uint8(size as u8);
        }

        // can fit on 14 bits
        if size < 0x4000 {
            return self.uint16((size as u16) | 0x8000);
        }

        // use up to 30 bits
        return self.uint32((size as u32) | 0xC0000000);
    }

    pub fn blob(&'a mut self, blob: &'a [u8]) -> &'a mut Encoder {
        let size = blob.len();
        if blob.len() > 0x3FFFFFFF {
            self.chunks.push(Chunk::Error("[blob] value is too long"));
            return self;
        }
        let sref = self.size(size);
        sref.capacity += size;
        sref.chunks.push(Chunk::Blob(blob));
        return sref;
    }

    pub fn string(&'a mut self, string: &'a str) -> &'a mut Encoder {
        self.blob(string.as_bytes())
    }

    pub fn encode(&'a self) -> Result<Vec<u8>, Error> {
        let mut data: Vec<u8> = Vec::with_capacity(self.capacity);

        for chunk in self.chunks.iter() {
            match chunk {
                &Chunk::Uint8(uint8) => data.push(uint8),
                &Chunk::Uint16(uint16) => {
                    data.push((uint16 >> 8) as u8);
                    data.push((uint16 & 0xFF) as u8);
                },
                &Chunk::Uint32(uint32) => {
                    data.push(((uint32) >> 24) as u8);
                    data.push((((uint32) >> 16) & 0xFF) as u8);
                    data.push((((uint32) >> 8) & 0xFF) as u8);
                    data.push(((uint32) & 0xFF) as u8);
                },
                &Chunk::Blob(blob) => data.extend_from_slice(blob),
                &Chunk::Error(msg) => return Err(Error(msg)),
            }
        }

        Ok(data)
    }
}

pub struct Decoder<'a> {
    index: usize,
    length: usize,
    data: &'a[u8],
}

impl<'a> Decoder<'a> {
    pub fn new(data: &[u8]) -> Decoder {
        Decoder {
            index: 0,
            length: data.len(),
            data: data,
        }
    }

    pub fn uint8(&mut self) -> Result<u8, Error<'a>> {
        if self.index >= self.length {
            return Err(Error::out_of_bounds());
        }
        let uint8 = self.data[self.index];
        self.index += 1;
        return Ok(uint8);
    }

    pub fn uint16(&mut self) -> Result<u16, Error<'a>> {
        Ok(
            (try!(self.uint8()) as u16) << 8 |
            (try!(self.uint8()) as u16)
        )
    }

    pub fn uint32(&mut self) -> Result<u32, Error<'a>> {
        Ok(
            (try!(self.uint8()) as u32) << 24 |
            (try!(self.uint8()) as u32) << 16 |
            (try!(self.uint8()) as u32) << 8  |
            (try!(self.uint8()) as u32)
        )
    }

    pub fn int8(&mut self) -> Result<i8, Error<'a>> {
        let uint8 = try!(self.uint8());
        Ok(unsafe { mem::transmute_copy(&uint8) })
    }

    pub fn int16(&mut self) -> Result<i16, Error<'a>> {
        let uint16 = try!(self.uint16());
        Ok(unsafe { mem::transmute_copy(&uint16) })
    }

    pub fn int32(&mut self) -> Result<i32, Error<'a>> {
        let uint32 = try!(self.uint32());
        Ok(unsafe { mem::transmute_copy(&uint32) })
    }

    pub fn float32(&mut self) -> Result<f32, Error<'a>> {
        let uint32 = try!(self.uint32());
        Ok(unsafe { mem::transmute_copy(&uint32) })
    }

    pub fn float64(&mut self) -> Result<f64, Error<'a>> {
        let uint64 = (try!(self.uint32()) as u64) << 32 |
                     (try!(self.uint32()) as u64);
        Ok(unsafe { mem::transmute_copy(&uint64) })
    }

    pub fn size(&mut self) -> Result<usize, Error<'a>> {
        let mut size: usize = try!(self.uint8()) as usize;

        // 1 byte (no signature)
        if (size & 128) == 0 {
            return Ok(size);
        }

        let sig: u8 = (size as u8) >> 6;
        // remove signature from the first byte
        size = size & 63 /* 00111111 */;

        // 2 bytes (signature is 10)
        if sig == 2 {
            return Ok(size << 8 | try!(self.uint8()) as usize);
        }

        Ok(
            size << 24                          |
            (try!(self.uint8()) as usize) << 16 |
            (try!(self.uint8()) as usize) << 8  |
            (try!(self.uint8()) as usize)
        )
    }

    pub fn blob(&mut self) -> Result<Vec<u8>, Error<'a>> {
        let size = try!(self.size());
        if self.index + size >= self.length {
            return Err(Error::out_of_bounds());
        }

        let blob = self.data[self.index .. self.index + size].to_vec();

        self.index += size;

        return Ok(blob);
    }

    pub fn string(&mut self) -> Result<String, Error<'a>> {
        let blob = try!(self.blob());
        return match String::from_utf8(blob) {
            Ok(string) => Ok(string),
            Err(_) => Err(Error("Couldn't decode UTF-8 string")),
        }
    }
}
<|endoftext|>


<commit_before>// DOCS

extern crate tempdir;

use std::error::Error as ErrorTrait;
use std::fmt;
use std::io;
use std::fs;
use std::borrow::Borrow;
use std::path;
use std::convert::AsRef;

use tempdir::TempDir;

pub use OverwriteBehavior::{AllowOverwrite, DisallowOverwrite};

#[derive(Clone,Copy)]
pub enum OverwriteBehavior {
    /// Overwrite files silently.
    AllowOverwrite,

    /// Don't overwrite files. `AtomicFile.write` will raise errors for such conditions only after
    /// you've already written your data.
    DisallowOverwrite
}

/// Represents an error raised by `AtomicFile.write`.
#[derive(Debug)]
pub enum Error<E> {
    /// The error originated in the library itself, while it was either creating a temporary file
    /// or moving the file into place.
    Internal(io::Error),
    /// The error originated in the user-supplied callback.
    User(E)
}

impl From<Error<io::Error>> for io::Error {
    fn from(e: Error<io::Error>) -> Self {
        match e {
            Error::Internal(x) => x,
            Error::User(x) => x
        }
    }
}

impl<E: fmt::Display> fmt::Display for Error<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Internal(ref e) => e.fmt(f),
            Error::User(ref e) => e.fmt(f)
        }
    }
}

impl<E: ErrorTrait> ErrorTrait for Error<E> {
    fn description(&self) -> &str {
        match *self {
            Error::Internal(ref e) => e.description(),
            Error::User(ref e) => e.description()
        }
    }

    fn cause(&self) -> Option<&ErrorTrait> {
        match *self {
            Error::Internal(ref e) => Some(e),
            Error::User(ref e) => Some(e)
        }
    }
}

pub struct AtomicFile {
    path: path::PathBuf,
    overwrite: OverwriteBehavior,
    tmpdir: path::PathBuf
}

impl AtomicFile {
    /// Helper for writing to `path` in write-only mode.
    ///
    /// If `DisallowOverwrite` is given, errors will be returned from `self.write(...)` if the file
    /// exists.
    pub fn new<P: AsRef<path::Path>>(path: P, overwrite: OverwriteBehavior) -> Self {
        let p = path.as_ref();
        AtomicFile::new_with_tmpdir(p, overwrite, p.parent().unwrap_or(p))
    }

    pub fn new_with_tmpdir<P: AsRef<path::Path>>(path: P, overwrite: OverwriteBehavior, tmpdir: P) -> Self {
        AtomicFile {
            path: path.as_ref().to_path_buf(),
            overwrite: overwrite,
            tmpdir: tmpdir.as_ref().to_path_buf()
        }
    }

    fn commit(&self, tmppath: &path::Path) -> io::Result<()> {
        match self.overwrite {
            AllowOverwrite => replace_atomic(tmppath, self.path()),
            DisallowOverwrite => move_atomic(tmppath, self.path())
        }
    }

    /// Get the target filepath.
    pub fn path(&self) -> &path::Path { &self.path.borrow() }

    /// Open a temporary file, call `f` on it (which is supposed to write to it), then move the
    /// file atomically to `self.path`.
    pub fn write<T, E, F>(&self, f: F) -> Result<T, Error<E>> where
        F: FnOnce(&mut fs::File) -> Result<T, E>
    {
        let tmpdir = try!(TempDir::new_in(
            &self.tmpdir,
            ".atomicwrite"
        ).map_err(Error::Internal));

        let tmppath = tmpdir.path().join("tmpfile.tmp");
        let rv = {
            let mut tmpfile = try!(fs::File::create(&tmppath).map_err(Error::Internal));
            try!(f(&mut tmpfile).map_err(Error::User))
        };
        try!(self.commit(&tmppath).map_err(Error::Internal));
        Ok(rv)
    }
}

#[cfg(unix)]
mod imp {
    extern crate nix;

    use std::{io,fs,path};
    use std::os::unix::io::AsRawFd;

    fn fsync<T: AsRawFd>(f: T) -> io::Result<()> {
        match nix::unistd::fsync(f.as_raw_fd()) {
            Ok(()) => Ok(()),
            Err(e) => {
                let io_error = if let nix::Error::Sys(errno) = e {
                    errno.into()
                } else {
                    let desc = match e {
                        nix::Error::Sys(_) => unreachable!(),
                        nix::Error::InvalidPath => "invalid path",
                        nix::Error::InvalidUtf8 => "invalid utf-8",
                        nix::Error::UnsupportedOperation => "unsupported operation",
                    };

                    io::Error::new(io::ErrorKind::Other, desc)
                };

                Err(io_error)
            }
        }
    }

    fn fsync_dir(x: &path::Path) -> io::Result<()> {
        let f = try!(fs::File::open(x));
        try!(fsync(f));
        Ok(())
    }

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        try!(fs::rename(src, dst));

        let dst_directory = dst.parent().unwrap();
        try!(fsync_dir(dst_directory));
        Ok(())
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        try!(fs::hard_link(src, dst));
        try!(fs::remove_file(src));

        let src_directory = src.parent().unwrap();
        let dst_directory = dst.parent().unwrap();
        try!(fsync_dir(dst_directory));
        if src_directory != dst_directory { try!(fsync_dir(src_directory)); }
        Ok(())
    }
}

#[cfg(windows)]
mod imp {
    extern crate winapi;
    extern crate kernel32 as win32kernel;

    use std::{io,path};
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    macro_rules! call {
        ($e: expr) => (
            if $e != 0 {
                Ok(())
            } else {
                Err(io::Error::last_os_error())
            }
        )
    }

    fn path_to_windows_str<T: AsRef<OsStr>>(x: T) -> Vec<winapi::WCHAR> {
        x.as_ref().encode_wide().chain(Some(0)).collect()
    }

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {win32kernel::MoveFileExW(
            path_to_windows_str(src).as_ptr(), path_to_windows_str(dst).as_ptr(),
            winapi::MOVEFILE_WRITE_THROUGH | winapi::MOVEFILE_REPLACE_EXISTING
        )})
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {win32kernel::MoveFileExW(
            path_to_windows_str(src).as_ptr(), path_to_windows_str(dst).as_ptr(),
            winapi::MOVEFILE_WRITE_THROUGH
        )})
    }
}

/// Move `src` to `dst`. If `dst` exists, it will be silently overwritten.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::replace_atomic(src, dst)
}

/// Move `src` to `dst`. An error will be returned if `dst` exists.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::move_atomic(src, dst)
}
<commit_msg>Simplify errorhandling<commit_after>// DOCS

extern crate tempdir;

use std::error::Error as ErrorTrait;
use std::fmt;
use std::io;
use std::fs;
use std::borrow::Borrow;
use std::path;
use std::convert::AsRef;

use tempdir::TempDir;

pub use OverwriteBehavior::{AllowOverwrite, DisallowOverwrite};

#[derive(Clone,Copy)]
pub enum OverwriteBehavior {
    /// Overwrite files silently.
    AllowOverwrite,

    /// Don't overwrite files. `AtomicFile.write` will raise errors for such conditions only after
    /// you've already written your data.
    DisallowOverwrite
}

/// Represents an error raised by `AtomicFile.write`.
#[derive(Debug)]
pub enum Error<E> {
    /// The error originated in the library itself, while it was either creating a temporary file
    /// or moving the file into place.
    Internal(io::Error),
    /// The error originated in the user-supplied callback.
    User(E)
}

impl From<Error<io::Error>> for io::Error {
    fn from(e: Error<io::Error>) -> Self {
        match e {
            Error::Internal(x) => x,
            Error::User(x) => x
        }
    }
}

impl<E: fmt::Display> fmt::Display for Error<E> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Internal(ref e) => e.fmt(f),
            Error::User(ref e) => e.fmt(f)
        }
    }
}

impl<E: ErrorTrait> ErrorTrait for Error<E> {
    fn description(&self) -> &str {
        match *self {
            Error::Internal(ref e) => e.description(),
            Error::User(ref e) => e.description()
        }
    }

    fn cause(&self) -> Option<&ErrorTrait> {
        match *self {
            Error::Internal(ref e) => Some(e),
            Error::User(ref e) => Some(e)
        }
    }
}

pub struct AtomicFile {
    path: path::PathBuf,
    overwrite: OverwriteBehavior,
    tmpdir: path::PathBuf
}

impl AtomicFile {
    /// Helper for writing to `path` in write-only mode.
    ///
    /// If `DisallowOverwrite` is given, errors will be returned from `self.write(...)` if the file
    /// exists.
    pub fn new<P: AsRef<path::Path>>(path: P, overwrite: OverwriteBehavior) -> Self {
        let p = path.as_ref();
        AtomicFile::new_with_tmpdir(p, overwrite, p.parent().unwrap_or(p))
    }

    pub fn new_with_tmpdir<P: AsRef<path::Path>>(path: P, overwrite: OverwriteBehavior, tmpdir: P) -> Self {
        AtomicFile {
            path: path.as_ref().to_path_buf(),
            overwrite: overwrite,
            tmpdir: tmpdir.as_ref().to_path_buf()
        }
    }

    fn commit(&self, tmppath: &path::Path) -> io::Result<()> {
        match self.overwrite {
            AllowOverwrite => replace_atomic(tmppath, self.path()),
            DisallowOverwrite => move_atomic(tmppath, self.path())
        }
    }

    /// Get the target filepath.
    pub fn path(&self) -> &path::Path { &self.path.borrow() }

    /// Open a temporary file, call `f` on it (which is supposed to write to it), then move the
    /// file atomically to `self.path`.
    pub fn write<T, E, F>(&self, f: F) -> Result<T, Error<E>> where
        F: FnOnce(&mut fs::File) -> Result<T, E>
    {
        let tmpdir = try!(TempDir::new_in(
            &self.tmpdir,
            ".atomicwrite"
        ).map_err(Error::Internal));

        let tmppath = tmpdir.path().join("tmpfile.tmp");
        let rv = {
            let mut tmpfile = try!(fs::File::create(&tmppath).map_err(Error::Internal));
            try!(f(&mut tmpfile).map_err(Error::User))
        };
        try!(self.commit(&tmppath).map_err(Error::Internal));
        Ok(rv)
    }
}

#[cfg(unix)]
mod imp {
    extern crate nix;

    use std::{io,fs,path};
    use std::os::unix::io::AsRawFd;

    fn fsync<T: AsRawFd>(f: T) -> io::Result<()> {
        match nix::unistd::fsync(f.as_raw_fd()) {
            Ok(()) => Ok(()),
            Err(nix::Error::Sys(errno)) => Err(errno.into()),
            Err(nix::Error::InvalidPath) => Err(io::Error::new(io::ErrorKind::Other, "invalid path")),
            Err(nix::Error::InvalidUtf8) => Err(io::Error::new(io::ErrorKind::Other, "invalid utf-8")),
            Err(nix::Error::UnsupportedOperation) => Err(io::Error::new(io::ErrorKind::Other, "unsupported operation"))
        }
    }

    fn fsync_dir(x: &path::Path) -> io::Result<()> {
        let f = try!(fs::File::open(x));
        try!(fsync(f));
        Ok(())
    }

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        try!(fs::rename(src, dst));

        let dst_directory = dst.parent().unwrap();
        try!(fsync_dir(dst_directory));
        Ok(())
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        try!(fs::hard_link(src, dst));
        try!(fs::remove_file(src));

        let src_directory = src.parent().unwrap();
        let dst_directory = dst.parent().unwrap();
        try!(fsync_dir(dst_directory));
        if src_directory != dst_directory { try!(fsync_dir(src_directory)); }
        Ok(())
    }
}

#[cfg(windows)]
mod imp {
    extern crate winapi;
    extern crate kernel32 as win32kernel;

    use std::{io,path};
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    macro_rules! call {
        ($e: expr) => (
            if $e != 0 {
                Ok(())
            } else {
                Err(io::Error::last_os_error())
            }
        )
    }

    fn path_to_windows_str<T: AsRef<OsStr>>(x: T) -> Vec<winapi::WCHAR> {
        x.as_ref().encode_wide().chain(Some(0)).collect()
    }

    pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {win32kernel::MoveFileExW(
            path_to_windows_str(src).as_ptr(), path_to_windows_str(dst).as_ptr(),
            winapi::MOVEFILE_WRITE_THROUGH | winapi::MOVEFILE_REPLACE_EXISTING
        )})
    }

    pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
        call!(unsafe {win32kernel::MoveFileExW(
            path_to_windows_str(src).as_ptr(), path_to_windows_str(dst).as_ptr(),
            winapi::MOVEFILE_WRITE_THROUGH
        )})
    }
}

/// Move `src` to `dst`. If `dst` exists, it will be silently overwritten.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn replace_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::replace_atomic(src, dst)
}

/// Move `src` to `dst`. An error will be returned if `dst` exists.
///
/// Both paths must reside on the same filesystem for the operation to be atomic.
pub fn move_atomic(src: &path::Path, dst: &path::Path) -> io::Result<()> {
    imp::move_atomic(src, dst)
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod test {
    #[test]
    fn it_works() {
    }
}
<commit_msg>deleted test... for now<commit_after>pub mod decimal;
<|endoftext|>


<commit_before>//! Library to extract the raw data and some metadata from digital camera
//! images. Given an image in a supported format and camera you will be able to get
//! everything needed to process the image
//!
//! # Example
//! ```rust,no_run
//! use std::env;
//! use std::fs::File;
//! use std::io::prelude::*;
//! use std::io::BufWriter;
//!
//! extern crate rawloader;
//!
//! fn main() {
//!   let args: Vec<_> = env::args().collect();
//!   if args.len() != 2 {
//!     println!("Usage: {} <file>", args[0]);
//!     std::process::exit(2);
//!   }
//!   let file = &args[1];
//!   let image = rawloader::decode_file(file).unwrap();
//!
//!   // Write out the image as a grayscale PPM
//!   let mut f = BufWriter::new(File::create(format!("{}.ppm",file)).unwrap());
//!   let preamble = format!("P6 {} {} {}\n", image.width, image.height, 65535).into_bytes();
//!   f.write_all(&preamble).unwrap();
//!   if let rawloader::RawImageData::Integer(data) = image.data {
//!     for pix in data {
//!       // Do an extremely crude "demosaic" by setting R=G=B
//!       let pixhigh = (pix>>8) as u8;
//!       let pixlow  = (pix&0x0f) as u8;
//!       f.write_all(&[pixhigh, pixlow, pixhigh, pixlow, pixhigh, pixlow]).unwrap()
//!     }
//!   } else {
//!     eprintln!("Don't know how to process non-integer raw files");
//!   }
//! }
//! ```

#![deny(
  missing_docs,
  missing_debug_implementations,
  missing_copy_implementations,
  unsafe_code,
  unstable_features,
  unused_import_braces,
  unused_qualifications
)]

#[macro_use] extern crate enum_primitive;
extern crate num;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate serde_derive;
extern crate itertools;

mod decoders;
pub use decoders::RawImage;
pub use decoders::RawImageData;
pub use decoders::Orientation;
pub use decoders::cfa::CFA;
#[doc(hidden)] pub use decoders::Buffer;
#[doc(hidden)] pub use decoders::RawLoader;

lazy_static! {
  static ref LOADER: RawLoader = decoders::RawLoader::new();
}

use std::path::Path;
use std::error::Error;
use std::fmt;
use std::io::Read;

/// Error type for any reason for the decode to fail
#[derive(Debug)]
pub struct RawLoaderError {
  msg: String,
}

impl fmt::Display for RawLoaderError {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "RawLoaderError: \"{}\"", self.msg)
  }
}

impl Error for RawLoaderError {
}

impl RawLoaderError {
  fn new(msg: String) -> Self {
    Self {
      msg,
    }
  }
}

/// Take a path to a raw file and return a decoded image or an error
///
/// # Example
/// ```rust,ignore
/// let image = match rawloader::decode_file("path/to/your/file.RAW") {
///   Ok(val) => val,
///   Err(e) => ... some appropriate action when the file is unreadable ...
/// };
/// ```
pub fn decode_file<P: AsRef<Path>>(path: P) -> Result<RawImage,RawLoaderError> {
  LOADER.decode_file(path.as_ref()).map_err(|err| RawLoaderError::new(err))
}

/// Take a readable source and return a decoded image or an error
///
/// # Example
/// ```rust,ignore
/// let mut file = match File::open(path).unwrap();
/// let image = match rawloader::decode(&mut file) {
///   Ok(val) => val,
///   Err(e) => ... some appropriate action when the file is unreadable ...
/// };
/// ```
pub fn decode(reader: &mut Read) -> Result<RawImage,RawLoaderError> {
  LOADER.decode(reader).map_err(|err| RawLoaderError::new(err))
}
<commit_msg>description() in Error for older versions of rust<commit_after>//! Library to extract the raw data and some metadata from digital camera
//! images. Given an image in a supported format and camera you will be able to get
//! everything needed to process the image
//!
//! # Example
//! ```rust,no_run
//! use std::env;
//! use std::fs::File;
//! use std::io::prelude::*;
//! use std::io::BufWriter;
//!
//! extern crate rawloader;
//!
//! fn main() {
//!   let args: Vec<_> = env::args().collect();
//!   if args.len() != 2 {
//!     println!("Usage: {} <file>", args[0]);
//!     std::process::exit(2);
//!   }
//!   let file = &args[1];
//!   let image = rawloader::decode_file(file).unwrap();
//!
//!   // Write out the image as a grayscale PPM
//!   let mut f = BufWriter::new(File::create(format!("{}.ppm",file)).unwrap());
//!   let preamble = format!("P6 {} {} {}\n", image.width, image.height, 65535).into_bytes();
//!   f.write_all(&preamble).unwrap();
//!   if let rawloader::RawImageData::Integer(data) = image.data {
//!     for pix in data {
//!       // Do an extremely crude "demosaic" by setting R=G=B
//!       let pixhigh = (pix>>8) as u8;
//!       let pixlow  = (pix&0x0f) as u8;
//!       f.write_all(&[pixhigh, pixlow, pixhigh, pixlow, pixhigh, pixlow]).unwrap()
//!     }
//!   } else {
//!     eprintln!("Don't know how to process non-integer raw files");
//!   }
//! }
//! ```

#![deny(
  missing_docs,
  missing_debug_implementations,
  missing_copy_implementations,
  unsafe_code,
  unstable_features,
  unused_import_braces,
  unused_qualifications
)]

#[macro_use] extern crate enum_primitive;
extern crate num;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate serde_derive;
extern crate itertools;

mod decoders;
pub use decoders::RawImage;
pub use decoders::RawImageData;
pub use decoders::Orientation;
pub use decoders::cfa::CFA;
#[doc(hidden)] pub use decoders::Buffer;
#[doc(hidden)] pub use decoders::RawLoader;

lazy_static! {
  static ref LOADER: RawLoader = decoders::RawLoader::new();
}

use std::path::Path;
use std::error::Error;
use std::fmt;
use std::io::Read;

/// Error type for any reason for the decode to fail
#[derive(Debug)]
pub struct RawLoaderError {
  msg: String,
}

impl fmt::Display for RawLoaderError {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "RawLoaderError: \"{}\"", self.msg)
  }
}

impl Error for RawLoaderError {
  // Implement description so that older versions of rust still work
  fn description(&self) -> &str {
    "description() is deprecated; use Display"
  }
}

impl RawLoaderError {
  fn new(msg: String) -> Self {
    Self {
      msg,
    }
  }
}

/// Take a path to a raw file and return a decoded image or an error
///
/// # Example
/// ```rust,ignore
/// let image = match rawloader::decode_file("path/to/your/file.RAW") {
///   Ok(val) => val,
///   Err(e) => ... some appropriate action when the file is unreadable ...
/// };
/// ```
pub fn decode_file<P: AsRef<Path>>(path: P) -> Result<RawImage,RawLoaderError> {
  LOADER.decode_file(path.as_ref()).map_err(|err| RawLoaderError::new(err))
}

/// Take a readable source and return a decoded image or an error
///
/// # Example
/// ```rust,ignore
/// let mut file = match File::open(path).unwrap();
/// let image = match rawloader::decode(&mut file) {
///   Ok(val) => val,
///   Err(e) => ... some appropriate action when the file is unreadable ...
/// };
/// ```
pub fn decode(reader: &mut Read) -> Result<RawImage,RawLoaderError> {
  LOADER.decode(reader).map_err(|err| RawLoaderError::new(err))
}
<|endoftext|>


<commit_before>#![feature(str_char)]

//TODO: Rewrite to iterators

pub fn splits<'l,T,F: FnMut(&'l str,&'l str) -> Option<T>>(s: &'l str,mut search: F) -> Option<T>{
	let mut begin = "";
	let mut end   = s;

	loop{
		if end.is_empty(){
			return None
		}

		let head_len = end.char_at(0).len_utf8();
		begin = unsafe{s.slice_unchecked(0,begin.len() + head_len)};
		end = unsafe{end.slice_unchecked(head_len,end.len())};

		if let Some(data) = search(begin,end){
			return Some(data);
		}
	}
}

pub fn splits_char<'l,T,F: FnMut(char,&'l str,&'l str) -> Option<T>>(s: &'l str,mut search: F) -> Option<T>{
	let mut begin = "";
	let mut end   = s;

	loop{
		if end.is_empty(){
			return None
		}

		let c = end.char_at(0);
		let c_len = c.len_utf8();

		end   = unsafe{end.slice_unchecked(c_len,end.len())};

		if let Some(data) = search(c,begin,end){
			return Some(data);
		}

		begin = unsafe{s.slice_unchecked(0,begin.len() + c_len)};
	}
}

#[test]
fn test_splits(){
	let mut i = 0;
	assert!(splits("0123456789",|begin,end|{
		match i{
			0 => {assert_eq!(begin,"0");assert_eq!(end,"123456789");},
			1 => {assert_eq!(begin,"01");assert_eq!(end,"23456789");},
			2 => {assert_eq!(begin,"012");assert_eq!(end,"3456789");},
			3 => {assert_eq!(begin,"0123");assert_eq!(end,"456789");},
			4 => {assert_eq!(begin,"01234");assert_eq!(end,"56789");},
			5 => {assert_eq!(begin,"012345");assert_eq!(end,"6789");},
			6 => {assert_eq!(begin,"0123456");assert_eq!(end,"789");},
			7 => {assert_eq!(begin,"01234567");assert_eq!(end,"89");},
			8 => {assert_eq!(begin,"012345678");assert_eq!(end,"9");},
			9 => {assert_eq!(begin,"0123456789");assert_eq!(end,"");},
			_ => unreachable!()
		}
		i+=1;
		Some(())
	}).is_some());
}

#[test]
fn test_splits_char(){
	let mut i = 0;
	assert!(splits_char("0123456789",|c,begin,end|{
		match i{
			0 => {assert_eq!(begin,"");assert_eq!(c,'0');assert_eq!(end,"123456789");},
			1 => {assert_eq!(begin,"0");assert_eq!(c,'1');assert_eq!(end,"23456789");},
			2 => {assert_eq!(begin,"01");assert_eq!(c,'2');assert_eq!(end,"3456789");},
			3 => {assert_eq!(begin,"012");assert_eq!(c,'3');assert_eq!(end,"456789");},
			4 => {assert_eq!(begin,"0123");assert_eq!(c,'4');assert_eq!(end,"56789");},
			5 => {assert_eq!(begin,"01234");assert_eq!(c,'5');assert_eq!(end,"6789");},
			6 => {assert_eq!(begin,"012345");assert_eq!(c,'6');assert_eq!(end,"789");},
			7 => {assert_eq!(begin,"0123456");assert_eq!(c,'7');assert_eq!(end,"89");},
			8 => {assert_eq!(begin,"01234567");assert_eq!(c,'8');assert_eq!(end,"9");},
			9 => {assert_eq!(begin,"012345678");assert_eq!(c,'9');assert_eq!(end,"");},
			_ => unreachable!()
		}
		i+=1;
		Some(())
	}).is_some());
}
<commit_msg>Rewrite to iterators<commit_after>#![feature(core,str_char)]

extern crate core;

use core::iter::Iterator;

pub struct Splits<'l>{
	str  : &'l str,
	begin: &'l str,
	end  : &'l str
}

impl<'l> Splits<'l>{
	pub fn from_str(str: &'l str) -> Self{
		Splits{
			str  : str,
			begin: "",
			end  : str
		}
	}
}

impl<'l> Iterator for Splits<'l>{
	type Item = (&'l str,&'l str);

	fn next(&mut self) -> Option<<Self as Iterator>::Item>{
		if self.end.is_empty(){
			None
		}else{
			let head_len = self.end.char_at(0).len_utf8();
			self.begin = unsafe{self.str.slice_unchecked(0,self.begin.len() + head_len)};
			self.end = unsafe{self.end.slice_unchecked(head_len,self.end.len())};

			Some((self.begin,self.end))
		}
	}
}

pub struct SplitsChar<'l>{
	str  : &'l str,
	begin: &'l str,
	end  : &'l str
}

impl<'l> SplitsChar<'l>{
	pub fn from_str(str: &'l str) -> Self{
		SplitsChar{
			str  : str,
			begin: "",
			end  :  str
		}
	}
}

impl<'l> Iterator for SplitsChar<'l>{
	type Item = (&'l str,char,&'l str);

	fn next(&mut self) -> Option<<Self as Iterator>::Item>{
		if self.end.is_empty(){
			None
		}else{
			let c = self.end.char_at(0);
			let c_len = c.len_utf8();

			self.end = unsafe{self.end.slice_unchecked(c_len,self.end.len())};
			let begin = self.begin;
			self.begin = unsafe{self.str.slice_unchecked(0,self.begin.len() + c_len)};

			Some((begin,c,self.end))
		}
	}
}

#[test]
fn test_splits(){
	let mut splits = Splits::from_str("0123456789");
	/*01*/assert_eq!(splits.next().unwrap(),("0","123456789"));
	/*02*/assert_eq!(splits.next().unwrap(),("01","23456789"));
	/*03*/assert_eq!(splits.next().unwrap(),("012","3456789"));
	/*04*/assert_eq!(splits.next().unwrap(),("0123","456789"));
	/*05*/assert_eq!(splits.next().unwrap(),("01234","56789"));
	/*06*/assert_eq!(splits.next().unwrap(),("012345","6789"));
	/*07*/assert_eq!(splits.next().unwrap(),("0123456","789"));
	/*08*/assert_eq!(splits.next().unwrap(),("01234567","89"));
	/*09*/assert_eq!(splits.next().unwrap(),("012345678","9"));
	/*10*/assert_eq!(splits.next().unwrap(),("0123456789",""));
	/*11*/assert!(splits.next().is_none());
}

#[test]
fn test_splits_char(){
	let mut splits = SplitsChar::from_str("0123456789");
	/*01*/assert_eq!(splits.next().unwrap(),("",'0',"123456789"));
	/*02*/assert_eq!(splits.next().unwrap(),("0",'1',"23456789"));
	/*03*/assert_eq!(splits.next().unwrap(),("01",'2',"3456789"));
	/*04*/assert_eq!(splits.next().unwrap(),("012",'3',"456789"));
	/*05*/assert_eq!(splits.next().unwrap(),("0123",'4',"56789"));
	/*06*/assert_eq!(splits.next().unwrap(),("01234",'5',"6789"));
	/*07*/assert_eq!(splits.next().unwrap(),("012345",'6',"789"));
	/*08*/assert_eq!(splits.next().unwrap(),("0123456",'7',"89"));
	/*09*/assert_eq!(splits.next().unwrap(),("01234567",'8',"9"));
	/*10*/assert_eq!(splits.next().unwrap(),("012345678",'9',""));
	/*11*/assert!(splits.next().is_none());
}
<|endoftext|>


<commit_before>//! Providing the features between "full" and "derive" of syn.
//!
//! This crate provides the following two unique data structures.
//!
//! * [`syn_mid::ItemFn`] -- A function whose body is not parsed.
//!
//!   ```text
//!   fn process(n: usize) -> Result<()> { ... }
//!   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^     ^
//!   ```
//!
//! * [`syn_mid::Block`] -- A block whose body is not parsed.
//!
//!   ```text
//!   { ... }
//!   ^     ^
//!   ```
//!
//! Other data structures are the same as data structures of [syn]. These are defined in this crate
//! because they cannot be used in [syn] without "full" feature.
//!
//! ## Optional features
//!
//! syn-mid in the default features aims to provide the features between "full"
//! and "derive" of [syn].
//!
//! * **`clone-impls`** — Clone impls for all syntax tree types.
//!
//! [`syn_mid::ItemFn`]: struct.ItemFn.html
//! [`syn_mid::Block`]: struct.Block.html
//! [syn]: https://github.com/dtolnay/syn
//!

#![doc(html_root_url = "https://docs.rs/syn-mid/0.4.0")]
#![doc(test(
    no_crate_inject,
    attr(
        deny(warnings, rust_2018_idioms, single_use_lifetimes),
        allow(dead_code)
    )
))]
#![warn(unsafe_code)]
#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
#![warn(clippy::all, clippy::pedantic)]
#![allow(
    clippy::eval_order_dependence,
    clippy::large_enum_variant,
    clippy::module_name_repetitions,
    clippy::use_self
)]

// Many of the code contained in this crate are copies from https://github.com/dtolnay/syn.

#[macro_use]
mod macros;

mod arg;
mod pat;
mod path;

pub use self::arg::*;
pub use self::pat::*;

use proc_macro2::TokenStream;
use syn::{
    punctuated::Punctuated, token, Abi, Attribute, Generics, Ident, ReturnType, Token, Visibility,
};

ast_struct! {
    /// A braced block containing Rust statements.
    pub struct Block {
        pub brace_token: token::Brace,
        /// Statements in a block
        pub stmts: TokenStream,
    }
}

ast_struct! {
    /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
    /// }`.
    pub struct ItemFn {
        pub attrs: Vec<Attribute>,
        pub vis: Visibility,
        pub constness: Option<Token![const]>,
        pub asyncness: Option<Token![async]>,
        pub unsafety: Option<Token![unsafe]>,
        pub abi: Option<Abi>,
        pub fn_token: Token![fn],
        pub ident: Ident,
        pub generics: Generics,
        pub paren_token: token::Paren,
        pub inputs: Punctuated<FnArg, Token![,]>,
        pub output: ReturnType,
        pub block: Block,
    }
}

mod parsing {
    use syn::{
        braced, parenthesized,
        parse::{Parse, ParseStream, Result},
        Abi, Attribute, Generics, Ident, ReturnType, Token, Visibility, WhereClause,
    };

    use super::{Block, FnArg, ItemFn};

    impl Parse for Block {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let content;
            Ok(Self {
                brace_token: braced!(content in input),
                stmts: content.parse()?,
            })
        }
    }

    impl Parse for ItemFn {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let attrs = input.call(Attribute::parse_outer)?;
            let vis: Visibility = input.parse()?;
            let constness: Option<Token![const]> = input.parse()?;
            let asyncness: Option<Token![async]> = input.parse()?;
            let unsafety: Option<Token![unsafe]> = input.parse()?;
            let abi: Option<Abi> = input.parse()?;
            let fn_token: Token![fn] = input.parse()?;
            let ident: Ident = input.parse()?;
            let generics: Generics = input.parse()?;

            let content;
            let paren_token = parenthesized!(content in input);
            let inputs = content.parse_terminated(FnArg::parse)?;

            let output: ReturnType = input.parse()?;
            let where_clause: Option<WhereClause> = input.parse()?;

            let block = input.parse()?;

            Ok(Self {
                attrs,
                vis,
                constness,
                asyncness,
                unsafety,
                abi,
                fn_token,
                ident,
                generics: Generics {
                    where_clause,
                    ..generics
                },
                paren_token,
                inputs,
                output,
                block,
            })
        }
    }
}

mod printing {
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};

    use super::{Block, ItemFn};

    impl ToTokens for Block {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.brace_token.surround(tokens, |tokens| {
                tokens.append_all(self.stmts.clone());
            });
        }
    }

    impl ToTokens for ItemFn {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(&self.attrs);
            self.vis.to_tokens(tokens);
            self.constness.to_tokens(tokens);
            self.asyncness.to_tokens(tokens);
            self.unsafety.to_tokens(tokens);
            self.abi.to_tokens(tokens);
            self.fn_token.to_tokens(tokens);
            self.ident.to_tokens(tokens);
            self.generics.to_tokens(tokens);
            self.paren_token.surround(tokens, |tokens| {
                self.inputs.to_tokens(tokens);
            });
            self.output.to_tokens(tokens);
            self.generics.where_clause.to_tokens(tokens);
            self.block.brace_token.surround(tokens, |tokens| {
                tokens.append_all(self.block.stmts.clone());
            });
        }
    }
}
<commit_msg>Forbid unsafe code<commit_after>//! Providing the features between "full" and "derive" of syn.
//!
//! This crate provides the following two unique data structures.
//!
//! * [`syn_mid::ItemFn`] -- A function whose body is not parsed.
//!
//!   ```text
//!   fn process(n: usize) -> Result<()> { ... }
//!   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^     ^
//!   ```
//!
//! * [`syn_mid::Block`] -- A block whose body is not parsed.
//!
//!   ```text
//!   { ... }
//!   ^     ^
//!   ```
//!
//! Other data structures are the same as data structures of [syn]. These are defined in this crate
//! because they cannot be used in [syn] without "full" feature.
//!
//! ## Optional features
//!
//! syn-mid in the default features aims to provide the features between "full"
//! and "derive" of [syn].
//!
//! * **`clone-impls`** — Clone impls for all syntax tree types.
//!
//! [`syn_mid::ItemFn`]: struct.ItemFn.html
//! [`syn_mid::Block`]: struct.Block.html
//! [syn]: https://github.com/dtolnay/syn
//!

#![doc(html_root_url = "https://docs.rs/syn-mid/0.4.0")]
#![doc(test(
    no_crate_inject,
    attr(
        deny(warnings, rust_2018_idioms, single_use_lifetimes),
        allow(dead_code)
    )
))]
#![forbid(unsafe_code)]
#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
#![warn(clippy::all, clippy::pedantic)]
#![allow(
    clippy::eval_order_dependence,
    clippy::large_enum_variant,
    clippy::module_name_repetitions,
    clippy::use_self
)]

// Many of the code contained in this crate are copies from https://github.com/dtolnay/syn.

#[macro_use]
mod macros;

mod arg;
mod pat;
mod path;

pub use self::arg::*;
pub use self::pat::*;

use proc_macro2::TokenStream;
use syn::{
    punctuated::Punctuated, token, Abi, Attribute, Generics, Ident, ReturnType, Token, Visibility,
};

ast_struct! {
    /// A braced block containing Rust statements.
    pub struct Block {
        pub brace_token: token::Brace,
        /// Statements in a block
        pub stmts: TokenStream,
    }
}

ast_struct! {
    /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
    /// }`.
    pub struct ItemFn {
        pub attrs: Vec<Attribute>,
        pub vis: Visibility,
        pub constness: Option<Token![const]>,
        pub asyncness: Option<Token![async]>,
        pub unsafety: Option<Token![unsafe]>,
        pub abi: Option<Abi>,
        pub fn_token: Token![fn],
        pub ident: Ident,
        pub generics: Generics,
        pub paren_token: token::Paren,
        pub inputs: Punctuated<FnArg, Token![,]>,
        pub output: ReturnType,
        pub block: Block,
    }
}

mod parsing {
    use syn::{
        braced, parenthesized,
        parse::{Parse, ParseStream, Result},
        Abi, Attribute, Generics, Ident, ReturnType, Token, Visibility, WhereClause,
    };

    use super::{Block, FnArg, ItemFn};

    impl Parse for Block {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let content;
            Ok(Self {
                brace_token: braced!(content in input),
                stmts: content.parse()?,
            })
        }
    }

    impl Parse for ItemFn {
        fn parse(input: ParseStream<'_>) -> Result<Self> {
            let attrs = input.call(Attribute::parse_outer)?;
            let vis: Visibility = input.parse()?;
            let constness: Option<Token![const]> = input.parse()?;
            let asyncness: Option<Token![async]> = input.parse()?;
            let unsafety: Option<Token![unsafe]> = input.parse()?;
            let abi: Option<Abi> = input.parse()?;
            let fn_token: Token![fn] = input.parse()?;
            let ident: Ident = input.parse()?;
            let generics: Generics = input.parse()?;

            let content;
            let paren_token = parenthesized!(content in input);
            let inputs = content.parse_terminated(FnArg::parse)?;

            let output: ReturnType = input.parse()?;
            let where_clause: Option<WhereClause> = input.parse()?;

            let block = input.parse()?;

            Ok(Self {
                attrs,
                vis,
                constness,
                asyncness,
                unsafety,
                abi,
                fn_token,
                ident,
                generics: Generics {
                    where_clause,
                    ..generics
                },
                paren_token,
                inputs,
                output,
                block,
            })
        }
    }
}

mod printing {
    use proc_macro2::TokenStream;
    use quote::{ToTokens, TokenStreamExt};

    use super::{Block, ItemFn};

    impl ToTokens for Block {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.brace_token.surround(tokens, |tokens| {
                tokens.append_all(self.stmts.clone());
            });
        }
    }

    impl ToTokens for ItemFn {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            tokens.append_all(&self.attrs);
            self.vis.to_tokens(tokens);
            self.constness.to_tokens(tokens);
            self.asyncness.to_tokens(tokens);
            self.unsafety.to_tokens(tokens);
            self.abi.to_tokens(tokens);
            self.fn_token.to_tokens(tokens);
            self.ident.to_tokens(tokens);
            self.generics.to_tokens(tokens);
            self.paren_token.surround(tokens, |tokens| {
                self.inputs.to_tokens(tokens);
            });
            self.output.to_tokens(tokens);
            self.generics.where_clause.to_tokens(tokens);
            self.block.brace_token.surround(tokens, |tokens| {
                tokens.append_all(self.block.stmts.clone());
            });
        }
    }
}
<|endoftext|>


<commit_before>//! # Executable & Dynamic Library Paths
//! Utility functions to get the path of the currently executing
//! process or the the current dynamic library.
//!
//! The latter is particularly useful for ‘plug-in’ type dynamic
//! libraries that need to load resources stored relative to the
//! location of the library in the file system.
//! ## Example
//! ```
//! let path = process_path::get_executable_path();
//! match path {
//!     None => println!("The process path could not be determined"),
//!     Some(path) => println!("{:?}", path)
//! }
//! ```
//! ## Supported Platforms
//! * Linux
//! * FreeBSD
//! * NetBSD
//! * DragonflyBSD
//! * macOS
//! * Windows
use std::path::PathBuf;

#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "linux")]
use linux as os;

#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
use macos as os;

#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
mod bsd;
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
use bsd as os;

#[cfg(any(
    target_os = "linux",
    target_os = "freebsd",
    target_os = "dragonfly",
    target_os = "netbsd",
    target_os = "macos"
))]
mod nix;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use windows as os;

/// Gets the path of the currently running process. If the path cannot be determined,
/// `None` is returned.
#[inline]
pub fn get_executable_path() -> Option<PathBuf> {
    os::get_executable_path()
}

/// Gets the path of the current dynamic library. If the path cannot be determined,
/// `None` is returned.
#[inline]
pub fn get_dylib_path() -> Option<PathBuf> {
    #[cfg(target_os = "windows")]
    {
        os::get_dylib_path()
    }
    #[cfg(not(target_os = "windows"))]
    {
        nix::get_dylib_path()
    }
}
<commit_msg>add initial illumos support<commit_after>//! # Executable & Dynamic Library Paths
//! Utility functions to get the path of the currently executing
//! process or the the current dynamic library.
//!
//! The latter is particularly useful for ‘plug-in’ type dynamic
//! libraries that need to load resources stored relative to the
//! location of the library in the file system.
//! ## Example
//! ```
//! let path = process_path::get_executable_path();
//! match path {
//!     None => println!("The process path could not be determined"),
//!     Some(path) => println!("{:?}", path)
//! }
//! ```
//! ## Supported Platforms
//! * Linux
//! * FreeBSD
//! * NetBSD
//! * DragonflyBSD
//! * macOS
//! * Windows
//! * illumos
use std::path::PathBuf;

#[cfg(any(target_os = "linux", target_os = "illumos"))]
mod linux;
#[cfg(any(target_os = "linux", target_os = "illumos"))]
use linux as os;

#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
use macos as os;

#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
mod bsd;
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
use bsd as os;

#[cfg(any(
    target_os = "linux",
    target_os = "freebsd",
    target_os = "dragonfly",
    target_os = "netbsd",
    target_os = "macos",
    target_os = "illumos"
))]
mod nix;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use windows as os;

/// Gets the path of the currently running process. If the path cannot be determined,
/// `None` is returned.
#[inline]
pub fn get_executable_path() -> Option<PathBuf> {
    os::get_executable_path()
}

/// Gets the path of the current dynamic library. If the path cannot be determined,
/// `None` is returned.
#[inline]
pub fn get_dylib_path() -> Option<PathBuf> {
    #[cfg(target_os = "windows")]
    {
        os::get_dylib_path()
    }
    #[cfg(not(target_os = "windows"))]
    {
        nix::get_dylib_path()
    }
}
<|endoftext|>


<commit_before>#![deny(missing_doc)]

//! AI behavior tree

extern crate event;
extern crate input;
extern crate serialize;

pub use behavior::{
    Action,
    After,
    AlwaysSucceed,
    Behavior,
    If,
    Fail,
    Pressed,
    Released,
    Select,
    Sequence,
    Wait,
    WaitForever,
    WhenAll,
    WhenAny,
    While,
};
pub use state::State;
pub use status::{
    Failure,
    Status,
    Success,
    Running,
};

mod behavior;
mod state;
mod status;

<commit_msg>Fix missing_doc warning<commit_after>#![deny(missing_docs)]

//! AI behavior tree

extern crate event;
extern crate input;
extern crate serialize;

pub use behavior::{
    Action,
    After,
    AlwaysSucceed,
    Behavior,
    If,
    Fail,
    Pressed,
    Released,
    Select,
    Sequence,
    Wait,
    WaitForever,
    WhenAll,
    WhenAny,
    While,
};
pub use state::State;
pub use status::{
    Failure,
    Status,
    Success,
    Running,
};

mod behavior;
mod state;
mod status;
<|endoftext|>


<commit_before>extern crate ladspa;
extern crate mio;

use std::default::Default;
use std::thread;
use std::sync::mpsc::{self, sync_channel};
use std::mem;
use std::io::{Read, ErrorKind};

use mio::*;
use mio::tcp::{TcpStream, TcpListener};

use ladspa::{Port, PortDescriptor, PortConnection};
use ladspa::{PluginDescriptor, Plugin};
use ladspa::{PROP_NONE};
use ladspa::{HINT_INTEGER};
use ladspa::{DefaultValue};
use ladspa::Data;

const BUFFER_SIZE: usize = 1024;
const BASE_PORT: u16 = 21300;

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Packet {
    position: usize,
    data: [Data; BUFFER_SIZE],
}

impl Packet {
    pub fn parse(bytes: [u8; BUFFER_SIZE*4]) -> Packet {
        Packet {
            position: 0,
            data: unsafe { mem::transmute(bytes) },
        }
    }

    pub fn read(&mut self) -> Data {
        if self.position >= BUFFER_SIZE {
            return 0_f32;
        }
        let data = self.data[self.position];
        self.position += 1;
        data
    }

    pub fn active(&self) -> bool {
        self.position < BUFFER_SIZE
    }
}

struct Transmitter {
    sample_rate: u64,
    channel: u16,
}

impl Transmitter {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        Box::new(Transmitter {
            sample_rate: sample_rate,
            channel: 0,
        })
    }

    fn init_client(&mut self) {
        //TODO
    }

    fn kill_client(&mut self) {
        //TODO
    }
}

impl Plugin for Transmitter {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_client();
            self.init_client();
        }

        //TODO
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_client();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_client();
    }
}

struct PacketTransmitter {
    socket: TcpStream,
    //TODO
}

struct Receiver {
    sample_rate: u64,
    channel: u16,
    packet_rx: Option<mpsc::Receiver<Packet>>,
    active_packets: Vec<Packet>,
    notify_tx: Option<Sender<<PacketReceiver as Handler>::Message>>,
}

impl Receiver {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        println!("receiver::new");
        Box::new(Receiver {
            sample_rate: sample_rate,
            channel: 0,
            packet_rx: None,
            active_packets: Vec::new(),
            notify_tx: None,
        })
    }

    fn init_server(&mut self) {
        let (data_tx, data_rx) = sync_channel(16);
        self.packet_rx = Some(data_rx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let server = TcpListener::bind(&addr).unwrap();
            event_loop.register(&server, SERVER).unwrap();
            event_loop.run(&mut PacketReceiver {
                server: server,
                data_tx: data_tx,
            }).unwrap();
        });
    }

    fn kill_server(&mut self) {
        self.notify_tx.as_ref().unwrap().send(()).unwrap();
    }
}

impl Plugin for Receiver {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_server();
            self.init_server();
        }

        let recv = match self.packet_rx.as_ref() {
            Some(rx) => rx,
            None => panic!("packet_rx is None!"),
        };

        loop {
            let packet = match recv.try_recv() {
                Ok(packet) => packet,
                Err(_) => break,
            };
            self.active_packets.push(packet);
            println!("have data!");
        }

        for i in 0..sample_count {
            outputl[i] = inputl[i];
            outputr[i] = inputr[i];
            for packet in self.active_packets.iter_mut() {
                let val = packet.read();
                outputl[i] += val;
                outputr[i] += val;
            }
        }

        self.active_packets.retain(|x| x.active());
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_server();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_server();
    }
}

struct PacketReceiver {
    server: TcpListener,
    data_tx: mpsc::SyncSender<Packet>,
}

impl Handler for PacketReceiver {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("the server socket is ready to accept a connection");
                match self.server.accept() {
                    Ok(Some(mut socket)) => {
                        let tx = self.data_tx.clone();
                        loop {
                            let mut bytes = [0; BUFFER_SIZE*4];
                            let res = socket.read(&mut bytes);
                            match res {
                                Ok(size) => {
                                    if size == 0 {
                                        println!("zero buffer");
                                        return;
                                    }
                                }
                                Err(e) => {
                                    if e.kind() == ErrorKind::WouldBlock {
                                        continue;
                                    }
                                    panic!(e);
                                }
                            }
                            let packet = Packet::parse(bytes);
                            tx.send(packet).unwrap();
                            println!("recv data!");
                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            },
            _ => panic!("Received unknown token"),
        }
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        event_loop.shutdown();
    }
}

#[no_mangle]
pub extern fn get_ladspa_descriptor(index: u64) -> Option<PluginDescriptor> {
    match index {
        0 => Some(PluginDescriptor {
            unique_id: 5877,
            label: "feedback_tx",
            properties: PROP_NONE,
            name: "Feedback Transmitter",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Transmitter::new,
        }),
        1 => Some(PluginDescriptor {
            unique_id: 5878,
            label: "feedback_rx",
            properties: PROP_NONE,
            name: "Feedback Receiver",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Receiver::new,
        }),
        _ => None
    }
}
<commit_msg>keep reading until the whole buffer is full<commit_after>extern crate ladspa;
extern crate mio;

use std::default::Default;
use std::thread;
use std::sync::mpsc::{self, sync_channel};
use std::mem;
use std::io::{Read, ErrorKind};

use mio::*;
use mio::tcp::{TcpStream, TcpListener};

use ladspa::{Port, PortDescriptor, PortConnection};
use ladspa::{PluginDescriptor, Plugin};
use ladspa::{PROP_NONE};
use ladspa::{HINT_INTEGER};
use ladspa::{DefaultValue};
use ladspa::Data;

const BUFFER_SIZE: usize = 1024;
const BASE_PORT: u16 = 21300;

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Packet {
    position: usize,
    data: [Data; BUFFER_SIZE],
}

impl Packet {
    pub fn parse(bytes: [u8; BUFFER_SIZE*4]) -> Packet {
        Packet {
            position: 0,
            data: unsafe { mem::transmute(bytes) },
        }
    }

    pub fn read(&mut self) -> Data {
        if self.position >= BUFFER_SIZE {
            return 0_f32;
        }
        let data = self.data[self.position];
        self.position += 1;
        data
    }

    pub fn active(&self) -> bool {
        self.position < BUFFER_SIZE
    }
}

struct Transmitter {
    sample_rate: u64,
    channel: u16,
}

impl Transmitter {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        Box::new(Transmitter {
            sample_rate: sample_rate,
            channel: 0,
        })
    }

    fn init_client(&mut self) {
        //TODO
    }

    fn kill_client(&mut self) {
        //TODO
    }
}

impl Plugin for Transmitter {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_client();
            self.init_client();
        }

        //TODO
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_client();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_client();
    }
}

struct PacketTransmitter {
    socket: TcpStream,
    //TODO
}

struct Receiver {
    sample_rate: u64,
    channel: u16,
    packet_rx: Option<mpsc::Receiver<Packet>>,
    active_packets: Vec<Packet>,
    notify_tx: Option<Sender<<PacketReceiver as Handler>::Message>>,
}

impl Receiver {
    pub fn new(desc: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        println!("receiver::new");
        Box::new(Receiver {
            sample_rate: sample_rate,
            channel: 0,
            packet_rx: None,
            active_packets: Vec::new(),
            notify_tx: None,
        })
    }

    fn init_server(&mut self) {
        let (data_tx, data_rx) = sync_channel(16);
        self.packet_rx = Some(data_rx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let server = TcpListener::bind(&addr).unwrap();
            event_loop.register(&server, SERVER).unwrap();
            event_loop.run(&mut PacketReceiver {
                server: server,
                data_tx: data_tx,
            }).unwrap();
        });
    }

    fn kill_server(&mut self) {
        self.notify_tx.as_ref().unwrap().send(()).unwrap();
    }
}

impl Plugin for Receiver {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_server();
            self.init_server();
        }

        let recv = match self.packet_rx.as_ref() {
            Some(rx) => rx,
            None => panic!("packet_rx is None!"),
        };

        loop {
            let packet = match recv.try_recv() {
                Ok(packet) => packet,
                Err(_) => break,
            };
            self.active_packets.push(packet);
            println!("have data!");
        }

        for i in 0..sample_count {
            outputl[i] = inputl[i];
            outputr[i] = inputr[i];
            for packet in self.active_packets.iter_mut() {
                let val = packet.read();
                outputl[i] += val;
                outputr[i] += val;
            }
        }

        self.active_packets.retain(|x| x.active());
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.init_server();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_server();
    }
}

struct PacketReceiver {
    server: TcpListener,
    data_tx: mpsc::SyncSender<Packet>,
}

impl Handler for PacketReceiver {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut mio::EventLoop<Self>, token: mio::Token, events: mio::EventSet) {
        match token {
            SERVER => {
                // Only receive readable events
                assert!(events.is_readable());

                println!("the server socket is ready to accept a connection");
                match self.server.accept() {
                    Ok(Some(mut socket)) => {
                        let tx = self.data_tx.clone();
                        let mut buf = [0; BUFFER_SIZE*4];
                        let mut buf_pos = 0;
                        loop {
                            let res = socket.read(&mut buf[buf_pos..]);
                            match res {
                                Ok(num_read) => {
                                    // if we got a length zero read, the connection is done.
                                    if num_read == 0 {
                                        return;
                                    }

                                    // check if we've filled the buffer
                                    buf_pos += num_read;
                                    if buf_pos != BUFFER_SIZE*4 {
                                        continue;
                                    }
                                    buf_pos = 0;
                                }
                                Err(e) => {
                                    if e.kind() == ErrorKind::WouldBlock {
                                        continue;
                                    }
                                    panic!(e);
                                }
                            }
                            let packet = Packet::parse(buf);
                            tx.send(packet).unwrap();
                            println!("recv data!");
                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            },
            _ => panic!("Received unknown token"),
        }
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        event_loop.shutdown();
    }
}

#[no_mangle]
pub extern fn get_ladspa_descriptor(index: u64) -> Option<PluginDescriptor> {
    match index {
        0 => Some(PluginDescriptor {
            unique_id: 5877,
            label: "feedback_tx",
            properties: PROP_NONE,
            name: "Feedback Transmitter",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Transmitter::new,
        }),
        1 => Some(PluginDescriptor {
            unique_id: 5878,
            label: "feedback_rx",
            properties: PROP_NONE,
            name: "Feedback Receiver",
            maker: "Noah Weninger",
            copyright: "None",
            ports: vec![
                Port {
                    name: "Left Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio In",
                    desc: PortDescriptor::AudioInput,
                    ..Default::default()
                },
                Port {
                    name: "Left Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Right Audio Out",
                    desc: PortDescriptor::AudioOutput,
                    ..Default::default()
                },
                Port {
                    name: "Channel",
                    desc: PortDescriptor::ControlInput,
                    hint: Some(HINT_INTEGER),
                    default: Some(DefaultValue::Value0),
                    lower_bound: Some(0_f32),
                    upper_bound: Some(255_f32),
                }
            ],
            new: Receiver::new,
        }),
        _ => None
    }
}
<|endoftext|>


<commit_before>pub fn build_proverb(list: Vec<&str>) -> String {
    unimplemented!()
}
<commit_msg>proverb: eliminate stub warnings<commit_after>pub fn build_proverb(list: Vec<&str>) -> String {
    unimplemented!("build a proverb from this list of items: {:?}", list)
}
<|endoftext|>