mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat(unstable): add Deno.ftruncate and ftruncateSync (#6243)
This commit is contained in:
parent
bdf2d26ba1
commit
86f92e04c7
5 changed files with 139 additions and 0 deletions
|
@ -12,6 +12,7 @@ export { applySourceMap, formatDiagnostics } from "./ops/errors.ts";
|
|||
export { signal, signals, Signal, SignalStream } from "./signals.ts";
|
||||
export { setRaw } from "./ops/tty.ts";
|
||||
export { utimeSync, utime } from "./ops/fs/utime.ts";
|
||||
export { ftruncateSync, ftruncate } from "./ops/fs/truncate.ts";
|
||||
export { ShutdownMode, shutdown } from "./net.ts";
|
||||
export { listen, listenDatagram, connect } from "./net_unstable.ts";
|
||||
export { startTls } from "./tls.ts";
|
||||
|
|
39
cli/js/lib.deno.unstable.d.ts
vendored
39
cli/js/lib.deno.unstable.d.ts
vendored
|
@ -1248,4 +1248,43 @@ declare namespace Deno {
|
|||
|
||||
/** **UNSTABLE**: The URL of the file that was originally executed from the command-line. */
|
||||
export const mainModule: string;
|
||||
|
||||
/** Synchronously truncates or extends the specified file stream, to reach the
|
||||
* specified `len`. If `len` is not specified then the entire file contents
|
||||
* are truncated.
|
||||
*
|
||||
* ```ts
|
||||
* // truncate the entire file
|
||||
* const file = Deno.open("my_file.txt", { read: true, write: true, truncate: true, create: true });
|
||||
* Deno.ftruncateSync(file.rid);
|
||||
*
|
||||
* // truncate part of the file
|
||||
* const file = Deno.open("my_file.txt", { read: true, write: true, create: true });
|
||||
* Deno.write(file.rid, new TextEncoder().encode("Hello World"));
|
||||
* Deno.ftruncateSync(file.rid, 7);
|
||||
* const data = new Uint8Array(32);
|
||||
* Deno.readSync(file.rid, data);
|
||||
* console.log(new TextDecoder().decode(data)); // Hello W
|
||||
* ```
|
||||
*/
|
||||
export function ftruncateSync(rid: number, len?: number): void;
|
||||
|
||||
/** Truncates or extends the specified file stream, to reach the specified `len`. If
|
||||
* `len` is not specified then the entire file contents are truncated.
|
||||
*
|
||||
* ```ts
|
||||
* // truncate the entire file
|
||||
* const file = Deno.open("my_file.txt", { read: true, write: true, create: true });
|
||||
* await Deno.ftruncate(file.rid);
|
||||
*
|
||||
* // truncate part of the file
|
||||
* const file = Deno.open("my_file.txt", { read: true, write: true, create: true });
|
||||
* await Deno.write(file.rid, new TextEncoder().encode("Hello World"));
|
||||
* await Deno.ftruncate(file.rid, 7);
|
||||
* const data = new Uint8Array(32);
|
||||
* await Deno.read(file.rid, data);
|
||||
* console.log(new TextDecoder().decode(data)); // Hello W
|
||||
* ```
|
||||
*/
|
||||
export function ftruncate(rid: number, len?: number): Promise<void>;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,14 @@ function coerceLen(len?: number): number {
|
|||
return len;
|
||||
}
|
||||
|
||||
export function ftruncateSync(rid: number, len?: number): void {
|
||||
sendSync("op_ftruncate", { rid, len: coerceLen(len) });
|
||||
}
|
||||
|
||||
export async function ftruncate(rid: number, len?: number): Promise<void> {
|
||||
await sendAsync("op_ftruncate", { rid, len: coerceLen(len) });
|
||||
}
|
||||
|
||||
export function truncateSync(path: string, len?: number): void {
|
||||
sendSync("op_truncate", { path, len: coerceLen(len) });
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
|
|||
i.register_op("op_link", s.stateful_json_op(op_link));
|
||||
i.register_op("op_symlink", s.stateful_json_op(op_symlink));
|
||||
i.register_op("op_read_link", s.stateful_json_op(op_read_link));
|
||||
i.register_op("op_ftruncate", s.stateful_json_op2(op_ftruncate));
|
||||
i.register_op("op_truncate", s.stateful_json_op(op_truncate));
|
||||
i.register_op("op_make_temp_dir", s.stateful_json_op(op_make_temp_dir));
|
||||
i.register_op("op_make_temp_file", s.stateful_json_op(op_make_temp_file));
|
||||
|
@ -783,6 +784,52 @@ fn op_read_link(
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct FtruncateArgs {
|
||||
promise_id: Option<u64>,
|
||||
rid: i32,
|
||||
len: i32,
|
||||
}
|
||||
|
||||
fn op_ftruncate(
|
||||
isolate_state: &mut CoreIsolateState,
|
||||
state: &State,
|
||||
args: Value,
|
||||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<JsonOp, OpError> {
|
||||
state.check_unstable("Deno.ftruncate");
|
||||
let args: FtruncateArgs = serde_json::from_value(args)?;
|
||||
let rid = args.rid as u32;
|
||||
let len = args.len as u64;
|
||||
|
||||
let resource_table = isolate_state.resource_table.clone();
|
||||
let is_sync = args.promise_id.is_none();
|
||||
|
||||
if is_sync {
|
||||
let mut resource_table = resource_table.borrow_mut();
|
||||
std_file_resource(&mut resource_table, rid, |r| match r {
|
||||
Ok(std_file) => std_file.set_len(len).map_err(OpError::from),
|
||||
Err(_) => Err(OpError::type_error(
|
||||
"cannot truncate this type of resource".to_string(),
|
||||
)),
|
||||
})?;
|
||||
Ok(JsonOp::Sync(json!({})))
|
||||
} else {
|
||||
let fut = async move {
|
||||
let mut resource_table = resource_table.borrow_mut();
|
||||
std_file_resource(&mut resource_table, rid, |r| match r {
|
||||
Ok(std_file) => std_file.set_len(len).map_err(OpError::from),
|
||||
Err(_) => Err(OpError::type_error(
|
||||
"cannot truncate this type of resource".to_string(),
|
||||
)),
|
||||
})?;
|
||||
Ok(json!({}))
|
||||
};
|
||||
Ok(JsonOp::Async(fut.boxed_local()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct TruncateArgs {
|
||||
|
|
|
@ -1,6 +1,50 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { unitTest, assertEquals, assert } from "./test_util.ts";
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
function ftruncateSyncSuccess(): void {
|
||||
const filename = Deno.makeTempDirSync() + "/test_ftruncateSync.txt";
|
||||
const file = Deno.openSync(filename, {
|
||||
create: true,
|
||||
read: true,
|
||||
write: true,
|
||||
});
|
||||
|
||||
Deno.ftruncateSync(file.rid, 20);
|
||||
assertEquals(Deno.readFileSync(filename).byteLength, 20);
|
||||
Deno.ftruncateSync(file.rid, 5);
|
||||
assertEquals(Deno.readFileSync(filename).byteLength, 5);
|
||||
Deno.ftruncateSync(file.rid, -5);
|
||||
assertEquals(Deno.readFileSync(filename).byteLength, 0);
|
||||
|
||||
Deno.close(file.rid);
|
||||
Deno.removeSync(filename);
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
async function ftruncateSuccess(): Promise<void> {
|
||||
const filename = Deno.makeTempDirSync() + "/test_ftruncate.txt";
|
||||
const file = await Deno.open(filename, {
|
||||
create: true,
|
||||
read: true,
|
||||
write: true,
|
||||
});
|
||||
|
||||
await Deno.ftruncate(file.rid, 20);
|
||||
assertEquals((await Deno.readFile(filename)).byteLength, 20);
|
||||
await Deno.ftruncate(file.rid, 5);
|
||||
assertEquals((await Deno.readFile(filename)).byteLength, 5);
|
||||
await Deno.ftruncate(file.rid, -5);
|
||||
assertEquals((await Deno.readFile(filename)).byteLength, 0);
|
||||
|
||||
Deno.close(file.rid);
|
||||
await Deno.remove(filename);
|
||||
}
|
||||
);
|
||||
|
||||
unitTest(
|
||||
{ perms: { read: true, write: true } },
|
||||
function truncateSyncSuccess(): void {
|
||||
|
|
Loading…
Reference in a new issue