@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.
Files changed (72) hide show
  1. package/dist/dist.min.js +4500 -261
  2. package/dist/es5/arcgis-webscene-loader.js +1 -1
  3. package/dist/es5/i3s-attribute-loader.js +1 -1
  4. package/dist/es5/i3s-building-scene-layer-loader.js +1 -1
  5. package/dist/es5/i3s-content-loader.js +1 -1
  6. package/dist/es5/i3s-loader.js +1 -1
  7. package/dist/es5/i3s-node-page-loader.js +1 -1
  8. package/dist/es5/i3s-slpk-loader.js +1 -1
  9. package/dist/es5/index.js +14 -0
  10. package/dist/es5/index.js.map +1 -1
  11. package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js +25 -12
  12. package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js.map +1 -1
  13. package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js +62 -33
  14. package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -1
  15. package/dist/es5/lib/parsers/parse-zip/buffer-file-provider.js +46 -0
  16. package/dist/es5/lib/parsers/parse-zip/buffer-file-provider.js.map +1 -0
  17. package/dist/es5/lib/parsers/parse-zip/cd-file-header.js +75 -35
  18. package/dist/es5/lib/parsers/parse-zip/cd-file-header.js.map +1 -1
  19. package/dist/es5/lib/parsers/parse-zip/file-provider.js +2 -0
  20. package/dist/es5/lib/parsers/parse-zip/file-provider.js.map +1 -0
  21. package/dist/es5/lib/parsers/parse-zip/local-file-header.js +63 -17
  22. package/dist/es5/lib/parsers/parse-zip/local-file-header.js.map +1 -1
  23. package/dist/esm/arcgis-webscene-loader.js +1 -1
  24. package/dist/esm/i3s-attribute-loader.js +1 -1
  25. package/dist/esm/i3s-building-scene-layer-loader.js +1 -1
  26. package/dist/esm/i3s-content-loader.js +1 -1
  27. package/dist/esm/i3s-loader.js +1 -1
  28. package/dist/esm/i3s-node-page-loader.js +1 -1
  29. package/dist/esm/i3s-slpk-loader.js +1 -1
  30. package/dist/esm/index.js +2 -0
  31. package/dist/esm/index.js.map +1 -1
  32. package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js +8 -4
  33. package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js.map +1 -1
  34. package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js +11 -12
  35. package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -1
  36. package/dist/esm/lib/parsers/parse-zip/buffer-file-provider.js +23 -0
  37. package/dist/esm/lib/parsers/parse-zip/buffer-file-provider.js.map +1 -0
  38. package/dist/esm/lib/parsers/parse-zip/cd-file-header.js +7 -7
  39. package/dist/esm/lib/parsers/parse-zip/cd-file-header.js.map +1 -1
  40. package/dist/esm/lib/parsers/parse-zip/file-provider.js +2 -0
  41. package/dist/esm/lib/parsers/parse-zip/file-provider.js.map +1 -0
  42. package/dist/esm/lib/parsers/parse-zip/local-file-header.js +16 -10
  43. package/dist/esm/lib/parsers/parse-zip/local-file-header.js.map +1 -1
  44. package/dist/i3s-content-worker-node.js +2 -2
  45. package/dist/i3s-content-worker.js +8 -8
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +3 -1
  49. package/dist/lib/parsers/parse-slpk/parse-slpk.d.ts.map +1 -1
  50. package/dist/lib/parsers/parse-slpk/parse-slpk.js +8 -4
  51. package/dist/lib/parsers/parse-slpk/slpk-archieve.d.ts.map +1 -1
  52. package/dist/lib/parsers/parse-slpk/slpk-archieve.js +12 -12
  53. package/dist/lib/parsers/parse-zip/buffer-file-provider.d.ts +37 -0
  54. package/dist/lib/parsers/parse-zip/buffer-file-provider.d.ts.map +1 -0
  55. package/dist/lib/parsers/parse-zip/buffer-file-provider.js +47 -0
  56. package/dist/lib/parsers/parse-zip/cd-file-header.d.ts +9 -20
  57. package/dist/lib/parsers/parse-zip/cd-file-header.d.ts.map +1 -1
  58. package/dist/lib/parsers/parse-zip/cd-file-header.js +7 -7
  59. package/dist/lib/parsers/parse-zip/file-provider.d.ts +31 -0
  60. package/dist/lib/parsers/parse-zip/file-provider.d.ts.map +1 -0
  61. package/dist/lib/parsers/parse-zip/file-provider.js +2 -0
  62. package/dist/lib/parsers/parse-zip/local-file-header.d.ts +8 -13
  63. package/dist/lib/parsers/parse-zip/local-file-header.d.ts.map +1 -1
  64. package/dist/lib/parsers/parse-zip/local-file-header.js +16 -10
  65. package/package.json +9 -9
  66. package/src/index.ts +2 -0
  67. package/src/lib/parsers/parse-slpk/parse-slpk.ts +12 -4
  68. package/src/lib/parsers/parse-slpk/slpk-archieve.ts +14 -13
  69. package/src/lib/parsers/parse-zip/buffer-file-provider.ts +55 -0
  70. package/src/lib/parsers/parse-zip/cd-file-header.ts +25 -32
  71. package/src/lib/parsers/parse-zip/file-provider.ts +34 -0
  72. 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 decompressedData = await processOnWorker(CompressionWorker, data, {
138
- compression: 'gzip',
139
- operation: 'decompress',
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
- * File name
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 = (headerOffset: number, buffer: DataView): ZipCDFileHeader => {
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, true);
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, true);
47
+ const fileNameLength = await buffer.getUint16(headerOffset + offsets.CD_FILE_NAME_LENGTH_OFFSET);
56
48
 
57
- const fileName = buffer.buffer.slice(
58
- headerOffset + offsets.CD_FILE_NAME_OFFSET,
59
- headerOffset + offsets.CD_FILE_NAME_OFFSET + fileNameLength
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, true); // setting it to the one from zip64
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
- * Extra field length
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: DataView
33
- ): ZipLocalFileHeader => {
34
- const offsets = {
35
- COMPRESSED_SIZE_OFFSET: 18,
36
- FILE_NAME_LENGTH_OFFSET: 26,
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, true);
43
+ const fileNameLength = await buffer.getUint16(headerOffset + offsets.FILE_NAME_LENGTH_OFFSET);
42
44
 
43
- const extraFieldLength = buffer.getUint16(headerOffset + offsets.EXTRA_FIELD_LENGTH_OFFSET, true);
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, true);
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