@@ -129,90 +129,98 @@ class BRARCHIVEHandler implements FormatHandler {
129129 }
130130 }
131131 else if ( ( inputFormat . internal === "json" || inputFormat . internal === "zip" ) && outputFormat . internal === "brarchive" ) {
132- const working_files : FileData [ ] = [ ] ;
132+ const working_files : { [ key : string ] : FileData [ ] } = { } ;
133133
134134 // Special handling for zip input.
135135 if ( inputFormat . internal === "zip" ) {
136136 for ( const file of inputFiles ) {
137137 const zip = new JSZip ( ) ;
138138 await zip . loadAsync ( file . bytes ) ;
139139
140+ let done_something_flag = false ;
141+
140142 // Extract all files from ZIP
143+ working_files [ file . name ] = [ ] ;
141144 for ( const [ filename , zipEntry ] of Object . entries ( zip . files ) ) {
142145 if ( ! zipEntry . dir ) {
143146 if ( filename . endsWith ( ".json" ) === false ) {
144147 throw new Error ( "Archive contains more than just .json files; abort." ) ;
145148 }
146149 else {
150+ done_something_flag = true ;
147151 const data = await zipEntry . async ( "uint8array" ) ;
148- working_files . push ( {
152+ working_files [ file . name ] . push ( {
149153 name : filename ,
150154 bytes : data
151155 } ) ;
152156 }
153157 }
154158 }
155- }
156-
157- // Throw error if empty
158- if ( working_files . length === 0 ) {
159- throw new Error ( "No applicable files to unzip found." ) ;
159+
160+ // Throw error if empty
161+ if ( ! done_something_flag ) {
162+ throw new Error ( "No applicable files to unzip found in " + file . name ) ;
163+ }
160164 }
161165 }
162166 else {
163- working_files . push ( ...inputFiles ) ;
167+ working_files [ "Unnamed.brarchive" ] = [ ] ;
168+ working_files [ "Unnamed.brarchive" ] . push ( ...inputFiles ) ;
164169 }
165170
166- // Unlikely, but handle it.
167- if ( working_files . length > 0xFFFFFFFF ) {
168- throw new Error ( "Too many input files to encode in 4 bytes." ) ;
169- }
170-
171- // Zip all the inputs into one archive.
172- const working_bytes : number [ ] = [ ] ;
173-
174- // Write headers and magic numbers.
175- working_bytes . push ( 0x7D , 0x27 , 0x25 , 0xB1 ) ;
176- working_bytes . push ( 0xA0 , 0x52 , 0x70 , 0x26 ) ;
177- working_bytes . push ( ...write_lendian_4 ( working_files . length ) ) ;
178- working_bytes . push ( 0x01 , 0x00 , 0x00 , 0x00 ) ;
179-
180- // Start writing FileEntry's
181- const encoder = new TextEncoder ( ) ;
182- for ( let i = 0 ; i < working_files . length ; i ++ ) {
183- // Shorten name if need be
184- let name = working_files [ i ] . name
185- while ( ( encoder . encode ( name ) ) . length > 247 ) {
186- name = name . substring ( 0 , name . length - 1 ) ;
171+ // Iterate through each collection of files.
172+ for ( const key in working_files ) {
173+ // Unlikely, but handle it.
174+ if ( working_files [ key ] . length > 0xFFFFFFFF ) {
175+ throw new Error ( "Too many input files to encode in 4 bytes." ) ;
187176 }
177+
178+ // Zip all the inputs into one archive.
179+ const working_bytes : number [ ] = [ ] ;
188180
189- const name_bytes : Uint8Array = encoder . encode ( name ) ;
190- working_bytes . push ( name_bytes . length ) ;
181+ // Write headers and magic numbers.
182+ working_bytes . push ( 0x7D , 0x27 , 0x25 , 0xB1 ) ;
183+ working_bytes . push ( 0xA0 , 0x52 , 0x70 , 0x26 ) ;
184+ working_bytes . push ( ...write_lendian_4 ( working_files [ key ] . length ) ) ;
185+ working_bytes . push ( 0x01 , 0x00 , 0x00 , 0x00 ) ;
191186
192- // Push name and padding
193- working_bytes . push ( ...name_bytes ) ;
194- for ( let pushed = name_bytes . length ; pushed < 247 ; pushed ++ ) {
195- working_bytes . push ( 0x00 ) ;
187+ // Start writing FileEntry's
188+ const encoder = new TextEncoder ( ) ;
189+ for ( let i = 0 ; i < working_files [ key ] . length ; i ++ ) {
190+ // Shorten name if need be
191+ let name = working_files [ key ] [ i ] . name
192+ while ( ( encoder . encode ( name ) ) . length > 247 ) {
193+ name = name . substring ( 0 , name . length - 1 ) ;
194+ }
195+
196+ const name_bytes : Uint8Array = encoder . encode ( name ) ;
197+ working_bytes . push ( name_bytes . length ) ;
198+
199+ // Push name and padding
200+ working_bytes . push ( ...name_bytes ) ;
201+ for ( let pushed = name_bytes . length ; pushed < 247 ; pushed ++ ) {
202+ working_bytes . push ( 0x00 ) ;
203+ }
204+
205+ // Relative offset is the sum of the file sizes of every file that comes before it.
206+ let relative_offset = 0 ;
207+ for ( let i2 = i - 1 ; i2 >= 0 ; i2 -- ) {
208+ relative_offset += working_files [ key ] [ i2 ] . bytes . length ;
209+ }
210+ working_bytes . push ( ...write_lendian_4 ( relative_offset ) ) ;
211+
212+ // Then, the file size of *this* file.
213+ working_bytes . push ( ...write_lendian_4 ( working_files [ key ] [ i ] . bytes . length ) ) ;
196214 }
197215
198- // Relative offset is the sum of the file sizes of every file that comes before it.
199- let relative_offset = 0 ;
200- for ( let i2 = i - 1 ; i2 >= 0 ; i2 -- ) {
201- relative_offset += working_files [ i2 ] . bytes . length ;
216+ // FileEntry's are done. Write raw data.
217+ for ( let i = 0 ; i < working_files [ key ] . length ; i ++ ) {
218+ working_bytes . push ( ...working_files [ key ] [ i ] . bytes ) ;
202219 }
203- working_bytes . push ( ...write_lendian_4 ( relative_offset ) ) ;
204220
205- // Then, the file size of *this* file.
206- working_bytes . push ( ... write_lendian_4 ( working_files [ i ] . bytes . length ) ) ;
221+ // Finally, push our file.
222+ outputFiles . push ( { bytes : new Uint8Array ( working_bytes ) , name : key . split ( "." ) . slice ( 0 , - 1 ) . join ( "." ) + "." + outputFormat . extension } ) ;
207223 }
208-
209- // FileEntry's are done. Write raw data.
210- for ( let i = 0 ; i < working_files . length ; i ++ ) {
211- working_bytes . push ( ...working_files [ i ] . bytes ) ;
212- }
213-
214- // Finally, push our file.
215- outputFiles . push ( { bytes : new Uint8Array ( working_bytes ) , name : "Unnamed.brarchive" } ) ;
216224 }
217225 else {
218226 throw new Error ( "Invalid input-output" ) ;
0 commit comments