about summary refs log tree commit diff
path: root/src/libstd/rt/uv/uvio.rs
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2013-08-20 15:38:41 -0700
committerJeff Olson <olson.jeffery@gmail.com>2013-08-22 16:31:57 -0700
commit05c8cc70c90032d578606e811bbb1266cd8d2fcd (patch)
tree26d35271abb9c78c159499477956fe2aba0d60c9 /src/libstd/rt/uv/uvio.rs
parent48d67610285b423e806e0c44be43d01d5c1a7dbc (diff)
downloadrust-05c8cc70c90032d578606e811bbb1266cd8d2fcd.tar.gz
rust-05c8cc70c90032d578606e811bbb1266cd8d2fcd.zip
std: rework file io.. support [p]read,[p]write, impl seek/tell + more tests
Diffstat (limited to 'src/libstd/rt/uv/uvio.rs')
-rw-r--r--src/libstd/rt/uv/uvio.rs111
1 files changed, 79 insertions, 32 deletions
diff --git a/src/libstd/rt/uv/uvio.rs b/src/libstd/rt/uv/uvio.rs
index 2acf2cccfea..2a62c782d0b 100644
--- a/src/libstd/rt/uv/uvio.rs
+++ b/src/libstd/rt/uv/uvio.rs
@@ -31,6 +31,7 @@ use rt::uv::idle::IdleWatcher;
 use rt::uv::net::{UvIpv4SocketAddr, UvIpv6SocketAddr};
 use unstable::sync::Exclusive;
 use super::super::io::support::PathLike;
+use libc::{lseek, c_long, SEEK_CUR};
 
 #[cfg(test)] use container::Container;
 #[cfg(test)] use unstable::run_in_bare_thread;
@@ -458,19 +459,20 @@ impl IoFactory for UvIoFactory {
         Ok(~UvTimer::new(watcher, home))
     }
 
-    fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileDescriptor {
-        ~UvFileDescriptor {
+    fn fs_from_raw_fd(&mut self, fd: c_int, close_on_drop: bool) -> ~RtioFileStream {
+        ~UvFileStream {
             loop_: Loop{handle:self.uv_loop().native_handle()},
             fd: file::FileDescriptor(fd),
-            close_on_drop: close_on_drop
-        } as ~RtioFileDescriptor
+            close_on_drop: close_on_drop,
+        } as ~RtioFileStream
     }
 
     fn fs_open<P: PathLike>(&mut self, path: &P, flags: int, mode: int)
-        -> Result<~RtioFileDescriptor, IoError> {
+        -> Result<~RtioFileStream, IoError> {
         let loop_ = Loop {handle: self.uv_loop().native_handle()};
         let result_cell = Cell::new_empty();
-        let result_cell_ptr: *Cell<Result<~RtioFileDescriptor, IoError>> = &result_cell;
+        let result_cell_ptr: *Cell<Result<~RtioFileStream,
+                                           IoError>> = &result_cell;
         let path_cell = Cell::new(path);
         let scheduler = Local::take::<Scheduler>();
         do scheduler.deschedule_running_task_and_then |_, task| {
@@ -478,10 +480,10 @@ impl IoFactory for UvIoFactory {
             let path = path_cell.take();
             do file::FileDescriptor::open(loop_, path, flags, mode) |req,err| {
                 if err.is_none() {
-                    let res = Ok(~UvFileDescriptor {
+                    let res = Ok(~UvFileStream {
                         loop_: loop_,
                         fd: file::FileDescriptor(req.get_result()),
-                        close_on_drop: true} as ~RtioFileDescriptor);
+                        close_on_drop: true} as ~RtioFileStream);
                     unsafe { (*result_cell_ptr).put_back(res); }
                     let scheduler = Local::take::<Scheduler>();
                     scheduler.resume_blocked_task_immediately(task_cell.take());
@@ -1056,32 +1058,14 @@ impl RtioTimer for UvTimer {
     }
 }
 
-pub struct UvFileDescriptor {
+pub struct UvFileStream {
     loop_: Loop,
     fd: file::FileDescriptor,
     close_on_drop: bool
 }
 
-impl UvFileDescriptor {
-}
-
-impl Drop for UvFileDescriptor {
-    fn drop(&self) {
-        if self.close_on_drop {
-            let scheduler = Local::take::<Scheduler>();
-            do scheduler.deschedule_running_task_and_then |_, task| {
-                let task_cell = Cell::new(task);
-                do self.fd.close(self.loop_) |_,_| {
-                    let scheduler = Local::take::<Scheduler>();
-                    scheduler.resume_blocked_task_immediately(task_cell.take());
-                };
-            };
-        }
-    }
-}
-
-impl RtioFileDescriptor for UvFileDescriptor {
-    fn read(&mut self, buf: &mut [u8], offset: i64) -> Result<int, IoError> {
+impl UvFileStream {
+    fn base_read(&mut self, buf: &mut [u8], offset: i64) -> Result<int, IoError> {
         let scheduler = Local::take::<Scheduler>();
         let result_cell = Cell::new_empty();
         let result_cell_ptr: *Cell<Result<int, IoError>> = &result_cell;
@@ -1101,7 +1085,7 @@ impl RtioFileDescriptor for UvFileDescriptor {
         };
         result_cell.take()
     }
-    fn write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> {
+    fn base_write(&mut self, buf: &[u8], offset: i64) -> Result<(), IoError> {
         let scheduler = Local::take::<Scheduler>();
         let result_cell = Cell::new_empty();
         let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
@@ -1123,6 +1107,69 @@ impl RtioFileDescriptor for UvFileDescriptor {
     }
 }
 
+impl Drop for UvFileStream {
+    fn drop(&self) {
+        if self.close_on_drop {
+            let scheduler = Local::take::<Scheduler>();
+            do scheduler.deschedule_running_task_and_then |_, task| {
+                let task_cell = Cell::new(task);
+                do self.fd.close(self.loop_) |_,_| {
+                    let scheduler = Local::take::<Scheduler>();
+                    scheduler.resume_blocked_task_immediately(task_cell.take());
+                };
+            };
+        }
+    }
+}
+
+impl RtioFileStream for UvFileStream {
+    fn read(&mut self, buf: &mut [u8]) -> Result<int, IoError> {
+        self.base_read(buf, -1)
+    }
+    fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
+        self.base_write(buf, -1)
+    }
+    fn pread(&mut self, buf: &mut [u8], offset: u64) -> Result<int, IoError> {
+        self.base_read(buf, offset as i64)
+    }
+    fn pwrite(&mut self, buf: &[u8], offset: u64) -> Result<(), IoError> {
+        self.base_write(buf, offset as i64)
+    }
+    fn seek(&mut self, pos: i64, whence: i64) -> Result<(), IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+        unsafe {
+            match lseek((*self.fd), pos as c_long, whence as c_int) {
+                -1 => {
+                    Err(IoError {
+                        kind: OtherIoError,
+                        desc: "Failed to lseek.",
+                        detail: None
+                    })
+                },
+                _ => Ok(())
+            }
+        }
+    }
+    fn tell(&self) -> Result<u64, IoError> {
+        #[fixed_stack_segment]; #[inline(never)];
+        unsafe {
+            match lseek((*self.fd), 0, SEEK_CUR) {
+                -1 => {
+                    Err(IoError {
+                        kind: OtherIoError,
+                        desc: "Failed to lseek, needed to tell().",
+                        detail: None
+                    })
+                },
+                n=> Ok(n as u64)
+            }
+        }
+    }
+    fn flush(&mut self) -> Result<(), IoError> {
+        Ok(())
+    }
+}
+
 #[test]
 fn test_simple_io_no_connect() {
     do run_in_newsched_task {
@@ -1647,12 +1694,12 @@ fn file_test_uvio_full_simple_impl() {
         {
             let mut fd = (*io).fs_open(&Path(path), create_flags as int, mode as int).unwrap();
             let write_buf = write_val.as_bytes();
-            fd.write(write_buf, 0);
+            fd.write(write_buf);
         }
         {
             let mut fd = (*io).fs_open(&Path(path), ro_flags as int, mode as int).unwrap();
             let mut read_vec = [0, .. 1028];
-            let nread = fd.read(read_vec, 0).unwrap();
+            let nread = fd.read(read_vec).unwrap();
             let read_val = str::from_bytes(read_vec.slice(0, nread as uint));
             assert!(read_val == write_val.to_owned());
         }