mirror of
https://github.com/denoland/deno.git
synced 2024-12-01 16:51:13 -05:00
Add deno.truncate (#805)
This commit is contained in:
parent
f51903f773
commit
062b22fe56
7 changed files with 147 additions and 0 deletions
1
BUILD.gn
1
BUILD.gn
|
@ -96,6 +96,7 @@ ts_sources = [
|
||||||
"js/text_encoding.ts",
|
"js/text_encoding.ts",
|
||||||
"js/timers.ts",
|
"js/timers.ts",
|
||||||
"js/trace.ts",
|
"js/trace.ts",
|
||||||
|
"js/truncate.ts",
|
||||||
"js/types.ts",
|
"js/types.ts",
|
||||||
"js/util.ts",
|
"js/util.ts",
|
||||||
"js/v8_source_maps.ts",
|
"js/v8_source_maps.ts",
|
||||||
|
|
|
@ -17,5 +17,6 @@ export { ErrorKind, DenoError } from "./errors";
|
||||||
export { libdeno } from "./libdeno";
|
export { libdeno } from "./libdeno";
|
||||||
export { arch, platform } from "./platform";
|
export { arch, platform } from "./platform";
|
||||||
export { trace } from "./trace";
|
export { trace } from "./trace";
|
||||||
|
export { truncateSync, truncate } from "./truncate";
|
||||||
export { setGlobalTimeout } from "./timers";
|
export { setGlobalTimeout } from "./timers";
|
||||||
export const args: string[] = [];
|
export const args: string[] = [];
|
||||||
|
|
42
js/truncate.ts
Normal file
42
js/truncate.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import * as fbs from "gen/msg_generated";
|
||||||
|
import { flatbuffers } from "flatbuffers";
|
||||||
|
import * as dispatch from "./dispatch";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncates or extends the specified file synchronously,
|
||||||
|
* updating the size of this file to become size.
|
||||||
|
*
|
||||||
|
* import { truncateSync } from "deno";
|
||||||
|
*
|
||||||
|
* truncateSync("hello.txt", 10);
|
||||||
|
*/
|
||||||
|
export function truncateSync(name: string, len?: number): void {
|
||||||
|
dispatch.sendSync(...req(name, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncates or extends the specified file,
|
||||||
|
* updating the size of this file to become size.
|
||||||
|
*
|
||||||
|
* import { truncate } from "deno";
|
||||||
|
*
|
||||||
|
* await truncate("hello.txt", 10);
|
||||||
|
*/
|
||||||
|
export async function truncate(name: string, len?: number): Promise<void> {
|
||||||
|
await dispatch.sendAsync(...req(name, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
function req(
|
||||||
|
name: string,
|
||||||
|
len?: number
|
||||||
|
): [flatbuffers.Builder, fbs.Any, flatbuffers.Offset] {
|
||||||
|
const builder = new flatbuffers.Builder();
|
||||||
|
const name_ = builder.createString(name);
|
||||||
|
len = len && len > 0 ? Math.floor(len) : 0;
|
||||||
|
fbs.Truncate.startTruncate(builder);
|
||||||
|
fbs.Truncate.addName(builder, name_);
|
||||||
|
fbs.Truncate.addLen(builder, len);
|
||||||
|
const msg = fbs.Truncate.endTruncate(builder);
|
||||||
|
return [builder, fbs.Any.Truncate, msg];
|
||||||
|
}
|
73
js/truncate_test.ts
Normal file
73
js/truncate_test.ts
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { testPerm, assertEqual } from "./test_util.ts";
|
||||||
|
import * as deno from "deno";
|
||||||
|
|
||||||
|
function readDataSync(name: string): string {
|
||||||
|
const data = deno.readFileSync(name);
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
const text = decoder.decode(data);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function readData(name: string): Promise<string> {
|
||||||
|
const data = await deno.readFile(name);
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
const text = decoder.decode(data);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
testPerm({ write: true }, function truncateSyncSuccess() {
|
||||||
|
const enc = new TextEncoder();
|
||||||
|
const d = enc.encode("Hello");
|
||||||
|
const filename = deno.makeTempDirSync() + "/test_truncateSync.txt";
|
||||||
|
deno.writeFileSync(filename, d);
|
||||||
|
deno.truncateSync(filename, 20);
|
||||||
|
let data = readDataSync(filename);
|
||||||
|
assertEqual(data.length, 20);
|
||||||
|
deno.truncateSync(filename, 5);
|
||||||
|
data = readDataSync(filename);
|
||||||
|
assertEqual(data.length, 5);
|
||||||
|
deno.truncateSync(filename, -5);
|
||||||
|
data = readDataSync(filename);
|
||||||
|
assertEqual(data.length, 0);
|
||||||
|
deno.removeSync(filename);
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: true }, async function truncateSuccess() {
|
||||||
|
const enc = new TextEncoder();
|
||||||
|
const d = enc.encode("Hello");
|
||||||
|
const filename = deno.makeTempDirSync() + "/test_truncate.txt";
|
||||||
|
await deno.writeFile(filename, d);
|
||||||
|
await deno.truncate(filename, 20);
|
||||||
|
let data = await readData(filename);
|
||||||
|
assertEqual(data.length, 20);
|
||||||
|
await deno.truncate(filename, 5);
|
||||||
|
data = await readData(filename);
|
||||||
|
assertEqual(data.length, 5);
|
||||||
|
await deno.truncate(filename, -5);
|
||||||
|
data = await readData(filename);
|
||||||
|
assertEqual(data.length, 0);
|
||||||
|
await deno.remove(filename);
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: false }, function truncateSyncPerm() {
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
deno.mkdirSync("/test_truncateSyncPermission.txt");
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
assertEqual(err.kind, deno.ErrorKind.PermissionDenied);
|
||||||
|
assertEqual(err.name, "PermissionDenied");
|
||||||
|
});
|
||||||
|
|
||||||
|
testPerm({ write: false }, async function truncatePerm() {
|
||||||
|
let err;
|
||||||
|
try {
|
||||||
|
await deno.mkdir("/test_truncatePermission.txt");
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
assertEqual(err.kind, deno.ErrorKind.PermissionDenied);
|
||||||
|
assertEqual(err.name, "PermissionDenied");
|
||||||
|
});
|
|
@ -19,5 +19,6 @@ import "./symlink_test.ts";
|
||||||
import "./platform_test.ts";
|
import "./platform_test.ts";
|
||||||
import "./text_encoding_test.ts";
|
import "./text_encoding_test.ts";
|
||||||
import "./trace_test.ts";
|
import "./trace_test.ts";
|
||||||
|
import "./truncate_test.ts";
|
||||||
import "./v8_source_maps_test.ts";
|
import "./v8_source_maps_test.ts";
|
||||||
import "../website/app_test.js";
|
import "../website/app_test.js";
|
||||||
|
|
|
@ -77,6 +77,7 @@ pub fn msg_from_js(
|
||||||
msg::Any::Symlink => handle_symlink,
|
msg::Any::Symlink => handle_symlink,
|
||||||
msg::Any::SetEnv => handle_set_env,
|
msg::Any::SetEnv => handle_set_env,
|
||||||
msg::Any::Stat => handle_stat,
|
msg::Any::Stat => handle_stat,
|
||||||
|
msg::Any::Truncate => handle_truncate,
|
||||||
msg::Any::WriteFile => handle_write_file,
|
msg::Any::WriteFile => handle_write_file,
|
||||||
msg::Any::Exit => handle_exit,
|
msg::Any::Exit => handle_exit,
|
||||||
_ => panic!(format!(
|
_ => panic!(format!(
|
||||||
|
@ -977,3 +978,25 @@ fn handle_read_link(
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_truncate(
|
||||||
|
state: Arc<IsolateState>,
|
||||||
|
base: &msg::Base,
|
||||||
|
data: &'static mut [u8],
|
||||||
|
) -> Box<Op> {
|
||||||
|
assert_eq!(data.len(), 0);
|
||||||
|
|
||||||
|
if !state.flags.allow_write {
|
||||||
|
return odd_future(permission_denied());
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = base.msg_as_truncate().unwrap();
|
||||||
|
let filename = String::from(msg.name().unwrap());
|
||||||
|
let len = msg.len();
|
||||||
|
blocking!(base.sync(), || {
|
||||||
|
debug!("handle_truncate {} {}", filename, len);
|
||||||
|
let f = fs::OpenOptions::new().write(true).open(&filename)?;
|
||||||
|
f.set_len(len as u64)?;
|
||||||
|
Ok(empty_buf())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ union Any {
|
||||||
Stat,
|
Stat,
|
||||||
StatRes,
|
StatRes,
|
||||||
SetEnv,
|
SetEnv,
|
||||||
|
Truncate,
|
||||||
Open,
|
Open,
|
||||||
OpenRes,
|
OpenRes,
|
||||||
Read,
|
Read,
|
||||||
|
@ -247,6 +248,11 @@ table StatRes {
|
||||||
has_mode: bool; // false on windows
|
has_mode: bool; // false on windows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table Truncate {
|
||||||
|
name: string;
|
||||||
|
len: uint;
|
||||||
|
}
|
||||||
|
|
||||||
table WriteFileSync {
|
table WriteFileSync {
|
||||||
filename: string;
|
filename: string;
|
||||||
data: [ubyte];
|
data: [ubyte];
|
||||||
|
|
Loading…
Reference in a new issue