-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.ts
156 lines (138 loc) · 4.48 KB
/
index.ts
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import libmagicFactory from "./libmagic-wrapper";
import type LibmagicModule from "./LibmagicModule";
import type StdioOverrideFunction from "./StdioOverrideFunction";
export { default as StdioOverrideFunction } from "./StdioOverrideFunction";
declare function wrappedDetect(bufPointer: number, bufLength: number): string;
export enum WASMagicFlags {
/** No flags */
NONE = 0x0000000,
/** Turn on debugging */
DEBUG = 0x0000001,
/** Follow symlinks */
SYMLINK = 0x0000002,
/** Check inside compressed files */
COMPRESS = 0x0000004,
/** Look at the contents of devices */
DEVICES = 0x0000008,
/** Return the MIME type */
MIME_TYPE = 0x0000010,
/** Return all matches */
CONTINUE = 0x0000020,
/** Print warnings to stderr */
CHECK = 0x0000040,
/** Restore access time on exit */
PRESERVE_ATIME = 0x0000080,
/** Don't convert unprintable chars */
RAW = 0x0000100,
/** Handle ENOENT etc as real errors */
ERROR = 0x0000200,
/** Return the MIME encoding */
MIME_ENCODING = 0x0000400,
/** Return the Apple creator/type */
APPLE = 0x0000800,
/** Return a /-separated list of extensions */
EXTENSION = 0x1000000,
/** Check inside compressed files but not report compression */
COMPRESS_TRANSP = 0x2000000,
/** Don't allow decompression that needs to fork */
NO_COMPRESS_FORK = 0x4000000,
/** Don't check for compressed files */
NO_CHECK_COMPRESS = 0x0001000,
/** Don't check for tar files */
NO_CHECK_TAR = 0x0002000,
/** Don't check magic entries */
NO_CHECK_SOFT = 0x0004000,
/** Don't check application type */
NO_CHECK_APPTYPE = 0x0008000,
/** Don't check for elf details */
NO_CHECK_ELF = 0x0010000,
/** Don't check for text files */
NO_CHECK_TEXT = 0x0020000,
/** Don't check for cdf files */
NO_CHECK_CDF = 0x0040000,
/** Don't check for CSV files */
NO_CHECK_CSV = 0x0080000,
/** Don't check tokens */
NO_CHECK_TOKENS = 0x0100000,
/** Don't check text encodings */
NO_CHECK_ENCODING = 0x0200000,
/** Don't check for JSON files */
NO_CHECK_JSON = 0x0400000,
/** Don't check for SIMH tape files */
NO_CHECK_SIMH = 0x0800000,
}
export type WASMagicOptions = {
flags?: WASMagicFlags;
loadDefaultMagicfile?: boolean;
magicFiles?: Uint8Array[];
stdio?: StdioOverrideFunction;
};
type WASMagicOptionsComplete = {
flags: WASMagicFlags;
loadDefaultMagicfile: boolean;
magicFiles: Uint8Array[];
stdio: StdioOverrideFunction;
};
const defaultWASMagicOptions: WASMagicOptionsComplete = Object.freeze({
flags: WASMagicFlags.MIME_TYPE,
loadDefaultMagicfile: true,
magicFiles: [],
stdio: (_stdioName: "stdout" | "stderr", _text: string) => {},
});
export class WASMagic {
static async create(
options: WASMagicOptions = defaultWASMagicOptions,
): Promise<WASMagic> {
const Module = await libmagicFactory();
return new WASMagic(Module, options);
}
private Module: LibmagicModule;
private detectFromWasm: typeof wrappedDetect;
private constructor(Module: LibmagicModule, inputOptions: WASMagicOptions) {
const options = Object.assign({}, defaultWASMagicOptions, inputOptions);
Module.printOverride = options.stdio;
Module.FS.chdir("/magic");
const magicPaths: string[] = [];
// Write each magic file to the internal WASM filesystem
for (let i = 0; i < options.magicFiles.length; i++) {
Module.FS.writeFile(`/magic/${i}`, options.magicFiles[i]);
magicPaths.push(`${i}`);
}
if (options.loadDefaultMagicfile) {
magicPaths.push("magic.mgc");
}
const loadErr = Module.ccall(
"magic_wrapper_load",
"string",
["number", "string"],
[options.flags, magicPaths.join(":")],
);
if (loadErr !== "") {
throw new Error(`WASMagic Load Error: ${loadErr}`);
}
// Remove each magic file from the internal WASM filesystem
// This frees available memory
for (let i = 0; i < options.magicFiles.length; i++) {
Module.FS.unlink(`/magic/${i}`);
}
Module.FS.unlink("/magic/magic.mgc");
this.Module = Module;
this.detectFromWasm = Module.cwrap("magic_wrapper_detect", "string", [
"number",
"number",
]) as typeof wrappedDetect;
}
detect(buf: Uint8Array): string {
const ptr = this.Module._malloc(buf.length);
this.Module.HEAPU8.set(buf, ptr);
const result = this.detectFromWasm(ptr, buf.length);
this.Module._free(ptr);
return result;
}
/**
* @deprecated Use {@link WASMagic#detect} instead
*/
getMime(buf: Uint8Array): string {
return this.detect(buf);
}
}