mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
add filemanager_thread
This commit is contained in:
parent
ab12d8098f
commit
c618ee21d0
8 changed files with 182 additions and 0 deletions
137
components/net/filemanager_thread.rs
Normal file
137
components/net/filemanager_thread.rs
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
|
use net_traits::filemanager_thread::{FileManagerThreadMsg, FileManagerResult, FileManagerThreadError};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use util::thread::spawn_named;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
pub struct FileManager {
|
||||||
|
receiver: IpcReceiver<FileManagerThreadMsg>,
|
||||||
|
idmap: RefCell<HashMap<Uuid, PathBuf>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileManager {
|
||||||
|
fn new(recv: IpcReceiver<FileManagerThreadMsg>) -> FileManager {
|
||||||
|
FileManager {
|
||||||
|
receiver: recv,
|
||||||
|
idmap: RefCell::new(HashMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_thread() -> IpcSender<FileManagerThreadMsg> {
|
||||||
|
let (chan, recv) = ipc::channel().unwrap();
|
||||||
|
|
||||||
|
spawn_named("FileManager".to_owned(), move || {
|
||||||
|
FileManager::new(recv).start();
|
||||||
|
});
|
||||||
|
|
||||||
|
chan
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start the file manager event loop
|
||||||
|
pub fn start(&mut self) {
|
||||||
|
loop {
|
||||||
|
match self.receiver.recv().unwrap() {
|
||||||
|
FileManagerThreadMsg::SelectFile(sender) => self.select_file(sender),
|
||||||
|
FileManagerThreadMsg::SelectFiles(sender) => self.select_files(sender),
|
||||||
|
FileManagerThreadMsg::ReadFile(sender, id) => self.read_file(sender, id),
|
||||||
|
FileManagerThreadMsg::DeleteFileID(id) => self.delete_fileid(id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FileManager {
|
||||||
|
fn select_file(&mut self, sender: IpcSender<FileManagerResult<(Uuid, PathBuf, u64)>>) {
|
||||||
|
// TODO: Pull the dialog UI in and get selected
|
||||||
|
let selected_path = Path::new("");
|
||||||
|
|
||||||
|
match self.create_entry(selected_path) {
|
||||||
|
Some(triple) => {
|
||||||
|
let _ = sender.send(Ok(triple));
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
let _ = sender.send(Err(FileManagerThreadError::InvalidSelection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn select_files(&mut self, sender: IpcSender<FileManagerResult<Vec<(Uuid, PathBuf, u64)>>>) {
|
||||||
|
let selected_paths = vec![Path::new("")];
|
||||||
|
|
||||||
|
let mut replies = vec![];
|
||||||
|
|
||||||
|
for path in selected_paths {
|
||||||
|
match self.create_entry(path) {
|
||||||
|
Some(triple) => replies.push(triple),
|
||||||
|
None => {
|
||||||
|
let _ = sender.send(Err(FileManagerThreadError::InvalidSelection));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = sender.send(Ok(replies));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_entry(&mut self, file_path: &Path) -> Option<(Uuid, PathBuf, u64)> {
|
||||||
|
match File::open(file_path) {
|
||||||
|
Ok(handler) => {
|
||||||
|
let id = Uuid::new_v4();
|
||||||
|
self.idmap.borrow_mut().insert(id, file_path.to_path_buf());
|
||||||
|
|
||||||
|
// Unix Epoch: https://doc.servo.org/std/time/constant.UNIX_EPOCH.html
|
||||||
|
let epoch = handler.metadata().and_then(|metadata| metadata.modified()).map_err(|_| ())
|
||||||
|
.and_then(|systime| systime.elapsed().map_err(|_| ()))
|
||||||
|
.and_then(|elapsed| {
|
||||||
|
let secs = elapsed.as_secs();
|
||||||
|
let nsecs = elapsed.subsec_nanos();
|
||||||
|
let msecs = secs * 1000 + nsecs as u64 / 1000000;
|
||||||
|
Ok(msecs)
|
||||||
|
});
|
||||||
|
|
||||||
|
let filename = file_path.file_name();
|
||||||
|
|
||||||
|
match (epoch, filename) {
|
||||||
|
(Ok(epoch), Some(filename)) => Some((id, Path::new(filename).to_path_buf(), epoch)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_file(&mut self, sender: IpcSender<FileManagerResult<Vec<u8>>>, id: Uuid) {
|
||||||
|
|
||||||
|
match self.idmap.borrow().get(&id).and_then(|filepath| {
|
||||||
|
let mut buffer = vec![];
|
||||||
|
match File::open(&filepath) {
|
||||||
|
Ok(mut handler) => {
|
||||||
|
match handler.read_to_end(&mut buffer) {
|
||||||
|
Ok(_) => Some(buffer),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Some(buffer) => {
|
||||||
|
let _ = sender.send(Ok(buffer));
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
let _ = sender.send(Err(FileManagerThreadError::ReadFileError));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete_fileid(&mut self, id: Uuid) {
|
||||||
|
self.idmap.borrow_mut().remove(&id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(fnbox)]
|
#![feature(fnbox)]
|
||||||
|
#![feature(fs_time)]
|
||||||
#![feature(mpsc_select)]
|
#![feature(mpsc_select)]
|
||||||
#![feature(plugin)]
|
#![feature(plugin)]
|
||||||
#![feature(plugin)]
|
#![feature(plugin)]
|
||||||
|
@ -48,6 +49,7 @@ pub mod cookie;
|
||||||
pub mod cookie_storage;
|
pub mod cookie_storage;
|
||||||
pub mod data_loader;
|
pub mod data_loader;
|
||||||
pub mod file_loader;
|
pub mod file_loader;
|
||||||
|
pub mod filemanager_thread;
|
||||||
pub mod hsts;
|
pub mod hsts;
|
||||||
pub mod http_loader;
|
pub mod http_loader;
|
||||||
pub mod image_cache_thread;
|
pub mod image_cache_thread;
|
||||||
|
|
|
@ -22,3 +22,4 @@ serde = "0.7"
|
||||||
serde_macros = "0.7"
|
serde_macros = "0.7"
|
||||||
url = {version = "1.0.0", features = ["heap_size"]}
|
url = {version = "1.0.0", features = ["heap_size"]}
|
||||||
websocket = "0.17"
|
websocket = "0.17"
|
||||||
|
uuid = { version = "0.2.2", features = ["v4", "serde"] }
|
||||||
|
|
34
components/net_traits/filemanager_thread.rs
Normal file
34
components/net_traits/filemanager_thread.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub enum FileManagerThreadMsg {
|
||||||
|
/// Select a single file, return triple (FileID, FileName, lastModified)
|
||||||
|
SelectFile(IpcSender<FileManagerResult<(Uuid, PathBuf, u64)>>),
|
||||||
|
|
||||||
|
/// Select multiple files, return a vector of triples
|
||||||
|
SelectFiles(IpcSender<FileManagerResult<Vec<(Uuid, PathBuf, u64)>>>),
|
||||||
|
|
||||||
|
/// Read file, return the bytes
|
||||||
|
ReadFile(IpcSender<FileManagerResult<Vec<u8>>>, Uuid),
|
||||||
|
|
||||||
|
/// Delete the FileID entry
|
||||||
|
DeleteFileID(Uuid),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type FileManagerResult<T> = Result<T, FileManagerThreadError>;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub enum FileManagerThreadError {
|
||||||
|
/// The selection action is invalid, nothing is selected
|
||||||
|
InvalidSelection,
|
||||||
|
/// Failure to process file information such as file name, modified time etc.
|
||||||
|
FileInfoProcessingError,
|
||||||
|
/// Failure to read the file content
|
||||||
|
ReadFileError,
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ extern crate msg;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate util;
|
extern crate util;
|
||||||
|
extern crate uuid;
|
||||||
extern crate websocket;
|
extern crate websocket;
|
||||||
|
|
||||||
use hyper::header::{ContentType, Headers};
|
use hyper::header::{ContentType, Headers};
|
||||||
|
@ -42,6 +43,7 @@ use websocket::header;
|
||||||
|
|
||||||
pub mod bluetooth_scanfilter;
|
pub mod bluetooth_scanfilter;
|
||||||
pub mod bluetooth_thread;
|
pub mod bluetooth_thread;
|
||||||
|
pub mod filemanager_thread;
|
||||||
pub mod hosts;
|
pub mod hosts;
|
||||||
pub mod image_cache_thread;
|
pub mod image_cache_thread;
|
||||||
pub mod net_error_list;
|
pub mod net_error_list;
|
||||||
|
|
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -1409,6 +1409,7 @@ dependencies = [
|
||||||
"serde_macros 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
|
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"websocket 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"websocket 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2377,6 +2378,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
2
ports/cef/Cargo.lock
generated
2
ports/cef/Cargo.lock
generated
|
@ -1304,6 +1304,7 @@ dependencies = [
|
||||||
"serde_macros 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
|
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"websocket 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"websocket 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2242,6 +2243,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
2
ports/gonk/Cargo.lock
generated
2
ports/gonk/Cargo.lock
generated
|
@ -1287,6 +1287,7 @@ dependencies = [
|
||||||
"serde_macros 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_macros 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
|
"uuid 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"websocket 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"websocket 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2223,6 +2224,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue