1
+ export class FsUtils {
2
+ static writeText ( fn , data ) {
3
+ if ( ! fn . startsWith ( "/storage" ) ) fn = FsUtils . fullPath ( fn ) ;
4
+
5
+ try {
6
+ hmFS . remove ( fn ) ;
7
+ } catch ( e ) { }
8
+
9
+ const buffer = FsUtils . strToUtf8 ( data ) ;
10
+ const f = FsUtils . open ( fn , hmFS . O_WRONLY | hmFS . O_CREAT ) ;
11
+ hmFS . write ( f , buffer , 0 , buffer . byteLength ) ;
12
+ hmFS . close ( f ) ;
13
+ }
14
+
15
+ static read ( fn , limit = false ) {
16
+ if ( ! fn . startsWith ( "/storage" ) ) fn = FsUtils . fullPath ( fn ) ;
17
+ const [ st , e ] = FsUtils . stat ( fn ) ;
18
+ const f = FsUtils . open ( fn , hmFS . O_RDONLY ) ;
19
+
20
+ const size = limit ? limit : st . size ;
21
+ const data = new ArrayBuffer ( size ) ;
22
+ hmFS . read ( f , data , 0 , size ) ;
23
+ hmFS . close ( f ) ;
24
+
25
+ return data ;
26
+ }
27
+
28
+ static fetchTextFile ( fn , limit = false ) {
29
+ const data = FsUtils . read ( fn , limit ) ;
30
+
31
+ const view = new Uint8Array ( data ) ;
32
+ let str = "" ;
33
+
34
+ return FsUtils . Utf8ArrayToStr ( view ) ;
35
+ }
36
+
37
+ static stat ( path ) {
38
+ path = FsUtils . fixPath ( path ) ;
39
+ return hmFS . stat_asset ( path ) ;
40
+ }
41
+
42
+ static fixPath ( path ) {
43
+ if ( path . startsWith ( "/storage" ) ) {
44
+ const statPath = "../../../" + path . substring ( 9 ) ;
45
+ return statPath ;
46
+ }
47
+ return path ;
48
+ }
49
+
50
+ static open ( path , m ) {
51
+ if ( path . startsWith ( "/storage" ) ) {
52
+ const statPath = "../../../" + path . substring ( 9 ) ;
53
+ return hmFS . open_asset ( statPath , m ) ;
54
+ }
55
+
56
+ return hmFS . open ( path , m ) ;
57
+ }
58
+
59
+ static fetchJSON ( fn ) {
60
+ const text = FsUtils . fetchTextFile ( fn ) ;
61
+ return JSON . parse ( text ) ;
62
+ }
63
+
64
+ static copy ( source , dest ) {
65
+ try {
66
+ hmFS . remove ( dest ) ;
67
+ } catch ( e ) { }
68
+
69
+ const buffer = FsUtils . read ( source ) ;
70
+ const f = FsUtils . open ( dest , hmFS . O_WRONLY | hmFS . O_CREAT ) ;
71
+ hmFS . write ( f , buffer , 0 , buffer . byteLength ) ;
72
+ hmFS . close ( f ) ;
73
+ }
74
+
75
+ static isFolder ( path ) {
76
+ const [ st , e ] = FsUtils . stat ( path ) ;
77
+ return ( st . mode & 32768 ) == 0 ;
78
+ }
79
+
80
+ static getSelfPath ( ) {
81
+ if ( ! FsUtils . selfPath ) {
82
+ const pkg = hmApp . packageInfo ( ) ;
83
+ const idn = pkg . appId . toString ( 16 ) . padStart ( 8 , "0" ) . toUpperCase ( ) ;
84
+ return "/storage/js_" + pkg . type + "s/" + idn ;
85
+ }
86
+
87
+ return FsUtils . selfPath ;
88
+ }
89
+
90
+ static fullPath ( path ) {
91
+ return FsUtils . getSelfPath ( ) + "/assets/" + path ;
92
+ }
93
+
94
+ static rmTree ( path ) {
95
+ if ( ! path . startsWith ( "/storage" ) ) path = FsUtils . fullPath ( path ) ;
96
+
97
+ const [ files , e ] = hmFS . readdir ( path ) ;
98
+ for ( let i in files ) {
99
+ FsUtils . rmTree ( path + "/" + files [ i ] ) ;
100
+ }
101
+
102
+ hmFS . remove ( path ) ;
103
+ }
104
+
105
+ static copyTree ( source , dest , removeSource ) {
106
+ if ( ! source . startsWith ( "/storage" ) ) source = FsUtils . fullPath ( source ) ;
107
+ if ( ! dest . startsWith ( "/storage" ) ) dest = FsUtils . fullPath ( dest ) ;
108
+
109
+ if ( ! FsUtils . isFolder ( source ) ) {
110
+ console . log ( "copy" , source , "->" , dest ) ;
111
+ FsUtils . copy ( source , dest ) ;
112
+ } else {
113
+ const [ files , e ] = hmFS . readdir ( source ) ;
114
+ hmFS . mkdir ( dest ) ;
115
+ for ( let i in files ) {
116
+ FsUtils . copyTree ( source + "/" + files [ i ] , dest + "/" + files [ i ] , removeSource ) ;
117
+ }
118
+ }
119
+
120
+ if ( removeSource ) {
121
+ console . log ( "Delete" , source ) ;
122
+ hmFS . remove ( source ) ;
123
+ }
124
+ }
125
+
126
+ static sizeTree ( path ) {
127
+ if ( ! path . startsWith ( "/storage" ) ) path = FsUtils . fullPath ( path ) ;
128
+
129
+ const [ files , e ] = hmFS . readdir ( path ) ;
130
+ let value = 0 ;
131
+
132
+ for ( let fn in files ) {
133
+ const file = path + "/" + files [ fn ] ;
134
+ const statPath = "../../../" + file . substring ( 9 ) ;
135
+ const [ st , e ] = hmFS . stat_asset ( statPath ) ;
136
+ value += st . size ? st . size : FsUtils . sizeTree ( file ) ;
137
+ }
138
+
139
+ return value ;
140
+ }
141
+
142
+ // https://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
143
+ static strToUtf8 ( str ) {
144
+ var utf8 = [ ] ;
145
+ for ( var i = 0 ; i < str . length ; i ++ ) {
146
+ var charcode = str . charCodeAt ( i ) ;
147
+ if ( charcode < 0x80 ) utf8 . push ( charcode ) ;
148
+ else if ( charcode < 0x800 ) {
149
+ utf8 . push ( 0xc0 | ( charcode >> 6 ) ,
150
+ 0x80 | ( charcode & 0x3f ) ) ;
151
+ } else if ( charcode < 0xd800 || charcode >= 0xe000 ) {
152
+ utf8 . push ( 0xe0 | ( charcode >> 12 ) ,
153
+ 0x80 | ( ( charcode >> 6 ) & 0x3f ) ,
154
+ 0x80 | ( charcode & 0x3f ) ) ;
155
+ } else {
156
+ i ++ ;
157
+ charcode = 0x10000 + ( ( ( charcode & 0x3ff ) << 10 )
158
+ | ( str . charCodeAt ( i ) & 0x3ff ) ) ;
159
+ utf8 . push ( 0xf0 | ( charcode >> 18 ) ,
160
+ 0x80 | ( ( charcode >> 12 ) & 0x3f ) ,
161
+ 0x80 | ( ( charcode >> 6 ) & 0x3f ) ,
162
+ 0x80 | ( charcode & 0x3f ) ) ;
163
+ }
164
+ }
165
+
166
+ return new Uint8Array ( utf8 ) . buffer ;
167
+ }
168
+
169
+ // source: https://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript
170
+ static Utf8ArrayToStr ( array ) {
171
+ var out , i , len , c ;
172
+ var char2 , char3 ;
173
+
174
+ out = "" ;
175
+ len = array . length ;
176
+ i = 0 ;
177
+ while ( i < len ) {
178
+ c = array [ i ++ ] ;
179
+ switch ( c >> 4 ) {
180
+ case 0 :
181
+ case 1 :
182
+ case 2 :
183
+ case 3 :
184
+ case 4 :
185
+ case 5 :
186
+ case 6 :
187
+ case 7 :
188
+ // 0xxxxxxx
189
+ out += String . fromCharCode ( c ) ;
190
+ break ;
191
+ case 12 :
192
+ case 13 :
193
+ // 110x xxxx 10xx xxxx
194
+ char2 = array [ i ++ ] ;
195
+ out += String . fromCharCode (
196
+ ( ( c & 0x1f ) << 6 ) | ( char2 & 0x3f )
197
+ ) ;
198
+ break ;
199
+ case 14 :
200
+ // 1110 xxxx 10xx xxxx 10xx xxxx
201
+ char2 = array [ i ++ ] ;
202
+ char3 = array [ i ++ ] ;
203
+ out += String . fromCharCode (
204
+ ( ( c & 0x0f ) << 12 ) |
205
+ ( ( char2 & 0x3f ) << 6 ) |
206
+ ( ( char3 & 0x3f ) << 0 )
207
+ ) ;
208
+ break ;
209
+ }
210
+ }
211
+
212
+ return out ;
213
+ }
214
+
215
+ static printBytes ( val ) {
216
+ if ( this . fsUnitCfg === undefined )
217
+ this . fsUnitCfg = hmFS . SysProGetBool ( "mmk_tb_fs_unit" ) ;
218
+
219
+ const options = this . fsUnitCfg ? [ "B" , "KiB" , "MiB" ] : [ "B" , "KB" , "MB" ] ;
220
+ const base = this . fsUnitCfg ? 1024 : 1000 ;
221
+
222
+ let curr = 0 ;
223
+ while ( val > 800 && curr < options . length ) {
224
+ val = val / base ;
225
+ curr ++ ;
226
+ }
227
+
228
+ return Math . round ( val * 100 ) / 100 + " " + options [ curr ] ;
229
+ }
230
+ }
0 commit comments