From a6f6209f5277f2737bc67efad5c91ab168aff6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 26 Aug 2019 16:18:42 +0200 Subject: [PATCH] port fs ops to JSON (#2812) --- cli/msg.fbs | 114 ------- cli/ops/dispatch_flatbuffers.rs | 24 +- cli/ops/fs.rs | 526 +++++++++++++++++--------------- cli/ops/mod.rs | 56 +++- cli/ops/utils.rs | 1 + js/chmod.ts | 17 +- js/chown.ts | 18 +- js/copy_file.ts | 18 +- js/dir.ts | 19 +- js/dispatch.ts | 30 +- js/file_info.ts | 22 +- js/link.ts | 18 +- js/make_temp_dir.ts | 36 +-- js/mkdir.ts | 18 +- js/read_dir.ts | 32 +- js/read_link.ts | 25 +- js/remove.ts | 17 +- js/rename.ts | 18 +- js/stat.ts | 54 ++-- js/symlink.ts | 28 +- js/truncate.ts | 26 +- 21 files changed, 480 insertions(+), 637 deletions(-) diff --git a/cli/msg.fbs b/cli/msg.fbs index a7359c5272..b5fc524836 100644 --- a/cli/msg.fbs +++ b/cli/msg.fbs @@ -1,27 +1,7 @@ union Any { - Chdir, - Chmod, - Chown, - CopyFile, - Cwd, - CwdRes, - Link, - MakeTempDir, - MakeTempDirRes, - Mkdir, Read, - ReadDir, - ReadDirRes, ReadRes, - Readlink, - ReadlinkRes, - Remove, - Rename, Seek, - Stat, - StatRes, - Symlink, - Truncate, Write, WriteRes, } @@ -122,105 +102,11 @@ table FormatErrorRes { error: string; } -table Chdir { - directory: string; -} - table KeyValue { key: string; value: string; } -table MakeTempDir { - dir: string; - prefix: string; - suffix: string; -} - -table MakeTempDirRes { - path: string; -} - -table Mkdir { - path: string; - recursive: bool; - mode: uint; // Specified by https://godoc.org/os#FileMode -} - -table Chmod { - path: string; - mode: uint; // Specified by https://godoc.org/os#FileMode -} - -table Chown { - path: string; - uid: uint; - gid: uint; // Specified by https://godoc.org/os#Chown -} - -table Remove { - path: string; - recursive: bool; -} - -table ReadDir { - path: string; -} - -table ReadDirRes { - entries: [StatRes]; -} - -table CopyFile { - from: string; - to: string; -} - -table Rename { - oldpath: string; - newpath: string; -} - -table Readlink { - name: string; -} - -table ReadlinkRes { - path: string; -} - -table Symlink { - oldname: string; - newname: string; -} - -table Link { - oldname: string; - newname: string; -} - -table Stat { - filename: string; - lstat: bool; -} - -table StatRes { - is_file: bool; - is_symlink: bool; - len: ulong; - modified:ulong; - accessed:ulong; - created:ulong; - mode: uint; - has_mode: bool; // false on windows - name: string; -} - -table Truncate { - name: string; - len: uint; -} - table Read { rid: uint32; // (ptr, len) is passed as second parameter to Deno.core.send(). diff --git a/cli/ops/dispatch_flatbuffers.rs b/cli/ops/dispatch_flatbuffers.rs index bd01587510..edec777034 100644 --- a/cli/ops/dispatch_flatbuffers.rs +++ b/cli/ops/dispatch_flatbuffers.rs @@ -6,19 +6,14 @@ use deno::*; use flatbuffers::FlatBufferBuilder; use hyper::rt::Future; -use super::files::{op_read, op_write}; -use super::fs::{ - op_chdir, op_chmod, op_chown, op_copy_file, op_cwd, op_link, - op_make_temp_dir, op_mkdir, op_read_dir, op_read_link, op_remove, op_rename, - op_stat, op_symlink, op_truncate, -}; - type CliDispatchFn = fn( state: &ThreadSafeState, base: &msg::Base<'_>, data: Option, ) -> CliOpResult; +use super::files::{op_read, op_write}; + /// Processes raw messages from JavaScript. /// This functions invoked every time Deno.core.dispatch() is called. /// control corresponds to the first argument of Deno.core.dispatch(). @@ -125,22 +120,7 @@ pub fn serialize_response( /// Standard ops set for most isolates pub fn op_selector_std(inner_type: msg::Any) -> Option { match inner_type { - msg::Any::Chdir => Some(op_chdir), - msg::Any::Chmod => Some(op_chmod), - msg::Any::Chown => Some(op_chown), - msg::Any::CopyFile => Some(op_copy_file), - msg::Any::Cwd => Some(op_cwd), - msg::Any::Link => Some(op_link), - msg::Any::MakeTempDir => Some(op_make_temp_dir), - msg::Any::Mkdir => Some(op_mkdir), msg::Any::Read => Some(op_read), - msg::Any::ReadDir => Some(op_read_dir), - msg::Any::Readlink => Some(op_read_link), - msg::Any::Remove => Some(op_remove), - msg::Any::Rename => Some(op_rename), - msg::Any::Stat => Some(op_stat), - msg::Any::Symlink => Some(op_symlink), - msg::Any::Truncate => Some(op_truncate), msg::Any::Write => Some(op_write), _ => None, diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs index f655e4e2db..c549bef329 100644 --- a/cli/ops/fs.rs +++ b/cli/ops/fs.rs @@ -1,14 +1,12 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -use super::dispatch_flatbuffers::serialize_response; +// Some deserializer fields are only used on Unix and Windows build fails without it +#![allow(dead_code)] use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value}; -use super::utils::*; use crate::deno_error::DenoError; use crate::deno_error::ErrorKind; use crate::fs as deno_fs; -use crate::msg; use crate::state::ThreadSafeState; use deno::*; -use flatbuffers::FlatBufferBuilder; use remove_dir_all::remove_dir_all; use std::convert::From; use std::fs; @@ -18,99 +16,130 @@ use std::time::UNIX_EPOCH; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; +#[derive(Deserialize)] +struct ChdirArgs { + directory: String, +} + pub fn op_chdir( _state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_chdir().unwrap(); - let directory = inner.directory().unwrap(); - std::env::set_current_dir(&directory)?; - ok_buf(empty_buf()) + args: Value, + _zero_copy: Option, +) -> Result { + let args: ChdirArgs = serde_json::from_value(args)?; + std::env::set_current_dir(&args.directory)?; + Ok(JsonOp::Sync(json!({}))) +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct MkdirArgs { + promise_id: Option, + path: String, + recursive: bool, + mode: u32, } pub fn op_mkdir( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_mkdir().unwrap(); - let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?; - let recursive = inner.recursive(); - let mode = inner.mode(); + args: Value, + _zero_copy: Option, +) -> Result { + let args: MkdirArgs = serde_json::from_value(args)?; + let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?; state.check_write(&path_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_mkdir {}", path_); - deno_fs::mkdir(&path, mode, recursive)?; - Ok(empty_buf()) + deno_fs::mkdir(&path, args.mode, args.recursive)?; + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ChmodArgs { + promise_id: Option, + path: String, + mode: u32, +} + pub fn op_chmod( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_chmod().unwrap(); - let _mode = inner.mode(); - let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: ChmodArgs = serde_json::from_value(args)?; + let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?; state.check_write(&path_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_chmod {}", &path_); // Still check file/dir exists on windows let _metadata = fs::metadata(&path)?; #[cfg(any(unix))] { let mut permissions = _metadata.permissions(); - permissions.set_mode(_mode); + permissions.set_mode(args.mode); fs::set_permissions(&path, permissions)?; } - Ok(empty_buf()) + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ChownArgs { + promise_id: Option, + path: String, + uid: u32, + gid: u32, +} + pub fn op_chown( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_chown().unwrap(); - let path = String::from(inner.path().unwrap()); - let uid = inner.uid(); - let gid = inner.gid(); + args: Value, + _zero_copy: Option, +) -> Result { + let args: ChownArgs = serde_json::from_value(args)?; - state.check_write(&path)?; + state.check_write(&args.path)?; - blocking(base.sync(), move || { - debug!("op_chown {}", &path); - match deno_fs::chown(&path, uid, gid) { - Ok(_) => Ok(empty_buf()), + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { + debug!("op_chown {}", &args.path); + match deno_fs::chown(args.path.as_ref(), args.uid, args.gid) { + Ok(_) => Ok(json!({})), Err(e) => Err(e), } }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RemoveArgs { + promise_id: Option, + path: String, + recursive: bool, +} + pub fn op_remove( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_remove().unwrap(); - let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?; - let recursive = inner.recursive(); + args: Value, + _zero_copy: Option, +) -> Result { + let args: RemoveArgs = serde_json::from_value(args)?; + let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?; + let recursive = args.recursive; state.check_write(&path_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_remove {}", path.display()); let metadata = fs::metadata(&path)?; if metadata.is_file() { @@ -120,25 +149,34 @@ pub fn op_remove( } else { fs::remove_dir(&path)?; } - Ok(empty_buf()) + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct CopyFileArgs { + promise_id: Option, + from: String, + to: String, +} + pub fn op_copy_file( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_copy_file().unwrap(); - let (from, from_) = deno_fs::resolve_from_cwd(inner.from().unwrap())?; - let (to, to_) = deno_fs::resolve_from_cwd(inner.to().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: CopyFileArgs = serde_json::from_value(args)?; + + let (from, from_) = deno_fs::resolve_from_cwd(args.from.as_ref())?; + let (to, to_) = deno_fs::resolve_from_cwd(args.to.as_ref())?; state.check_read(&from_)?; state.check_write(&to_)?; debug!("op_copy_file {} {}", from.display(), to.display()); - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { // On *nix, Rust deem non-existent path as invalid input // See https://github.com/rust-lang/rust/issues/54800 // Once the issue is reolved, we should remove this workaround. @@ -150,7 +188,7 @@ pub fn op_copy_file( } fs::copy(&from, &to)?; - Ok(empty_buf()) + Ok(json!({})) }) } @@ -174,22 +212,29 @@ fn get_mode(_perm: &fs::Permissions) -> u32 { 0 } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct StatArgs { + promise_id: Option, + filename: String, + lstat: bool, +} + pub fn op_stat( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_stat().unwrap(); - let cmd_id = base.cmd_id(); + args: Value, + _zero_copy: Option, +) -> Result { + let args: StatArgs = serde_json::from_value(args)?; + let (filename, filename_) = - deno_fs::resolve_from_cwd(inner.filename().unwrap())?; - let lstat = inner.lstat(); + deno_fs::resolve_from_cwd(args.filename.as_ref())?; + let lstat = args.lstat; state.check_read(&filename_)?; - blocking(base.sync(), move || { - let builder = &mut FlatBufferBuilder::new(); + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_stat {} {}", filename.display(), lstat); let metadata = if lstat { fs::symlink_metadata(&filename)? @@ -197,146 +242,140 @@ pub fn op_stat( fs::metadata(&filename)? }; - let inner = msg::StatRes::create( - builder, - &msg::StatResArgs { - is_file: metadata.is_file(), - is_symlink: metadata.file_type().is_symlink(), - len: metadata.len(), - modified: to_seconds!(metadata.modified()), - accessed: to_seconds!(metadata.accessed()), - created: to_seconds!(metadata.created()), - mode: get_mode(&metadata.permissions()), - has_mode: cfg!(target_family = "unix"), - ..Default::default() - }, - ); - - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::StatRes, - ..Default::default() - }, - )) + Ok(json!({ + "isFile": metadata.is_file(), + "isSymlink": metadata.file_type().is_symlink(), + "len": metadata.len(), + "modified":to_seconds!(metadata.modified()), + "accessed":to_seconds!(metadata.accessed()), + "created":to_seconds!(metadata.created()), + "mode": get_mode(&metadata.permissions()), + "hasMode": cfg!(target_family = "unix"), // false on windows, + })) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ReadDirArgs { + promise_id: Option, + path: String, +} + pub fn op_read_dir( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_read_dir().unwrap(); - let cmd_id = base.cmd_id(); - let (path, path_) = deno_fs::resolve_from_cwd(inner.path().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: ReadDirArgs = serde_json::from_value(args)?; + let (path, path_) = deno_fs::resolve_from_cwd(args.path.as_ref())?; state.check_read(&path_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_read_dir {}", path.display()); - let builder = &mut FlatBufferBuilder::new(); + let entries: Vec<_> = fs::read_dir(path)? .map(|entry| { let entry = entry.unwrap(); let metadata = entry.metadata().unwrap(); let file_type = metadata.file_type(); - let name = builder.create_string(entry.file_name().to_str().unwrap()); - msg::StatRes::create( - builder, - &msg::StatResArgs { - is_file: file_type.is_file(), - is_symlink: file_type.is_symlink(), - len: metadata.len(), - modified: to_seconds!(metadata.modified()), - accessed: to_seconds!(metadata.accessed()), - created: to_seconds!(metadata.created()), - name: Some(name), - mode: get_mode(&metadata.permissions()), - has_mode: cfg!(target_family = "unix"), - }, - ) + json!({ + "isFile": file_type.is_file(), + "isSymlink": file_type.is_symlink(), + "len": metadata.len(), + "modified": to_seconds!(metadata.modified()), + "accessed": to_seconds!(metadata.accessed()), + "created": to_seconds!(metadata.created()), + "mode": get_mode(&metadata.permissions()), + "name": entry.file_name().to_str().unwrap(), + "hasMode": cfg!(target_family = "unix"), // false on windows, + }) }) .collect(); - let entries = builder.create_vector(&entries); - let inner = msg::ReadDirRes::create( - builder, - &msg::ReadDirResArgs { - entries: Some(entries), - }, - ); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::ReadDirRes, - ..Default::default() - }, - )) + Ok(json!({ "entries": entries })) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct RenameArgs { + promise_id: Option, + oldpath: String, + newpath: String, +} + pub fn op_rename( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_rename().unwrap(); - let (oldpath, oldpath_) = - deno_fs::resolve_from_cwd(inner.oldpath().unwrap())?; - let (newpath, newpath_) = - deno_fs::resolve_from_cwd(inner.newpath().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: RenameArgs = serde_json::from_value(args)?; + + let (oldpath, oldpath_) = deno_fs::resolve_from_cwd(args.oldpath.as_ref())?; + let (newpath, newpath_) = deno_fs::resolve_from_cwd(args.newpath.as_ref())?; state.check_read(&oldpath_)?; state.check_write(&oldpath_)?; state.check_write(&newpath_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_rename {} {}", oldpath.display(), newpath.display()); fs::rename(&oldpath, &newpath)?; - Ok(empty_buf()) + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct LinkArgs { + promise_id: Option, + oldname: String, + newname: String, +} + pub fn op_link( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_link().unwrap(); - let (oldname, oldpath_) = - deno_fs::resolve_from_cwd(inner.oldname().unwrap())?; - let (newname, newname_) = - deno_fs::resolve_from_cwd(inner.newname().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: LinkArgs = serde_json::from_value(args)?; - state.check_read(&oldpath_)?; + let (oldname, oldname_) = deno_fs::resolve_from_cwd(args.oldname.as_ref())?; + let (newname, newname_) = deno_fs::resolve_from_cwd(args.newname.as_ref())?; + + state.check_read(&oldname_)?; state.check_write(&newname_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_link {} {}", oldname.display(), newname.display()); std::fs::hard_link(&oldname, &newname)?; - Ok(empty_buf()) + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct SymlinkArgs { + promise_id: Option, + oldname: String, + newname: String, +} + pub fn op_symlink( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_symlink().unwrap(); - let (oldname, _) = deno_fs::resolve_from_cwd(inner.oldname().unwrap())?; - let (newname, newname_) = - deno_fs::resolve_from_cwd(inner.newname().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: SymlinkArgs = serde_json::from_value(args)?; + + let (oldname, _oldname_) = deno_fs::resolve_from_cwd(args.oldname.as_ref())?; + let (newname, newname_) = deno_fs::resolve_from_cwd(args.newname.as_ref())?; state.check_write(&newname_)?; // TODO Use type for Windows. @@ -345,88 +384,97 @@ pub fn op_symlink( DenoError::new(ErrorKind::Other, "Not implemented".to_string()).into(), ); } - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_symlink {} {}", oldname.display(), newname.display()); #[cfg(any(unix))] std::os::unix::fs::symlink(&oldname, &newname)?; - Ok(empty_buf()) + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct ReadLinkArgs { + promise_id: Option, + name: String, +} + pub fn op_read_link( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let inner = base.inner_as_readlink().unwrap(); - let cmd_id = base.cmd_id(); - let (name, name_) = deno_fs::resolve_from_cwd(inner.name().unwrap())?; + args: Value, + _zero_copy: Option, +) -> Result { + let args: ReadLinkArgs = serde_json::from_value(args)?; + + let (name, name_) = deno_fs::resolve_from_cwd(args.name.as_ref())?; state.check_read(&name_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_read_link {}", name.display()); let path = fs::read_link(&name)?; - let builder = &mut FlatBufferBuilder::new(); - let path_off = builder.create_string(path.to_str().unwrap()); - let inner = msg::ReadlinkRes::create( - builder, - &msg::ReadlinkResArgs { - path: Some(path_off), - }, - ); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::ReadlinkRes, - ..Default::default() - }, - )) + let path_str = path.to_str().unwrap(); + + Ok(json!(path_str)) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct TruncateArgs { + promise_id: Option, + name: String, + len: u64, +} + pub fn op_truncate( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); + args: Value, + _zero_copy: Option, +) -> Result { + let args: TruncateArgs = serde_json::from_value(args)?; - let inner = base.inner_as_truncate().unwrap(); - let (filename, filename_) = deno_fs::resolve_from_cwd(inner.name().unwrap())?; - let len = inner.len(); + let (filename, filename_) = deno_fs::resolve_from_cwd(args.name.as_ref())?; + let len = args.len; state.check_write(&filename_)?; - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { debug!("op_truncate {} {}", filename_, len); let f = fs::OpenOptions::new().write(true).open(&filename)?; - f.set_len(u64::from(len))?; - Ok(empty_buf()) + f.set_len(len)?; + Ok(json!({})) }) } +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct MakeTempDirArgs { + promise_id: Option, + dir: Option, + prefix: Option, + suffix: Option, +} + pub fn op_make_temp_dir( state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let base = Box::new(*base); - let inner = base.inner_as_make_temp_dir().unwrap(); - let cmd_id = base.cmd_id(); + args: Value, + _zero_copy: Option, +) -> Result { + let args: MakeTempDirArgs = serde_json::from_value(args)?; // FIXME state.check_write("make_temp")?; - let dir = inner.dir().map(PathBuf::from); - let prefix = inner.prefix().map(String::from); - let suffix = inner.suffix().map(String::from); + let dir = args.dir.map(PathBuf::from); + let prefix = args.prefix.map(String::from); + let suffix = args.suffix.map(String::from); - blocking(base.sync(), move || { + let is_sync = args.promise_id.is_none(); + blocking_json(is_sync, move || { // TODO(piscisaureus): use byte vector for paths, not a string. // See https://github.com/denoland/deno/issues/627. // We can't assume that paths are always valid utf8 strings. @@ -436,23 +484,9 @@ pub fn op_make_temp_dir( prefix.as_ref().map(|x| &**x), suffix.as_ref().map(|x| &**x), )?; - let builder = &mut FlatBufferBuilder::new(); - let path_off = builder.create_string(path.to_str().unwrap()); - let inner = msg::MakeTempDirRes::create( - builder, - &msg::MakeTempDirResArgs { - path: Some(path_off), - }, - ); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::MakeTempDirRes, - ..Default::default() - }, - )) + let path_str = path.to_str().unwrap(); + + Ok(json!(path_str)) }) } @@ -482,24 +516,10 @@ pub fn op_utime( pub fn op_cwd( _state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult { - assert!(data.is_none()); - let cmd_id = base.cmd_id(); + _args: Value, + _zero_copy: Option, +) -> Result { let path = std::env::current_dir()?; - let builder = &mut FlatBufferBuilder::new(); - let cwd = - builder.create_string(&path.into_os_string().into_string().unwrap()); - let inner = msg::CwdRes::create(builder, &msg::CwdResArgs { cwd: Some(cwd) }); - let response_buf = serialize_response( - cmd_id, - builder, - msg::BaseArgs { - inner: Some(inner.as_union_value()), - inner_type: msg::Any::CwdRes, - ..Default::default() - }, - ); - ok_buf(response_buf) + let path_str = path.into_os_string().into_string().unwrap(); + Ok(JsonOp::Sync(json!(path_str))) } diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs index 4636754c9b..1a853e992a 100644 --- a/cli/ops/mod.rs +++ b/cli/ops/mod.rs @@ -26,7 +26,7 @@ mod workers; // Warning! These values are duplicated in the TypeScript code (js/dispatch.ts), // update with care. -pub const OP_FLATBUFFER: OpId = 44; +pub const OP_FLATBUFFER: OpId = 100; pub const OP_READ: OpId = 1; pub const OP_WRITE: OpId = 2; pub const OP_EXIT: OpId = 3; @@ -68,6 +68,21 @@ pub const OP_WORKER_GET_MESSAGE: OpId = 38; pub const OP_RUN: OpId = 39; pub const OP_RUN_STATUS: OpId = 40; pub const OP_KILL: OpId = 41; +pub const OP_CHDIR: OpId = 42; +pub const OP_MKDIR: OpId = 43; +pub const OP_CHMOD: OpId = 44; +pub const OP_CHOWN: OpId = 45; +pub const OP_REMOVE: OpId = 46; +pub const OP_COPY_FILE: OpId = 47; +pub const OP_STAT: OpId = 48; +pub const OP_READ_DIR: OpId = 49; +pub const OP_RENAME: OpId = 50; +pub const OP_LINK: OpId = 51; +pub const OP_SYMLINK: OpId = 52; +pub const OP_READ_LINK: OpId = 53; +pub const OP_TRUNCATE: OpId = 54; +pub const OP_MAKE_TEMP_DIR: OpId = 55; +pub const OP_CWD: OpId = 56; pub fn dispatch( state: &ThreadSafeState, @@ -242,6 +257,45 @@ pub fn dispatch( OP_KILL => { dispatch_json::dispatch(process::op_kill, state, control, zero_copy) } + OP_CHDIR => { + dispatch_json::dispatch(fs::op_chdir, state, control, zero_copy) + } + OP_MKDIR => { + dispatch_json::dispatch(fs::op_mkdir, state, control, zero_copy) + } + OP_CHMOD => { + dispatch_json::dispatch(fs::op_chmod, state, control, zero_copy) + } + OP_CHOWN => { + dispatch_json::dispatch(fs::op_chown, state, control, zero_copy) + } + OP_REMOVE => { + dispatch_json::dispatch(fs::op_remove, state, control, zero_copy) + } + OP_COPY_FILE => { + dispatch_json::dispatch(fs::op_copy_file, state, control, zero_copy) + } + OP_STAT => dispatch_json::dispatch(fs::op_stat, state, control, zero_copy), + OP_READ_DIR => { + dispatch_json::dispatch(fs::op_read_dir, state, control, zero_copy) + } + OP_RENAME => { + dispatch_json::dispatch(fs::op_rename, state, control, zero_copy) + } + OP_LINK => dispatch_json::dispatch(fs::op_link, state, control, zero_copy), + OP_SYMLINK => { + dispatch_json::dispatch(fs::op_symlink, state, control, zero_copy) + } + OP_READ_LINK => { + dispatch_json::dispatch(fs::op_read_link, state, control, zero_copy) + } + OP_TRUNCATE => { + dispatch_json::dispatch(fs::op_truncate, state, control, zero_copy) + } + OP_MAKE_TEMP_DIR => { + dispatch_json::dispatch(fs::op_make_temp_dir, state, control, zero_copy) + } + OP_CWD => dispatch_json::dispatch(fs::op_cwd, state, control, zero_copy), OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy), _ => panic!("bad op_id"), }; diff --git a/cli/ops/utils.rs b/cli/ops/utils.rs index 95b13b77ae..daa6150a60 100644 --- a/cli/ops/utils.rs +++ b/cli/ops/utils.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use crate::tokio_util; use deno::Buf; use deno::ErrBox; diff --git a/js/chmod.ts b/js/chmod.ts index 2d6a5ed0f7..23b3dff25f 100644 --- a/js/chmod.ts +++ b/js/chmod.ts @@ -1,15 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req( - path: string, - mode: number -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const path_ = builder.createString(path); - const inner = msg.Chmod.createChmod(builder, path_, mode); - return [builder, msg.Any.Chmod, inner]; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** Changes the permission of a specific file/directory of specified path * synchronously. @@ -17,7 +8,7 @@ function req( * Deno.chmodSync("/path/to/file", 0o666); */ export function chmodSync(path: string, mode: number): void { - sendSync(...req(path, mode)); + sendSync(dispatch.OP_CHMOD, { path, mode }); } /** Changes the permission of a specific file/directory of specified path. @@ -25,5 +16,5 @@ export function chmodSync(path: string, mode: number): void { * await Deno.chmod("/path/to/file", 0o666); */ export async function chmod(path: string, mode: number): Promise { - await sendAsync(...req(path, mode)); + await sendAsync(dispatch.OP_CHMOD, { path, mode }); } diff --git a/js/chown.ts b/js/chown.ts index 8787033fca..6bfddab98f 100644 --- a/js/chown.ts +++ b/js/chown.ts @@ -1,16 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req( - path: string, - uid: number, - gid: number -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const path_ = builder.createString(path); - const inner = msg.Chown.createChown(builder, path_, uid, gid); - return [builder, msg.Any.Chown, inner]; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** * Change owner of a regular file or directory synchronously. Unix only at the moment. @@ -19,7 +9,7 @@ function req( * @param gid group id of the new owner */ export function chownSync(path: string, uid: number, gid: number): void { - sendSync(...req(path, uid, gid)); + sendSync(dispatch.OP_CHOWN, { path, uid, gid }); } /** @@ -33,5 +23,5 @@ export async function chown( uid: number, gid: number ): Promise { - await sendAsync(...req(path, uid, gid)); + await sendAsync(dispatch.OP_CHOWN, { path, uid, gid }); } diff --git a/js/copy_file.ts b/js/copy_file.ts index 4c62ed1b0a..b299a52bc5 100644 --- a/js/copy_file.ts +++ b/js/copy_file.ts @@ -1,16 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req( - from: string, - to: string -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const from_ = builder.createString(from); - const to_ = builder.createString(to); - const inner = msg.CopyFile.createCopyFile(builder, from_, to_); - return [builder, msg.Any.CopyFile, inner]; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** Copies the contents of a file to another by name synchronously. * Creates a new file if target does not exists, and if target exists, @@ -22,7 +12,7 @@ function req( * Deno.copyFileSync("from.txt", "to.txt"); */ export function copyFileSync(from: string, to: string): void { - sendSync(...req(from, to)); + sendSync(dispatch.OP_COPY_FILE, { from, to }); } /** Copies the contents of a file to another by name. @@ -36,5 +26,5 @@ export function copyFileSync(from: string, to: string): void { * await Deno.copyFile("from.txt", "to.txt"); */ export async function copyFile(from: string, to: string): Promise { - await sendAsync(...req(from, to)); + await sendAsync(dispatch.OP_COPY_FILE, { from, to }); } diff --git a/js/dir.ts b/js/dir.ts index 824084f4de..f2cf91c21b 100644 --- a/js/dir.ts +++ b/js/dir.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { assert } from "./util"; -import { sendSync, flatbuffers, msg } from "./dispatch_flatbuffers"; +import { sendSync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** * `cwd()` Return a string representing the current working directory. @@ -10,15 +10,7 @@ import { sendSync, flatbuffers, msg } from "./dispatch_flatbuffers"; * throws `NotFound` exception if directory not available */ export function cwd(): string { - const builder = flatbuffers.createBuilder(); - msg.Cwd.startCwd(builder); - const inner = msg.Cwd.endCwd(builder); - const baseRes = sendSync(builder, msg.Any.Cwd, inner); - assert(baseRes != null); - assert(msg.Any.CwdRes === baseRes!.innerType()); - const res = new msg.CwdRes(); - assert(baseRes!.inner(res) != null); - return res.cwd()!; + return sendSync(dispatch.OP_CWD); } /** @@ -26,8 +18,5 @@ export function cwd(): string { * throws `NotFound` exception if directory not available */ export function chdir(directory: string): void { - const builder = flatbuffers.createBuilder(); - const directory_ = builder.createString(directory); - const inner = msg.Chdir.createChdir(builder, directory_); - sendSync(builder, msg.Any.Chdir, inner); + sendSync(dispatch.OP_CHDIR, { directory }); } diff --git a/js/dispatch.ts b/js/dispatch.ts index 6c7551441a..2416c19e29 100644 --- a/js/dispatch.ts +++ b/js/dispatch.ts @@ -4,7 +4,7 @@ import * as flatbuffers from "./dispatch_flatbuffers"; import * as json from "./dispatch_json"; // These consts are shared with Rust. Update with care. -export const OP_FLATBUFFER = 44; +export const OP_FLATBUFFER = 100; export const OP_READ = 1; export const OP_WRITE = 2; export const OP_EXIT = 3; @@ -46,6 +46,21 @@ export const OP_WORKER_GET_MESSAGE = 38; export const OP_RUN = 39; export const OP_RUN_STATUS = 40; export const OP_KILL = 41; +export const OP_CHDIR = 42; +export const OP_MKDIR = 43; +export const OP_CHMOD = 44; +export const OP_CHOWN = 45; +export const OP_REMOVE = 46; +export const OP_COPY_FILE = 47; +export const OP_STAT = 48; +export const OP_READ_DIR = 49; +export const OP_RENAME = 50; +export const OP_LINK = 51; +export const OP_SYMLINK = 52; +export const OP_READ_LINK = 53; +export const OP_TRUNCATE = 54; +export const OP_MAKE_TEMP_DIR = 55; +export const OP_CWD = 56; export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void { switch (opId) { @@ -73,6 +88,19 @@ export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void { case OP_HOST_GET_MESSAGE: case OP_WORKER_GET_MESSAGE: case OP_RUN_STATUS: + case OP_MKDIR: + case OP_CHMOD: + case OP_CHOWN: + case OP_REMOVE: + case OP_COPY_FILE: + case OP_STAT: + case OP_READ_DIR: + case OP_RENAME: + case OP_LINK: + case OP_SYMLINK: + case OP_READ_LINK: + case OP_TRUNCATE: + case OP_MAKE_TEMP_DIR: json.asyncMsgFromRust(opId, ui8); break; default: diff --git a/js/file_info.ts b/js/file_info.ts index f2e5a88aec..c124e06bfd 100644 --- a/js/file_info.ts +++ b/js/file_info.ts @@ -1,5 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; +import { StatResponse } from "./stat"; /** A FileInfo describes a file and is returned by `stat`, `lstat`, * `statSync`, `lstatSync`. @@ -58,17 +58,17 @@ export class FileInfoImpl implements FileInfo { name: string | null; /* @internal */ - constructor(private _inner: msg.StatRes) { - const modified = this._inner.modified().toFloat64(); - const accessed = this._inner.accessed().toFloat64(); - const created = this._inner.created().toFloat64(); - const hasMode = this._inner.hasMode(); - const mode = this._inner.mode(); // negative for invalid mode (Windows) - const name = this._inner.name(); + constructor(private _res: StatResponse) { + const modified = this._res.modified; + const accessed = this._res.accessed; + const created = this._res.created; + const hasMode = this._res.hasMode; + const mode = this._res.mode; // negative for invalid mode (Windows) + const name = this._res.name; - this._isFile = this._inner.isFile(); - this._isSymlink = this._inner.isSymlink(); - this.len = this._inner.len().toFloat64(); + this._isFile = this._res.isFile; + this._isSymlink = this._res.isSymlink; + this.len = this._res.len; this.modified = modified ? modified : null; this.accessed = accessed ? accessed : null; this.created = created ? created : null; diff --git a/js/link.ts b/js/link.ts index 0d849d289d..f6c6530b24 100644 --- a/js/link.ts +++ b/js/link.ts @@ -1,23 +1,13 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req( - oldname: string, - newname: string -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const oldname_ = builder.createString(oldname); - const newname_ = builder.createString(newname); - const inner = msg.Link.createLink(builder, oldname_, newname_); - return [builder, msg.Any.Link, inner]; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** Synchronously creates `newname` as a hard link to `oldname`. * * Deno.linkSync("old/name", "new/name"); */ export function linkSync(oldname: string, newname: string): void { - sendSync(...req(oldname, newname)); + sendSync(dispatch.OP_LINK, { oldname, newname }); } /** Creates `newname` as a hard link to `oldname`. @@ -25,5 +15,5 @@ export function linkSync(oldname: string, newname: string): void { * await Deno.link("old/name", "new/name"); */ export async function link(oldname: string, newname: string): Promise { - await sendAsync(...req(oldname, newname)); + await sendAsync(dispatch.OP_LINK, { oldname, newname }); } diff --git a/js/make_temp_dir.ts b/js/make_temp_dir.ts index f83f7fb60e..5e0a28205a 100644 --- a/js/make_temp_dir.ts +++ b/js/make_temp_dir.ts @@ -1,6 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; -import { assert } from "./util"; +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; export interface MakeTempDirOptions { dir?: string; @@ -8,41 +8,13 @@ export interface MakeTempDirOptions { suffix?: string; } -function req({ - dir, - prefix, - suffix -}: MakeTempDirOptions): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const fbDir = dir == null ? 0 : builder.createString(dir); - const fbPrefix = prefix == null ? 0 : builder.createString(prefix); - const fbSuffix = suffix == null ? 0 : builder.createString(suffix); - const inner = msg.MakeTempDir.createMakeTempDir( - builder, - fbDir, - fbPrefix, - fbSuffix - ); - return [builder, msg.Any.MakeTempDir, inner]; -} - -function res(baseRes: null | msg.Base): string { - assert(baseRes != null); - assert(msg.Any.MakeTempDirRes === baseRes!.innerType()); - const res = new msg.MakeTempDirRes(); - assert(baseRes!.inner(res) != null); - const path = res.path(); - assert(path != null); - return path!; -} - /** makeTempDirSync is the synchronous version of `makeTempDir`. * * const tempDirName0 = Deno.makeTempDirSync(); * const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' }); */ export function makeTempDirSync(options: MakeTempDirOptions = {}): string { - return res(sendSync(...req(options))); + return sendSync(dispatch.OP_MAKE_TEMP_DIR, options); } /** makeTempDir creates a new temporary directory in the directory `dir`, its @@ -59,5 +31,5 @@ export function makeTempDirSync(options: MakeTempDirOptions = {}): string { export async function makeTempDir( options: MakeTempDirOptions = {} ): Promise { - return res(await sendAsync(...req(options))); + return await sendAsync(dispatch.OP_MAKE_TEMP_DIR, options); } diff --git a/js/mkdir.ts b/js/mkdir.ts index 417c754a91..54f99224bd 100644 --- a/js/mkdir.ts +++ b/js/mkdir.ts @@ -1,16 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req( - path: string, - recursive: boolean, - mode: number -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const path_ = builder.createString(path); - const inner = msg.Mkdir.createMkdir(builder, path_, recursive, mode); - return [builder, msg.Any.Mkdir, inner]; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** Creates a new directory with the specified path synchronously. * If `recursive` is set to true, nested directories will be created (also known @@ -22,7 +12,7 @@ function req( * Deno.mkdirSync("nested/directories", true); */ export function mkdirSync(path: string, recursive = false, mode = 0o777): void { - sendSync(...req(path, recursive, mode)); + sendSync(dispatch.OP_MKDIR, { path, recursive, mode }); } /** Creates a new directory with the specified path. @@ -39,5 +29,5 @@ export async function mkdir( recursive = false, mode = 0o777 ): Promise { - await sendAsync(...req(path, recursive, mode)); + await sendAsync(dispatch.OP_MKDIR, { path, recursive, mode }); } diff --git a/js/read_dir.ts b/js/read_dir.ts index 13c620916e..27d011a089 100644 --- a/js/read_dir.ts +++ b/js/read_dir.ts @@ -1,25 +1,19 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; import { FileInfo, FileInfoImpl } from "./file_info"; -import { assert } from "./util"; +import { StatResponse } from "./stat"; -function req(path: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const path_ = builder.createString(path); - const inner = msg.ReadDir.createReadDir(builder, path_); - return [builder, msg.Any.ReadDir, inner]; +interface ReadDirResponse { + entries: StatResponse[]; } -function res(baseRes: null | msg.Base): FileInfo[] { - assert(baseRes != null); - assert(msg.Any.ReadDirRes === baseRes!.innerType()); - const res = new msg.ReadDirRes(); - assert(baseRes!.inner(res) != null); - const fileInfos: FileInfo[] = []; - for (let i = 0; i < res.entriesLength(); i++) { - fileInfos.push(new FileInfoImpl(res.entries(i)!)); - } - return fileInfos; +function res(response: ReadDirResponse): FileInfo[] { + return response.entries.map( + (statRes: StatResponse): FileInfo => { + return new FileInfoImpl(statRes); + } + ); } /** Reads the directory given by path and returns a list of file info @@ -28,7 +22,7 @@ function res(baseRes: null | msg.Base): FileInfo[] { * const files = Deno.readDirSync("/"); */ export function readDirSync(path: string): FileInfo[] { - return res(sendSync(...req(path))); + return res(sendSync(dispatch.OP_READ_DIR, { path })); } /** Reads the directory given by path and returns a list of file info. @@ -36,5 +30,5 @@ export function readDirSync(path: string): FileInfo[] { * const files = await Deno.readDir("/"); */ export async function readDir(path: string): Promise { - return res(await sendAsync(...req(path))); + return res(await sendAsync(dispatch.OP_READ_DIR, { path })); } diff --git a/js/read_link.ts b/js/read_link.ts index 8cac67dd1e..fae1e64b6f 100644 --- a/js/read_link.ts +++ b/js/read_link.ts @@ -1,30 +1,13 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { assert } from "./util"; -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req(name: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const name_ = builder.createString(name); - const inner = msg.Readlink.createReadlink(builder, name_); - return [builder, msg.Any.Readlink, inner]; -} - -function res(baseRes: null | msg.Base): string { - assert(baseRes !== null); - assert(msg.Any.ReadlinkRes === baseRes!.innerType()); - const res = new msg.ReadlinkRes(); - assert(baseRes!.inner(res) !== null); - const path = res.path(); - assert(path !== null); - return path!; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** Returns the destination of the named symbolic link synchronously. * * const targetPath = Deno.readlinkSync("symlink/path"); */ export function readlinkSync(name: string): string { - return res(sendSync(...req(name))); + return sendSync(dispatch.OP_READ_LINK, { name }); } /** Returns the destination of the named symbolic link. @@ -32,5 +15,5 @@ export function readlinkSync(name: string): string { * const targetPath = await Deno.readlink("symlink/path"); */ export async function readlink(name: string): Promise { - return res(await sendAsync(...req(name))); + return await sendAsync(dispatch.OP_READ_LINK, { name }); } diff --git a/js/remove.ts b/js/remove.ts index 95294e6cfc..f2a94f3953 100644 --- a/js/remove.ts +++ b/js/remove.ts @@ -1,20 +1,11 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; export interface RemoveOption { recursive?: boolean; } -function req( - path: string, - options: RemoveOption -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const path_ = builder.createString(path); - const inner = msg.Remove.createRemove(builder, path_, !!options.recursive); - return [builder, msg.Any.Remove, inner]; -} - /** Removes the named file or directory synchronously. Would throw * error if permission denied, not found, or directory not empty if `recursive` * set to false. @@ -23,7 +14,7 @@ function req( * Deno.removeSync("/path/to/dir/or/file", {recursive: false}); */ export function removeSync(path: string, options: RemoveOption = {}): void { - sendSync(...req(path, options)); + sendSync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive }); } /** Removes the named file or directory. Would throw error if @@ -37,5 +28,5 @@ export async function remove( path: string, options: RemoveOption = {} ): Promise { - await sendAsync(...req(path, options)); + await sendAsync(dispatch.OP_REMOVE, { path, recursive: !!options.recursive }); } diff --git a/js/rename.ts b/js/rename.ts index 31f480d0e4..80794747d6 100644 --- a/js/rename.ts +++ b/js/rename.ts @@ -1,16 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; - -function req( - oldpath: string, - newpath: string -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const oldpath_ = builder.createString(oldpath); - const newpath_ = builder.createString(newpath); - const inner = msg.Rename.createRename(builder, oldpath_, newpath_); - return [builder, msg.Any.Rename, inner]; -} +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; /** Synchronously renames (moves) `oldpath` to `newpath`. If `newpath` already * exists and is not a directory, `renameSync()` replaces it. OS-specific @@ -20,7 +10,7 @@ function req( * Deno.renameSync("old/path", "new/path"); */ export function renameSync(oldpath: string, newpath: string): void { - sendSync(...req(oldpath, newpath)); + sendSync(dispatch.OP_RENAME, { oldpath, newpath }); } /** Renames (moves) `oldpath` to `newpath`. If `newpath` already exists and is @@ -30,5 +20,5 @@ export function renameSync(oldpath: string, newpath: string): void { * await Deno.rename("old/path", "new/path"); */ export async function rename(oldpath: string, newpath: string): Promise { - await sendAsync(...req(oldpath, newpath)); + await sendAsync(dispatch.OP_RENAME, { oldpath, newpath }); } diff --git a/js/stat.ts b/js/stat.ts index 1fcce82afd..1cc8d070a9 100644 --- a/js/stat.ts +++ b/js/stat.ts @@ -1,24 +1,18 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; -import { assert } from "./util"; +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; import { FileInfo, FileInfoImpl } from "./file_info"; -function req( - filename: string, - lstat: boolean -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const filename_ = builder.createString(filename); - const inner = msg.Stat.createStat(builder, filename_, lstat); - return [builder, msg.Any.Stat, inner]; -} - -function res(baseRes: null | msg.Base): FileInfo { - assert(baseRes != null); - assert(msg.Any.StatRes === baseRes!.innerType()); - const res = new msg.StatRes(); - assert(baseRes!.inner(res) != null); - return new FileInfoImpl(res); +export interface StatResponse { + isFile: boolean; + isSymlink: boolean; + len: number; + modified: number; + accessed: number; + created: number; + mode: number; + hasMode: boolean; // false on windows + name: string | null; } /** Queries the file system for information on the path provided. If the given @@ -28,7 +22,11 @@ function res(baseRes: null | msg.Base): FileInfo { * assert(fileInfo.isFile()); */ export async function lstat(filename: string): Promise { - return res(await sendAsync(...req(filename, true))); + const res = (await sendAsync(dispatch.OP_STAT, { + filename, + lstat: true + })) as StatResponse; + return new FileInfoImpl(res); } /** Queries the file system for information on the path provided synchronously. @@ -39,7 +37,11 @@ export async function lstat(filename: string): Promise { * assert(fileInfo.isFile()); */ export function lstatSync(filename: string): FileInfo { - return res(sendSync(...req(filename, true))); + const res = sendSync(dispatch.OP_STAT, { + filename, + lstat: true + }) as StatResponse; + return new FileInfoImpl(res); } /** Queries the file system for information on the path provided. `stat` Will @@ -49,7 +51,11 @@ export function lstatSync(filename: string): FileInfo { * assert(fileInfo.isFile()); */ export async function stat(filename: string): Promise { - return res(await sendAsync(...req(filename, false))); + const res = (await sendAsync(dispatch.OP_STAT, { + filename, + lstat: false + })) as StatResponse; + return new FileInfoImpl(res); } /** Queries the file system for information on the path provided synchronously. @@ -59,5 +65,9 @@ export async function stat(filename: string): Promise { * assert(fileInfo.isFile()); */ export function statSync(filename: string): FileInfo { - return res(sendSync(...req(filename, false))); + const res = sendSync(dispatch.OP_STAT, { + filename, + lstat: false + }) as StatResponse; + return new FileInfoImpl(res); } diff --git a/js/symlink.ts b/js/symlink.ts index 40551e9f8e..6fd2e90a58 100644 --- a/js/symlink.ts +++ b/js/symlink.ts @@ -1,23 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; import * as util from "./util"; import { platform } from "./build"; -function req( - oldname: string, - newname: string, - type?: string -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - if (platform.os === "win" && type) { - return util.notImplemented(); - } - const builder = flatbuffers.createBuilder(); - const oldname_ = builder.createString(oldname); - const newname_ = builder.createString(newname); - const inner = msg.Symlink.createSymlink(builder, oldname_, newname_); - return [builder, msg.Any.Symlink, inner]; -} - /** Synchronously creates `newname` as a symbolic link to `oldname`. The type * argument can be set to `dir` or `file` and is only available on Windows * (ignored on other platforms). @@ -29,7 +15,10 @@ export function symlinkSync( newname: string, type?: string ): void { - sendSync(...req(oldname, newname, type)); + if (platform.os === "win" && type) { + return util.notImplemented(); + } + sendSync(dispatch.OP_SYMLINK, { oldname, newname }); } /** Creates `newname` as a symbolic link to `oldname`. The type argument can be @@ -43,5 +32,8 @@ export async function symlink( newname: string, type?: string ): Promise { - await sendAsync(...req(oldname, newname, type)); + if (platform.os === "win" && type) { + return util.notImplemented(); + } + await sendAsync(dispatch.OP_SYMLINK, { oldname, newname }); } diff --git a/js/truncate.ts b/js/truncate.ts index 259c57da5f..c6e5b3ad08 100644 --- a/js/truncate.ts +++ b/js/truncate.ts @@ -1,15 +1,17 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { sendSync, sendAsync } from "./dispatch_json"; +import * as dispatch from "./dispatch"; -function req( - name: string, - len?: number -): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { - const builder = flatbuffers.createBuilder(); - const name_ = builder.createString(name); - len = len && len > 0 ? Math.floor(len) : 0; - const inner = msg.Truncate.createTruncate(builder, name_, len); - return [builder, msg.Any.Truncate, inner]; +function coerceLen(len?: number): number { + if (!len) { + return 0; + } + + if (len < 0) { + return 0; + } + + return len; } /** Truncates or extends the specified file synchronously, updating the size of @@ -18,7 +20,7 @@ function req( * Deno.truncateSync("hello.txt", 10); */ export function truncateSync(name: string, len?: number): void { - sendSync(...req(name, len)); + sendSync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) }); } /** @@ -28,5 +30,5 @@ export function truncateSync(name: string, len?: number): void { * await Deno.truncate("hello.txt", 10); */ export async function truncate(name: string, len?: number): Promise { - await sendAsync(...req(name, len)); + await sendAsync(dispatch.OP_TRUNCATE, { name, len: coerceLen(len) }); }