forked from hyoo-ru/mam_mol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.ts
165 lines (124 loc) · 3.27 KB
/
file.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
157
158
159
160
161
162
163
164
165
namespace $ {
export type $mol_file_type = 'file' | 'dir' | 'link'
export interface $mol_file_stat {
type: $mol_file_type
size: number
atime: Date
mtime: Date
ctime: Date
}
export class $mol_file_not_found extends Error {}
export abstract class $mol_file extends $mol_object {
@ $mol_mem_key
static absolute( path : string ): $mol_file {
throw new Error( 'Not implemented yet' )
}
static relative( path : string ) : $mol_file {
throw new Error( 'Not implemented yet' )
}
path() {
return '.'
}
parent() {
return this.resolve( '..' )
}
abstract stat( next? : $mol_file_stat, force? : $mol_mem_force ): $mol_file_stat
reset(): void {
try {
this.stat(undefined, $mol_mem_force_cache)
} catch (error) {
if (error instanceof $mol_file_not_found) return
return $mol_fail_hidden(error)
}
}
version() {
return this.stat().mtime.getTime().toString( 36 ).toUpperCase()
}
abstract ensure(next?: boolean): boolean
watcher() {
console.warn('$mol_file_web.watcher() not implemented')
return {
destructor() {}
}
}
@ $mol_mem
exists( next? : boolean , force? : $mol_mem_force ) {
let exists = true
try {
this.stat()
} catch (error) {
if (error instanceof $mol_file_not_found) {
exists = false
} else {
return $mol_fail_hidden(error)
}
}
if( next === undefined ) return exists
if( next === exists ) return exists
if( next ) this.parent().exists( true )
this.ensure(next)
this.reset()
return next
}
type() {
return this.stat().type
}
name() {
return this.path().replace( /^.*\//, '' )
}
ext() {
const match = /((?:\.\w+)+)$/.exec( this.path() )
return match ? match[ 1 ].substring( 1 ) : ''
}
abstract buffer( next? : Uint8Array , force? : $mol_mem_force ): Uint8Array
text(next?: string, force?: $mol_mem_force) {
return $mol_charset_decode(this.buffer(next === undefined ? undefined : $mol_charset_encode(next), force))
}
fail(error: Error) {
this.buffer(error as any, $mol_mem_force_fail)
this.stat(error as any, $mol_mem_force_fail)
}
buffer_cached(buffer: Uint8Array) {
const ctime = new Date()
const stat: $mol_file_stat = {
type: 'file',
size: buffer.length,
ctime,
atime: ctime,
mtime: ctime
}
this.buffer(buffer, $mol_mem_force_cache)
this.stat(stat , $mol_mem_force_cache)
}
text_cached(content: string) {
this.buffer_cached($mol_charset_encode(content))
}
abstract sub(): $mol_file[]
abstract resolve(path: string): $mol_file
abstract relate( base?: $mol_file ): string
abstract append( next : Uint8Array | string ): void
find(
include? : RegExp ,
exclude? : RegExp
) {
const found = [] as $mol_file[]
const sub = this.sub()
for (const child of sub) {
const child_path = child.path()
if( exclude && child_path.match( exclude ) ) continue
if( !include || child_path.match( include ) ) found.push( child )
if( child.type() === 'dir' ) {
const sub_child = child.find( include , exclude )
for (const child of sub_child) found.push(child)
}
}
return found
}
size() {
switch( this.type() ) {
case 'file': return this.stat().size
default: return 0
}
}
}
}