Repository navigation
Expand file tree
/
Copy pathStreams.js
More file actions
127 lines (127 loc) · 4.92 KB
/
Copy pathStreams.js
File metadata and controls
127 lines (127 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import * as fs from "fs/promises";
import * as path from "path";
import { fileURLToPath } from "url";
export class PHPStreamContext {
options;
constructor(options = {}) {
this.options = options;
}
}
export class StreamRuntime {
static async stream_context_create(ctx, optionsArg) {
const options = await optionsArg?.get() || {};
return new PHPStreamContext(options);
}
static async fopen(ctx, filenameArg, modeArg) {
try {
const filename = String(await filenameArg?.get() ?? "");
const mode = String(await modeArg?.get() ?? "");
const localPath = filename.startsWith("file://") ? fileURLToPath(filename) : path.resolve(ctx.cwd, filename);
const normalizedMode = mode.replace(/[bt]/g, "");
const flags = {
r: "r", "r+": "r+", w: "w", "w+": "w+", a: "a", "a+": "a+",
x: "wx", "x+": "wx+",
c: fs.constants.O_WRONLY | fs.constants.O_CREAT,
"c+": fs.constants.O_RDWR | fs.constants.O_CREAT,
};
if (flags[normalizedMode] === undefined)
return false;
return { handle: await fs.open(localPath, flags[normalizedMode]), isResource: true };
}
catch {
return false;
}
}
static async fclose(ctx, streamArg) {
const stream = await streamArg?.get();
if (!stream?.isResource)
return false;
try {
await stream.handle.close();
stream.isResource = false;
return true;
}
catch {
return false;
}
}
static async fread(ctx, streamArg, lengthArg) {
const stream = await streamArg?.get();
const length = Number(await lengthArg?.get()) || 0;
if (!stream?.isResource || length < 0)
return false;
try {
const buffer = Buffer.alloc(length);
const { bytesRead } = await stream.handle.read(buffer, 0, length, null);
return buffer.subarray(0, bytesRead).toString("utf8");
}
catch {
return false;
}
}
static async fwrite(ctx, streamArg, dataArg, lengthArg) {
const stream = await streamArg?.get();
const data = await dataArg?.get();
const rawLength = await lengthArg?.get();
const length = rawLength !== undefined ? Number(rawLength) : undefined;
if (!stream?.isResource)
return false;
try {
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(String(data ?? ""));
const content = length === undefined ? buffer : buffer.subarray(0, Math.max(0, length));
return (await stream.handle.write(content)).bytesWritten;
}
catch {
return false;
}
}
static async stream_get_contents(ctx, streamArg, maxLengthArg, offsetArg) {
const stream = await streamArg?.get();
const rawMaxLength = await maxLengthArg?.get();
const rawOffset = await offsetArg?.get();
const maxLength = rawMaxLength !== undefined ? Number(rawMaxLength) : -1;
const offset = rawOffset !== undefined ? Number(rawOffset) : -1;
try {
if (typeof stream === "string") {
return await fs.readFile(stream, "utf8");
}
if (stream?.isResource && stream.handle) {
if (maxLength < 0 && offset < 0)
return await stream.handle.readFile("utf8");
const length = maxLength < 0 ? (await stream.handle.stat()).size : maxLength;
const buffer = Buffer.alloc(length);
const { bytesRead } = await stream.handle.read(buffer, 0, length, offset < 0 ? null : offset);
return buffer.subarray(0, bytesRead).toString("utf8");
}
return "";
}
catch {
return false;
}
}
static async stream_get_wrappers(ctx) {
return ["file", "http", "https", "ftp", "ftps", "compress.zlib", "compress.bzip2", "php", "data", "glob", "phar"];
}
static async stream_is_local(ctx, streamArg) {
const stream = await streamArg?.get();
if (typeof stream === "string") {
return !stream.includes("://") || stream.startsWith("file://");
}
return true;
}
static functions = {
"fopen": StreamRuntime.fopen,
"fclose": StreamRuntime.fclose,
"fread": StreamRuntime.fread,
"fwrite": StreamRuntime.fwrite,
"fputs": StreamRuntime.fwrite,
"stream_context_create": StreamRuntime.stream_context_create,
"stream_get_contents": StreamRuntime.stream_get_contents,
"stream_get_wrappers": StreamRuntime.stream_get_wrappers,
"stream_is_local": StreamRuntime.stream_is_local,
};
static register(engine) {
engine.registerFunctions(StreamRuntime.functions);
}
}
//# sourceMappingURL=Streams.js.map