@@ -24,102 +24,92 @@ export const initUntarJS = async (): Promise<IUnpackJSAPI> => {
2424 // fileCountPtr is the pointer to 4 bytes of memory in WebAssembly's heap that holds fileCount value from the ExtractedArchive structure in unpack.c.
2525 const fileCountPtr = wasmModule . _malloc ( 4 ) ;
2626
27- try {
28- const resultPtr = wasmModule . _extract_archive (
29- inputPtr ,
30- data . length ,
31- fileCountPtr
27+ const resultPtr = wasmModule . _extract_archive (
28+ inputPtr ,
29+ data . length ,
30+ fileCountPtr
31+ ) ;
32+
33+ /**
34+ * Since extract_archive returns a pointer that refers to an instance of the ExtractedArchive in unpack.c
35+ typedef struct {
36+ FileData* files;
37+ size_t fileCount;
38+ int status;
39+ char* error_message;
40+ } ExtractedArchive;
41+
42+ its fields are laid out in memory sequentially. Based on this and types each field will take 4 bytes:
43+
44+ 4 bytes 4 bytes 4 bytes 4 bytes
45+ ---------------|---------------|---------------|---------------
46+ files fileCount status error_message
47+
48+ `resultPtr` points to the beginning of the ExtractedArchive structure in WebAssembly memory
49+ and in order to get pointer of statusPtr we need to calculate it as: 0(offset of file pointer) + 4 (offset of fileCount) + 4 (offset for status)
50+ 'status' field and pointer of `error_message` are 32-bit signed integer
51+ */
52+ const statusPtr = wasmModule . getValue ( resultPtr + 8 , 'i32' ) ;
53+ const errorMessagePtr = wasmModule . getValue ( resultPtr + 12 , 'i32' ) ;
54+ if ( statusPtr !== 1 ) {
55+ const errorMessage = wasmModule . UTF8ToString ( errorMessagePtr ) ;
56+ console . error (
57+ 'Extraction failed with status:' ,
58+ statusPtr ,
59+ 'Error:' ,
60+ errorMessage
3261 ) ;
33-
34- /**
35- * Since extract_archive returns a pointer that refers to an instance of the ExtractedArchive in unpack.c
36- typedef struct {
37- FileData* files;
38- size_t fileCount;
39- int status;
40- char* error_message;
41- } ExtractedArchive;
42-
43- its fields are laid out in memory sequentially. Based on this and types each field will take 4 bytes:
44-
45- 4 bytes 4 bytes 4 bytes 4 bytes
46- ---------------|---------------|---------------|---------------
47- files fileCount status error_message
48-
49- `resultPtr` points to the beginning of the ExtractedArchive structure in WebAssembly memory
50- and in order to get pointer of statusPtr we need to calculate it as: 0(offset of file pointer) + 4 (offset of fileCount) + 4 (offset for status)
51- 'status' field and pointer of `error_message` are 32-bit signed integer
52- */
53- const statusPtr = wasmModule . getValue ( resultPtr + 8 , 'i32' ) ;
54- const errorMessagePtr = wasmModule . getValue ( resultPtr + 12 , 'i32' ) ;
55- if ( statusPtr !== 1 ) {
56- const errorMessage = wasmModule . UTF8ToString ( errorMessagePtr ) ;
57- console . error (
58- 'Extraction failed with status:' ,
59- statusPtr ,
60- 'Error:' ,
61- errorMessage
62- ) ;
63- return { } ;
64- }
65- const filesPtr = wasmModule . getValue ( resultPtr , 'i32' ) ;
66- const fileCount = wasmModule . getValue ( resultPtr + 4 , 'i32' ) ;
67-
68- const files : FilesData = { } ;
69-
70- /**
71- * FilesPtr is a pointer that refers to an instance of the FileData in unpack.c
72- typedef struct {
73- char* filename;
74- uint8_t* data;
75- size_t data_size;
76- } FileData;
77-
78- and its fields are laid out in memory sequentially too so each field take 4 bytes:
79-
80- 4 bytes 4 bytes 4 bytes
81- ---------------|---------------|---------------
82- filename data data_size
83-
84- `filesPtr + i * 12` calculates the memory address of the i-th FileData element in the array
85- where `12` is the size of each FileData structure in memory in bytes: 4 + 4 + 4
86- */
87-
88- for ( let i = 0 ; i < fileCount ; i ++ ) {
89- const fileDataPtr = filesPtr + i * 12 ;
90- const filenamePtr = wasmModule . getValue ( fileDataPtr , 'i32' ) ;
91- const dataSize = wasmModule . getValue ( fileDataPtr + 8 , 'i32' ) ;
92- const dataPtr = wasmModule . getValue ( fileDataPtr + 4 , 'i32' ) ;
93- const filename = wasmModule . UTF8ToString ( filenamePtr ) ;
94- const fileData = new Uint8Array (
95- wasmModule . HEAPU8 . buffer ,
96- dataPtr ,
97- dataSize
98- ) ;
99-
100- files [ filename ] = fileData ;
101- }
102-
103- wasmModule . _free ( inputPtr ) ;
104- wasmModule . _free ( fileCountPtr ) ;
105- wasmModule . _free ( errorMessagePtr ) ;
106- wasmModule . _free ( resultPtr ) ;
107-
108- return files ;
109- } catch ( error ) {
110- console . error ( 'Error during extraction:' , error ) ;
11162 return { } ;
11263 }
64+ const filesPtr = wasmModule . getValue ( resultPtr , 'i32' ) ;
65+ const fileCount = wasmModule . getValue ( resultPtr + 4 , 'i32' ) ;
66+
67+ const files : FilesData = { } ;
68+
69+ /**
70+ * FilesPtr is a pointer that refers to an instance of the FileData in unpack.c
71+ typedef struct {
72+ char* filename;
73+ uint8_t* data;
74+ size_t data_size;
75+ } FileData;
76+
77+ and its fields are laid out in memory sequentially too so each field take 4 bytes:
78+
79+ 4 bytes 4 bytes 4 bytes
80+ ---------------|---------------|---------------
81+ filename data data_size
82+
83+ `filesPtr + i * 12` calculates the memory address of the i-th FileData element in the array
84+ where `12` is the size of each FileData structure in memory in bytes: 4 + 4 + 4
85+ */
86+
87+ for ( let i = 0 ; i < fileCount ; i ++ ) {
88+ const fileDataPtr = filesPtr + i * 12 ;
89+ const filenamePtr = wasmModule . getValue ( fileDataPtr , 'i32' ) ;
90+ const dataSize = wasmModule . getValue ( fileDataPtr + 8 , 'i32' ) ;
91+ const dataPtr = wasmModule . getValue ( fileDataPtr + 4 , 'i32' ) ;
92+ const filename = wasmModule . UTF8ToString ( filenamePtr ) ;
93+ const fileData = new Uint8Array (
94+ wasmModule . HEAPU8 . buffer ,
95+ dataPtr ,
96+ dataSize
97+ ) ;
98+
99+ files [ filename ] = fileData ;
100+ }
101+
102+ wasmModule . _free ( inputPtr ) ;
103+ wasmModule . _free ( fileCountPtr ) ;
104+ wasmModule . _free ( errorMessagePtr ) ;
105+ wasmModule . _free ( resultPtr ) ;
106+
107+ return files ;
113108 } ;
114109
115110 const extract = async ( url : string ) : Promise < FilesData > => {
116- try {
117- const data = await fetchByteArray ( url ) ;
118- return await extractData ( data ) ;
119- } catch ( error ) {
120- console . error ( 'Error during extracting:' , error ) ;
121- return { } ;
122- }
111+ const data = await fetchByteArray ( url ) ;
112+ return await extractData ( data ) ;
123113 }
124114
125115 return {
0 commit comments