positioned-io 0.2.1

Reading and writing at an offset
Documentation
use std::fs::File;
use std::io::{Result, Error, Write};
use std::ptr::null_mut;

use super::{ReadAt, WriteAt};

use std::os::windows::io::AsRawHandle;

extern crate kernel32;
extern crate winapi;
use self::winapi::{BOOL, DWORD, LPVOID};
use self::winapi::minwinbase::OVERLAPPED;
use self::kernel32::ReadFile;

fn result(e: BOOL) -> Result<()> {
    if e == 0 {
        Err(Error::last_os_error())
    } else {
        Ok(())
    }
}

fn overlapped(pos: u64) -> OVERLAPPED {
    OVERLAPPED {
        Internal: 0,
        InternalHigh: 0,
        Offset: pos as u32,
        OffsetHigh: (pos >> 32) as u32,
        hEvent: null_mut(),
    }
}

impl ReadAt for File {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> Result<usize> {
        let mut bytes: DWORD = 0;
        let mut ov = overlapped(pos);
        try!(result(unsafe {
            ReadFile(self.as_raw_handle(),
                     buf.as_mut_ptr() as LPVOID,
                     buf.len() as DWORD,
                     &mut bytes,
                     &mut ov)
        }));
        Ok(bytes as usize)
    }
}

impl WriteAt for File {
    fn write_at(&mut self, pos: u64, buf: &[u8]) -> Result<usize> {
        let mut bytes: DWORD = 0;
        let mut ov = overlapped(pos);
        try!(result(unsafe {
            ReadFile(self.as_raw_handle(),
                     buf.as_ptr() as LPVOID,
                     buf.len() as DWORD,
                     &mut bytes,
                     &mut ov)
        }));
        Ok(bytes as usize)
    }
    fn flush(&mut self) -> Result<()> {
        Write::flush(self)
    }
}