@loaders.gl/i3s 4.0.0-alpha.10 → 4.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.min.js +4500 -261
- package/dist/es5/arcgis-webscene-loader.js +1 -1
- package/dist/es5/i3s-attribute-loader.js +1 -1
- package/dist/es5/i3s-building-scene-layer-loader.js +1 -1
- package/dist/es5/i3s-content-loader.js +1 -1
- package/dist/es5/i3s-loader.js +1 -1
- package/dist/es5/i3s-node-page-loader.js +1 -1
- package/dist/es5/i3s-slpk-loader.js +1 -1
- package/dist/es5/index.js +14 -0
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js +25 -12
- package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js.map +1 -1
- package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js +62 -33
- package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -1
- package/dist/es5/lib/parsers/parse-zip/buffer-file-provider.js +46 -0
- package/dist/es5/lib/parsers/parse-zip/buffer-file-provider.js.map +1 -0
- package/dist/es5/lib/parsers/parse-zip/cd-file-header.js +75 -35
- package/dist/es5/lib/parsers/parse-zip/cd-file-header.js.map +1 -1
- package/dist/es5/lib/parsers/parse-zip/file-provider.js +2 -0
- package/dist/es5/lib/parsers/parse-zip/file-provider.js.map +1 -0
- package/dist/es5/lib/parsers/parse-zip/local-file-header.js +63 -17
- package/dist/es5/lib/parsers/parse-zip/local-file-header.js.map +1 -1
- package/dist/esm/arcgis-webscene-loader.js +1 -1
- package/dist/esm/i3s-attribute-loader.js +1 -1
- package/dist/esm/i3s-building-scene-layer-loader.js +1 -1
- package/dist/esm/i3s-content-loader.js +1 -1
- package/dist/esm/i3s-loader.js +1 -1
- package/dist/esm/i3s-node-page-loader.js +1 -1
- package/dist/esm/i3s-slpk-loader.js +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js +8 -4
- package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js.map +1 -1
- package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js +11 -12
- package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -1
- package/dist/esm/lib/parsers/parse-zip/buffer-file-provider.js +23 -0
- package/dist/esm/lib/parsers/parse-zip/buffer-file-provider.js.map +1 -0
- package/dist/esm/lib/parsers/parse-zip/cd-file-header.js +7 -7
- package/dist/esm/lib/parsers/parse-zip/cd-file-header.js.map +1 -1
- package/dist/esm/lib/parsers/parse-zip/file-provider.js +2 -0
- package/dist/esm/lib/parsers/parse-zip/file-provider.js.map +1 -0
- package/dist/esm/lib/parsers/parse-zip/local-file-header.js +16 -10
- package/dist/esm/lib/parsers/parse-zip/local-file-header.js.map +1 -1
- package/dist/i3s-content-worker-node.js +2 -2
- package/dist/i3s-content-worker.js +8 -8
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/parsers/parse-slpk/parse-slpk.d.ts.map +1 -1
- package/dist/lib/parsers/parse-slpk/parse-slpk.js +8 -4
- package/dist/lib/parsers/parse-slpk/slpk-archieve.d.ts.map +1 -1
- package/dist/lib/parsers/parse-slpk/slpk-archieve.js +12 -12
- package/dist/lib/parsers/parse-zip/buffer-file-provider.d.ts +37 -0
- package/dist/lib/parsers/parse-zip/buffer-file-provider.d.ts.map +1 -0
- package/dist/lib/parsers/parse-zip/buffer-file-provider.js +47 -0
- package/dist/lib/parsers/parse-zip/cd-file-header.d.ts +9 -20
- package/dist/lib/parsers/parse-zip/cd-file-header.d.ts.map +1 -1
- package/dist/lib/parsers/parse-zip/cd-file-header.js +7 -7
- package/dist/lib/parsers/parse-zip/file-provider.d.ts +31 -0
- package/dist/lib/parsers/parse-zip/file-provider.d.ts.map +1 -0
- package/dist/lib/parsers/parse-zip/file-provider.js +2 -0
- package/dist/lib/parsers/parse-zip/local-file-header.d.ts +8 -13
- package/dist/lib/parsers/parse-zip/local-file-header.d.ts.map +1 -1
- package/dist/lib/parsers/parse-zip/local-file-header.js +16 -10
- package/package.json +9 -9
- package/src/index.ts +2 -0
- package/src/lib/parsers/parse-slpk/parse-slpk.ts +12 -4
- package/src/lib/parsers/parse-slpk/slpk-archieve.ts +14 -13
- package/src/lib/parsers/parse-zip/buffer-file-provider.ts +55 -0
- package/src/lib/parsers/parse-zip/cd-file-header.ts +25 -32
- package/src/lib/parsers/parse-zip/file-provider.ts +34 -0
- package/src/lib/parsers/parse-zip/local-file-header.ts +33 -24
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {processOnWorker} from '@loaders.gl/worker-utils';
|
|
2
1
|
import md5 from 'md5';
|
|
3
|
-
import {CompressionWorker} from '@loaders.gl/compression';
|
|
4
2
|
import {parseZipLocalFileHeader} from '../parse-zip/local-file-header';
|
|
3
|
+
import {DataViewFileProvider} from '../parse-zip/buffer-file-provider';
|
|
4
|
+
import {GZipCompression} from '@loaders.gl/compression';
|
|
5
5
|
|
|
6
6
|
/** Element of hash array */
|
|
7
7
|
type HashElement = {
|
|
@@ -15,6 +15,7 @@ type HashElement = {
|
|
|
15
15
|
offset: number;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
/** Description of real paths for different file types */
|
|
18
19
|
const PATH_DESCRIPTIONS: {test: RegExp; extensions: string[]}[] = [
|
|
19
20
|
{
|
|
20
21
|
test: /^$/,
|
|
@@ -114,7 +115,7 @@ export class SLPKArchive {
|
|
|
114
115
|
if (decompressedFile) {
|
|
115
116
|
return Buffer.from(decompressedFile);
|
|
116
117
|
}
|
|
117
|
-
const fileWithoutCompression = this.getFileBytes(path);
|
|
118
|
+
const fileWithoutCompression = await this.getFileBytes(path);
|
|
118
119
|
if (fileWithoutCompression) {
|
|
119
120
|
return Buffer.from(fileWithoutCompression);
|
|
120
121
|
}
|
|
@@ -129,17 +130,14 @@ export class SLPKArchive {
|
|
|
129
130
|
* @returns buffer with the file data
|
|
130
131
|
*/
|
|
131
132
|
private async getDataByPath(path: string): Promise<ArrayBuffer | undefined> {
|
|
132
|
-
const data = this.getFileBytes(path);
|
|
133
|
+
const data = await this.getFileBytes(path);
|
|
133
134
|
if (!data) {
|
|
134
135
|
return undefined;
|
|
135
136
|
}
|
|
136
137
|
if (/\.gz$/.test(path)) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
_workerType: 'test',
|
|
141
|
-
gzip: {}
|
|
142
|
-
});
|
|
138
|
+
const compression = new GZipCompression();
|
|
139
|
+
|
|
140
|
+
const decompressedData = await compression.decompress(data);
|
|
143
141
|
return decompressedData;
|
|
144
142
|
}
|
|
145
143
|
return Buffer.from(data);
|
|
@@ -150,17 +148,20 @@ export class SLPKArchive {
|
|
|
150
148
|
* @param path - path inside the archive
|
|
151
149
|
* @returns buffer with the raw file data
|
|
152
150
|
*/
|
|
153
|
-
private getFileBytes(path: string): ArrayBuffer | undefined {
|
|
151
|
+
private async getFileBytes(path: string): Promise<ArrayBuffer | undefined> {
|
|
154
152
|
const nameHash = Buffer.from(md5(path), 'hex');
|
|
155
153
|
const fileInfo = this.hashArray.find((val) => Buffer.compare(val.hash, nameHash) === 0);
|
|
156
154
|
if (!fileInfo) {
|
|
157
155
|
return undefined;
|
|
158
156
|
}
|
|
159
157
|
|
|
160
|
-
const localFileHeader = parseZipLocalFileHeader(
|
|
158
|
+
const localFileHeader = await parseZipLocalFileHeader(
|
|
161
159
|
this.slpkArchive.byteOffset + fileInfo?.offset,
|
|
162
|
-
this.slpkArchive
|
|
160
|
+
new DataViewFileProvider(this.slpkArchive)
|
|
163
161
|
);
|
|
162
|
+
if (!localFileHeader) {
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
164
165
|
|
|
165
166
|
const compressedFile = this.slpkArchive.buffer.slice(
|
|
166
167
|
localFileHeader.fileDataOffset,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {FileProvider} from './file-provider';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Provides file data using DataView
|
|
5
|
+
*/
|
|
6
|
+
export class DataViewFileProvider implements FileProvider {
|
|
7
|
+
/**
|
|
8
|
+
* The DataView from which data is provided
|
|
9
|
+
*/
|
|
10
|
+
private file: DataView;
|
|
11
|
+
|
|
12
|
+
constructor(file: DataView) {
|
|
13
|
+
this.file = file;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets an unsigned 8-bit integer at the specified byte offset from the start of the file.
|
|
18
|
+
* @param offset The offset, in bytes, from the start of the file where to read the data.
|
|
19
|
+
*/
|
|
20
|
+
getUint8(offset: number): Promise<number> {
|
|
21
|
+
return Promise.resolve(this.file.getUint8(offset));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Gets an unsigned 16-bit integer at the specified byte offset from the start of the file.
|
|
26
|
+
* @param offset The offset, in bytes, from the start of the file where to read the data.
|
|
27
|
+
*/
|
|
28
|
+
getUint16(offset: number): Promise<number> {
|
|
29
|
+
return Promise.resolve(this.file.getUint16(offset, true));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Gets an unsigned 32-bit integer at the specified byte offset from the start of the file.
|
|
34
|
+
* @param offset The offset, in bytes, from the start of the file where to read the data.
|
|
35
|
+
*/
|
|
36
|
+
getUint32(offset: number): Promise<number> {
|
|
37
|
+
return Promise.resolve(this.file.getUint32(offset, true));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* returns an ArrayBuffer whose contents are a copy of this file bytes from startOffset, inclusive, up to endOffset, exclusive.
|
|
42
|
+
* @param startOffset The offset, in bytes, from the start of the file where to start reading the data.
|
|
43
|
+
* @param endOffset The offset, in bytes, from the start of the file where to end reading the data.
|
|
44
|
+
*/
|
|
45
|
+
slice(startOffset: number, endOffset: number): Promise<ArrayBuffer> {
|
|
46
|
+
return Promise.resolve(this.file.buffer.slice(startOffset, endOffset));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* the length (in bytes) of the data.
|
|
51
|
+
*/
|
|
52
|
+
get length() {
|
|
53
|
+
return this.file.byteLength;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,31 +1,21 @@
|
|
|
1
|
+
import {FileProvider} from './file-provider';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* zip central directory file header info
|
|
3
5
|
* according to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
4
6
|
*/
|
|
5
7
|
export type ZipCDFileHeader = {
|
|
6
|
-
/**
|
|
7
|
-
* Compressed size
|
|
8
|
-
*/
|
|
8
|
+
/** Compressed size */
|
|
9
9
|
compressedSize: number;
|
|
10
|
-
/**
|
|
11
|
-
* Uncompressed size
|
|
12
|
-
*/
|
|
10
|
+
/** Uncompressed size */
|
|
13
11
|
uncompressedSize: number;
|
|
14
|
-
/**
|
|
15
|
-
* File name length
|
|
16
|
-
*/
|
|
12
|
+
/** File name length */
|
|
17
13
|
fileNameLength: number;
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
fileName: ArrayBuffer;
|
|
22
|
-
/**
|
|
23
|
-
* Extra field offset
|
|
24
|
-
*/
|
|
14
|
+
/** File name */
|
|
15
|
+
fileName: string;
|
|
16
|
+
/** Extra field offset */
|
|
25
17
|
extraOffset: number;
|
|
26
|
-
/**
|
|
27
|
-
* Relative offset of local file header
|
|
28
|
-
*/
|
|
18
|
+
/** Relative offset of local file header */
|
|
29
19
|
localHeaderOffset: number;
|
|
30
20
|
};
|
|
31
21
|
|
|
@@ -35,7 +25,10 @@ export type ZipCDFileHeader = {
|
|
|
35
25
|
* @param buffer - buffer containing whole array
|
|
36
26
|
* @returns Info from the header
|
|
37
27
|
*/
|
|
38
|
-
export const parseZipCDFileHeader = (
|
|
28
|
+
export const parseZipCDFileHeader = async (
|
|
29
|
+
headerOffset: number,
|
|
30
|
+
buffer: FileProvider
|
|
31
|
+
): Promise<ZipCDFileHeader> => {
|
|
39
32
|
const offsets = {
|
|
40
33
|
CD_COMPRESSED_SIZE_OFFSET: 20,
|
|
41
34
|
CD_UNCOMPRESSED_SIZE_OFFSET: 24,
|
|
@@ -45,25 +38,25 @@ export const parseZipCDFileHeader = (headerOffset: number, buffer: DataView): Zi
|
|
|
45
38
|
CD_FILE_NAME_OFFSET: 46
|
|
46
39
|
};
|
|
47
40
|
|
|
48
|
-
const compressedSize = buffer.getUint32(headerOffset + offsets.CD_COMPRESSED_SIZE_OFFSET
|
|
41
|
+
const compressedSize = await buffer.getUint32(headerOffset + offsets.CD_COMPRESSED_SIZE_OFFSET);
|
|
49
42
|
|
|
50
|
-
const uncompressedSize = buffer.getUint32(
|
|
51
|
-
headerOffset + offsets.CD_UNCOMPRESSED_SIZE_OFFSET
|
|
52
|
-
true
|
|
43
|
+
const uncompressedSize = await buffer.getUint32(
|
|
44
|
+
headerOffset + offsets.CD_UNCOMPRESSED_SIZE_OFFSET
|
|
53
45
|
);
|
|
54
46
|
|
|
55
|
-
const fileNameLength = buffer.getUint16(headerOffset + offsets.CD_FILE_NAME_LENGTH_OFFSET
|
|
47
|
+
const fileNameLength = await buffer.getUint16(headerOffset + offsets.CD_FILE_NAME_LENGTH_OFFSET);
|
|
56
48
|
|
|
57
|
-
const fileName =
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
const fileName = new TextDecoder().decode(
|
|
50
|
+
await buffer.slice(
|
|
51
|
+
headerOffset + offsets.CD_FILE_NAME_OFFSET,
|
|
52
|
+
headerOffset + offsets.CD_FILE_NAME_OFFSET + fileNameLength
|
|
53
|
+
)
|
|
60
54
|
);
|
|
61
55
|
|
|
62
56
|
const extraOffset = headerOffset + offsets.CD_FILE_NAME_OFFSET + fileNameLength;
|
|
63
57
|
|
|
64
|
-
const oldFormatOffset = buffer.getUint32(
|
|
65
|
-
headerOffset + offsets.CD_LOCAL_HEADER_OFFSET_OFFSET
|
|
66
|
-
true
|
|
58
|
+
const oldFormatOffset = await buffer.getUint32(
|
|
59
|
+
headerOffset + offsets.CD_LOCAL_HEADER_OFFSET_OFFSET
|
|
67
60
|
);
|
|
68
61
|
|
|
69
62
|
let fileDataOffset = oldFormatOffset;
|
|
@@ -78,7 +71,7 @@ export const parseZipCDFileHeader = (headerOffset: number, buffer: DataView): Zi
|
|
|
78
71
|
}
|
|
79
72
|
|
|
80
73
|
// getUint32 needs to be replaced with getBigUint64 for archieves bigger than 2gb
|
|
81
|
-
fileDataOffset = buffer.getUint32(extraOffset + offsetInZip64Data
|
|
74
|
+
fileDataOffset = await buffer.getUint32(extraOffset + offsetInZip64Data); // setting it to the one from zip64
|
|
82
75
|
}
|
|
83
76
|
const localHeaderOffset = fileDataOffset;
|
|
84
77
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for providing file data
|
|
3
|
+
*/
|
|
4
|
+
export interface FileProvider {
|
|
5
|
+
/**
|
|
6
|
+
* Gets an unsigned 8-bit integer at the specified byte offset from the start of the file.
|
|
7
|
+
* @param offset The offset, in bytes, from the start of the file where to read the data.
|
|
8
|
+
*/
|
|
9
|
+
getUint8(offset: number): Promise<number>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Gets an unsigned 16-bit integer at the specified byte offset from the start of the file.
|
|
13
|
+
* @param offset The offset, in bytes, from the start of the file where to read the data.
|
|
14
|
+
*/
|
|
15
|
+
getUint16(offset: number): Promise<number>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Gets an unsigned 32-bit integer at the specified byte offset from the start of the file.
|
|
19
|
+
* @param offset The offset, in bytes, from the file of the view where to read the data.
|
|
20
|
+
*/
|
|
21
|
+
getUint32(offset: number): Promise<number>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* returns an ArrayBuffer whose contents are a copy of this file bytes from startOffset, inclusive, up to endOffset, exclusive.
|
|
25
|
+
* @param startOffset The offset, in bytes, from the start of the file where to start reading the data.
|
|
26
|
+
* @param endOffset The offset, in bytes, from the start of the file where to end reading the data.
|
|
27
|
+
*/
|
|
28
|
+
slice(startOffset: number, endOffset: number): Promise<ArrayBuffer>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* the length (in bytes) of the data.
|
|
32
|
+
*/
|
|
33
|
+
length: number;
|
|
34
|
+
}
|
|
@@ -1,54 +1,63 @@
|
|
|
1
|
+
import {FileProvider} from './file-provider';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* zip local file header info
|
|
3
5
|
* according to https://en.wikipedia.org/wiki/ZIP_(file_format)
|
|
4
6
|
*/
|
|
5
7
|
export type ZipLocalFileHeader = {
|
|
6
|
-
/**
|
|
7
|
-
* File name length
|
|
8
|
-
*/
|
|
8
|
+
/** File name length */
|
|
9
9
|
fileNameLength: number;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
/** File name */
|
|
11
|
+
fileName: string;
|
|
12
|
+
/** Extra field length */
|
|
13
13
|
extraFieldLength: number;
|
|
14
|
-
/**
|
|
15
|
-
* Offset of the file data
|
|
16
|
-
*/
|
|
14
|
+
/** Offset of the file data */
|
|
17
15
|
fileDataOffset: number;
|
|
18
|
-
/**
|
|
19
|
-
* Compressed size
|
|
20
|
-
*/
|
|
16
|
+
/** Compressed size */
|
|
21
17
|
compressedSize: number;
|
|
22
18
|
};
|
|
23
19
|
|
|
20
|
+
const offsets = {
|
|
21
|
+
COMPRESSED_SIZE_OFFSET: 18,
|
|
22
|
+
FILE_NAME_LENGTH_OFFSET: 26,
|
|
23
|
+
EXTRA_FIELD_LENGTH_OFFSET: 28,
|
|
24
|
+
FILE_NAME_OFFSET: 30
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const signature = Buffer.from([0x50, 0x4b, 0x03, 0x04]);
|
|
28
|
+
|
|
24
29
|
/**
|
|
25
30
|
* Parses local file header of zip file
|
|
26
31
|
* @param headerOffset - offset in the archive where header starts
|
|
27
32
|
* @param buffer - buffer containing whole array
|
|
28
33
|
* @returns Info from the header
|
|
29
34
|
*/
|
|
30
|
-
export const parseZipLocalFileHeader = (
|
|
35
|
+
export const parseZipLocalFileHeader = async (
|
|
31
36
|
headerOffset: number,
|
|
32
|
-
buffer:
|
|
33
|
-
): ZipLocalFileHeader => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
EXTRA_FIELD_LENGTH_OFFSET: 28,
|
|
38
|
-
FILE_NAME_OFFSET: 30
|
|
39
|
-
};
|
|
37
|
+
buffer: FileProvider
|
|
38
|
+
): Promise<ZipLocalFileHeader | undefined> => {
|
|
39
|
+
if (Buffer.from(await buffer.slice(headerOffset, headerOffset + 4)).compare(signature) !== 0) {
|
|
40
|
+
return Promise.resolve(undefined);
|
|
41
|
+
}
|
|
40
42
|
|
|
41
|
-
const fileNameLength = buffer.getUint16(headerOffset + offsets.FILE_NAME_LENGTH_OFFSET
|
|
43
|
+
const fileNameLength = await buffer.getUint16(headerOffset + offsets.FILE_NAME_LENGTH_OFFSET);
|
|
42
44
|
|
|
43
|
-
const
|
|
45
|
+
const fileName = new TextDecoder().decode(
|
|
46
|
+
await buffer.slice(
|
|
47
|
+
headerOffset + offsets.FILE_NAME_OFFSET,
|
|
48
|
+
headerOffset + offsets.FILE_NAME_OFFSET + fileNameLength
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
const extraFieldLength = await buffer.getUint16(headerOffset + offsets.EXTRA_FIELD_LENGTH_OFFSET);
|
|
44
52
|
|
|
45
53
|
const fileDataOffset =
|
|
46
54
|
headerOffset + offsets.FILE_NAME_OFFSET + fileNameLength + extraFieldLength;
|
|
47
55
|
|
|
48
|
-
const compressedSize = buffer.getUint32(headerOffset + offsets.COMPRESSED_SIZE_OFFSET
|
|
56
|
+
const compressedSize = await buffer.getUint32(headerOffset + offsets.COMPRESSED_SIZE_OFFSET);
|
|
49
57
|
|
|
50
58
|
return {
|
|
51
59
|
fileNameLength,
|
|
60
|
+
fileName,
|
|
52
61
|
extraFieldLength,
|
|
53
62
|
fileDataOffset,
|
|
54
63
|
compressedSize
|