1
1
let tarball = { } ;
2
2
3
+ if ( typeof module === "object" && typeof module . exports === "object" ) {
4
+ // CommonJS
5
+ module . exports = tarball ;
6
+ } else if ( typeof this === "object" ) {
7
+ // Browser
8
+ // use this instead of window, since window might not exist and throw and error
9
+ this . tarball = tarball ;
10
+ }
11
+
3
12
tarball . TarReader = class {
4
13
constructor ( ) {
5
14
this . fileInfo = [ ] ;
@@ -19,12 +28,10 @@ tarball.TarReader = class {
19
28
}
20
29
21
30
readArrayBuffer ( arrayBuffer ) {
22
- return new Promise ( ( resolve , reject ) => {
23
- this . buffer = arrayBuffer ;
24
- this . fileInfo = [ ] ;
25
- this . _readFileInfo ( ) ;
26
- resolve ( this . fileInfo ) ;
27
- } ) ;
31
+ this . buffer = arrayBuffer ;
32
+ this . fileInfo = [ ] ;
33
+ this . _readFileInfo ( ) ;
34
+ return this . fileInfo ;
28
35
}
29
36
30
37
_readFileInfo ( ) {
@@ -61,13 +68,9 @@ tarball.TarReader = class {
61
68
62
69
_readString ( str_offset , size ) {
63
70
let strView = new Uint8Array ( this . buffer , str_offset , size ) ;
64
- let i = 0 ;
65
- let rtnStr = "" ;
66
- while ( strView [ i ] != 0 ) {
67
- rtnStr += String . fromCharCode ( strView [ i ] ) ;
68
- i ++ ;
69
- }
70
- return rtnStr ;
71
+ let i = strView . indexOf ( 0 ) ;
72
+ let td = new TextDecoder ( ) ;
73
+ return td . decode ( strView . slice ( 0 , i ) ) ;
71
74
}
72
75
73
76
_readFileName ( header_offset ) {
@@ -104,30 +107,37 @@ tarball.TarReader = class {
104
107
return blob ;
105
108
}
106
109
110
+ _readFileBinary ( file_offset , size ) {
111
+ let view = new Uint8Array ( this . buffer , file_offset , size ) ;
112
+ return view ;
113
+ }
114
+
107
115
_readTextFile ( file_offset , size ) {
108
116
let view = new Uint8Array ( this . buffer , file_offset , size ) ;
109
- let data = "" ;
110
- for ( let i = 0 ; i < size ; i ++ ) {
111
- data += String . fromCharCode ( view [ i ] ) ;
112
- }
113
- return data ;
117
+ let td = new TextDecoder ( ) ;
118
+ return td . decode ( view ) ;
114
119
}
115
120
116
121
getTextFile ( file_name ) {
117
- let i = this . fileInfo . findIndex ( info => info . name == file_name ) ;
118
- if ( i >= 0 ) {
119
- let info = this . fileInfo [ i ] ;
122
+ let info = this . fileInfo . find ( info => info . name == file_name ) ;
123
+ if ( info ) {
120
124
return this . _readTextFile ( info . header_offset + 512 , info . size ) ;
121
125
}
122
126
}
123
127
124
128
getFileBlob ( file_name , mimetype ) {
125
- let i = this . fileInfo . findIndex ( info => info . name == file_name ) ;
126
- if ( i >= 0 ) {
127
- let info = this . fileInfo [ i ] ;
129
+ let info = this . fileInfo . find ( info => info . name == file_name ) ;
130
+ if ( info ) {
128
131
return this . _readFileBlob ( info . header_offset + 512 , info . size , mimetype ) ;
129
132
}
130
133
}
134
+
135
+ getFileBinary ( file_name ) {
136
+ let info = this . fileInfo . find ( info => info . name == file_name ) ;
137
+ if ( info ) {
138
+ return this . _readFileBinary ( info . header_offset + 512 , info . size ) ;
139
+ }
140
+ }
131
141
} ;
132
142
133
143
tarball . TarWriter = class {
@@ -136,11 +146,8 @@ tarball.TarWriter = class {
136
146
}
137
147
138
148
addTextFile ( name , text , opts ) {
139
- let buf = new ArrayBuffer ( text . length ) ;
140
- let arr = new Uint8Array ( buf ) ;
141
- for ( let i = 0 ; i < text . length ; i ++ ) {
142
- arr [ i ] = text . charCodeAt ( i ) ;
143
- }
149
+ let te = new TextEncoder ( ) ;
150
+ let arr = te . encode ( text ) ;
144
151
this . fileData . push ( {
145
152
name : name ,
146
153
array : arr ,
@@ -201,7 +208,7 @@ tarball.TarWriter = class {
201
208
}
202
209
203
210
async download ( filename ) {
204
- let blob = await this . write ( ) ;
211
+ let blob = await this . writeBlob ( ) ;
205
212
let $downloadElem = document . createElement ( 'a' ) ;
206
213
$downloadElem . href = URL . createObjectURL ( blob ) ;
207
214
$downloadElem . download = filename ;
@@ -211,17 +218,23 @@ tarball.TarWriter = class {
211
218
document . body . removeChild ( $downloadElem ) ;
212
219
}
213
220
214
- write ( ) {
221
+ async writeBlob ( onUpdate ) {
222
+ return new Blob ( [ await this . write ( onUpdate ) ] , { "type" :"application/x-tar" } ) ;
223
+ }
224
+
225
+ write ( onUpdate ) {
215
226
return new Promise ( ( resolve , reject ) => {
216
227
this . _createBuffer ( ) ;
217
228
let offset = 0 ;
218
229
let filesAdded = 0 ;
219
230
let onFileDataAdded = ( ) => {
220
231
filesAdded ++ ;
232
+ if ( onUpdate ) {
233
+ onUpdate ( filesAdded / this . fileData . length * 100 ) ;
234
+ }
221
235
if ( filesAdded === this . fileData . length ) {
222
236
let arr = new Uint8Array ( this . buffer ) ;
223
- let blob = new Blob ( [ arr ] , { "type" :"application/x-tar" } ) ;
224
- resolve ( blob ) ;
237
+ resolve ( arr ) ;
225
238
}
226
239
} ;
227
240
for ( let fileIdx = 0 ; fileIdx < this . fileData . length ; fileIdx ++ ) {
@@ -269,12 +282,19 @@ tarball.TarWriter = class {
269
282
270
283
_writeString ( str , offset , size ) {
271
284
let strView = new Uint8Array ( this . buffer , offset , size ) ;
272
- for ( let i = 0 ; i < size ; i ++ ) {
273
- if ( i < str . length ) {
274
- strView [ i ] = str . charCodeAt ( i ) ;
275
- } else {
285
+ let te = new TextEncoder ( ) ;
286
+ if ( te . encodeInto ) {
287
+ // let the browser write directly into the buffer
288
+ let written = te . encodeInto ( str , strView ) . written ;
289
+ for ( let i = written ; i < size ; i ++ ) {
276
290
strView [ i ] = 0 ;
277
291
}
292
+ } else {
293
+ // browser can't write directly into the buffer, do it manually
294
+ let arr = te . encode ( str ) ;
295
+ for ( let i = 0 ; i < size ; i ++ ) {
296
+ strView [ i ] = i < arr . length ? arr [ i ] : 0 ;
297
+ }
278
298
}
279
299
}
280
300
0 commit comments