@loaders.gl/i3s 4.0.0-alpha.15 → 4.0.0-alpha.16
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 +278 -197
- 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.map +1 -1
- package/dist/es5/lib/parsers/constants.js +14 -15
- package/dist/es5/lib/parsers/constants.js.map +1 -1
- package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js +93 -29
- package/dist/es5/lib/parsers/parse-slpk/parse-slpk.js.map +1 -1
- package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js +51 -30
- package/dist/es5/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -1
- package/dist/es5/lib/parsers/parse-zip/cd-file-header.js +61 -42
- package/dist/es5/lib/parsers/parse-zip/cd-file-header.js.map +1 -1
- package/dist/es5/lib/parsers/parse-zip/end-of-central-directory.js +100 -0
- package/dist/es5/lib/parsers/parse-zip/end-of-central-directory.js.map +1 -0
- package/dist/es5/lib/parsers/parse-zip/local-file-header.js +1 -1
- package/dist/es5/lib/parsers/parse-zip/local-file-header.js.map +1 -1
- package/dist/es5/lib/parsers/parse-zip/search-from-the-end.js.map +1 -0
- package/dist/es5/types.js +1 -14
- package/dist/es5/types.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.map +1 -1
- package/dist/esm/lib/parsers/constants.js +14 -15
- package/dist/esm/lib/parsers/constants.js.map +1 -1
- package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js +49 -16
- package/dist/esm/lib/parsers/parse-slpk/parse-slpk.js.map +1 -1
- package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js +35 -18
- package/dist/esm/lib/parsers/parse-slpk/slpk-archieve.js.map +1 -1
- package/dist/esm/lib/parsers/parse-zip/cd-file-header.js +14 -8
- package/dist/esm/lib/parsers/parse-zip/cd-file-header.js.map +1 -1
- package/dist/esm/lib/parsers/parse-zip/end-of-central-directory.js +33 -0
- package/dist/esm/lib/parsers/parse-zip/end-of-central-directory.js.map +1 -0
- package/dist/esm/lib/parsers/parse-zip/local-file-header.js +1 -1
- package/dist/esm/lib/parsers/parse-zip/local-file-header.js.map +1 -1
- package/dist/esm/lib/parsers/parse-zip/search-from-the-end.js.map +1 -0
- package/dist/esm/types.js +0 -12
- package/dist/esm/types.js.map +1 -1
- package/dist/i3s-content-worker-node.js +47 -47
- package/dist/i3s-content-worker-node.js.map +2 -2
- package/dist/i3s-content-worker.js +22 -34
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/parsers/constants.d.ts.map +1 -1
- package/dist/lib/parsers/constants.js +14 -15
- package/dist/lib/parsers/parse-slpk/parse-slpk.d.ts +2 -1
- package/dist/lib/parsers/parse-slpk/parse-slpk.d.ts.map +1 -1
- package/dist/lib/parsers/parse-slpk/parse-slpk.js +61 -15
- package/dist/lib/parsers/parse-slpk/slpk-archieve.d.ts +21 -10
- package/dist/lib/parsers/parse-slpk/slpk-archieve.d.ts.map +1 -1
- package/dist/lib/parsers/parse-slpk/slpk-archieve.js +53 -24
- package/dist/lib/parsers/parse-zip/cd-file-header.d.ts +5 -1
- package/dist/lib/parsers/parse-zip/cd-file-header.d.ts.map +1 -1
- package/dist/lib/parsers/parse-zip/cd-file-header.js +15 -9
- package/dist/lib/parsers/parse-zip/end-of-central-directory.d.ts +18 -0
- package/dist/lib/parsers/parse-zip/end-of-central-directory.d.ts.map +1 -0
- package/dist/lib/parsers/parse-zip/end-of-central-directory.js +41 -0
- package/dist/lib/parsers/parse-zip/local-file-header.d.ts +1 -1
- package/dist/lib/parsers/parse-zip/local-file-header.d.ts.map +1 -1
- package/dist/lib/parsers/parse-zip/local-file-header.js +1 -1
- package/dist/lib/parsers/parse-zip/search-from-the-end.d.ts.map +1 -0
- package/dist/types.d.ts +17 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -13
- package/package.json +9 -9
- package/src/index.ts +0 -1
- package/src/lib/parsers/constants.ts +14 -15
- package/src/lib/parsers/parse-slpk/parse-slpk.ts +79 -25
- package/src/lib/parsers/parse-slpk/slpk-archieve.ts +55 -37
- package/src/lib/parsers/parse-zip/cd-file-header.ts +27 -9
- package/src/lib/parsers/parse-zip/end-of-central-directory.ts +78 -0
- package/src/lib/parsers/parse-zip/local-file-header.ts +2 -2
- package/src/types.ts +25 -40
- package/dist/es5/lib/parsers/parse-slpk/search-from-the-end.js.map +0 -1
- package/dist/esm/lib/parsers/parse-slpk/search-from-the-end.js.map +0 -1
- package/dist/lib/parsers/parse-slpk/search-from-the-end.d.ts.map +0 -1
- /package/dist/es5/lib/parsers/{parse-slpk → parse-zip}/search-from-the-end.js +0 -0
- /package/dist/esm/lib/parsers/{parse-slpk → parse-zip}/search-from-the-end.js +0 -0
- /package/dist/lib/parsers/{parse-slpk → parse-zip}/search-from-the-end.d.ts +0 -0
- /package/dist/lib/parsers/{parse-slpk → parse-zip}/search-from-the-end.js +0 -0
- /package/src/lib/parsers/{parse-slpk → parse-zip}/search-from-the-end.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { load } from '@loaders.gl/core';
|
|
2
2
|
import { parseI3STileAttribute } from './lib/parsers/parse-i3s-attribute';
|
|
3
3
|
import { getUrlWithToken } from './lib/utils/url-utils';
|
|
4
|
-
const VERSION = typeof "4.0.0-alpha.
|
|
4
|
+
const VERSION = typeof "4.0.0-alpha.16" !== 'undefined' ? "4.0.0-alpha.16" : 'latest';
|
|
5
5
|
const EMPTY_VALUE = '';
|
|
6
6
|
const REJECTED_STATUS = 'rejected';
|
|
7
7
|
export const I3SAttributeLoader = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseBuildingSceneLayer } from './lib/parsers/parse-i3s-building-scene-layer';
|
|
2
|
-
const VERSION = typeof "4.0.0-alpha.
|
|
2
|
+
const VERSION = typeof "4.0.0-alpha.16" !== 'undefined' ? "4.0.0-alpha.16" : 'beta';
|
|
3
3
|
export const I3SBuildingSceneLayerLoader = {
|
|
4
4
|
name: 'I3S Building Scene Layer',
|
|
5
5
|
id: 'i3s-building-scene-layer',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseI3STileContent } from './lib/parsers/parse-i3s-tile-content';
|
|
2
|
-
const VERSION = typeof "4.0.0-alpha.
|
|
2
|
+
const VERSION = typeof "4.0.0-alpha.16" !== 'undefined' ? "4.0.0-alpha.16" : 'beta';
|
|
3
3
|
export const I3SContentLoader = {
|
|
4
4
|
name: 'I3S Content (Indexed Scene Layers)',
|
|
5
5
|
id: 'i3s-content',
|
package/dist/esm/i3s-loader.js
CHANGED
|
@@ -2,7 +2,7 @@ import { parse } from '@loaders.gl/core';
|
|
|
2
2
|
import { I3SContentLoader } from './i3s-content-loader';
|
|
3
3
|
import { normalizeTileData, normalizeTilesetData } from './lib/parsers/parse-i3s';
|
|
4
4
|
import { COORDINATE_SYSTEM } from './lib/parsers/constants';
|
|
5
|
-
const VERSION = typeof "4.0.0-alpha.
|
|
5
|
+
const VERSION = typeof "4.0.0-alpha.16" !== 'undefined' ? "4.0.0-alpha.16" : 'latest';
|
|
6
6
|
const TILESET_REGEX = /layers\/[0-9]+$/;
|
|
7
7
|
const TILE_HEADER_REGEX = /nodes\/([0-9-]+|root)$/;
|
|
8
8
|
const SLPK_HEX = '504b0304';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const VERSION = typeof "4.0.0-alpha.
|
|
1
|
+
const VERSION = typeof "4.0.0-alpha.16" !== 'undefined' ? "4.0.0-alpha.16" : 'latest';
|
|
2
2
|
async function parseNodePage(data, options) {
|
|
3
3
|
return JSON.parse(new TextDecoder().decode(data));
|
|
4
4
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseSLPK as parseSLPKFromProvider } from './lib/parsers/parse-slpk/parse-slpk';
|
|
2
2
|
import { DataViewFileProvider } from './lib/parsers/parse-zip/data-view-file-provider';
|
|
3
|
-
const VERSION = typeof "4.0.0-alpha.
|
|
3
|
+
const VERSION = typeof "4.0.0-alpha.16" !== 'undefined' ? "4.0.0-alpha.16" : 'latest';
|
|
4
4
|
export const SLPKLoader = {
|
|
5
5
|
name: 'I3S SLPK (Scene Layer Package)',
|
|
6
6
|
id: 'slpk',
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["COORDINATE_SYSTEM","I3SLoader","SLPKLoader","I3SContentLoader","I3SAttributeLoader","loadFeatureAttributes","I3SBuildingSceneLayerLoader","I3SNodePageLoader","ArcGisWebSceneLoader","parseZipLocalFileHeader","parseSLPK"],"sources":["../../src/index.ts"],"sourcesContent":["// loaders.gl, MIT license\n\nexport type {\n BoundingVolumes,\n Mbs,\n Obb,\n SceneLayer3D,\n AttributeStorageInfo,\n Field,\n ESRIField,\n PopupInfo,\n Node3DIndexDocument,\n LodSelection,\n NodeReference,\n Resource,\n MaxScreenThresholdSQ,\n NodeInPage,\n SharedResources,\n Attribute,\n Extent,\n FeatureAttribute,\n FieldInfo,\n I3SMaterialDefinition,\n TextureDefinitionInfo,\n MaterialDefinitionInfo,\n FullExtent,\n StatisticsInfo,\n StatsInfo,\n Histogram,\n ValueCount,\n BuildingSceneSublayer,\n
|
|
1
|
+
{"version":3,"file":"index.js","names":["COORDINATE_SYSTEM","I3SLoader","SLPKLoader","I3SContentLoader","I3SAttributeLoader","loadFeatureAttributes","I3SBuildingSceneLayerLoader","I3SNodePageLoader","ArcGisWebSceneLoader","parseZipLocalFileHeader","parseSLPK"],"sources":["../../src/index.ts"],"sourcesContent":["// loaders.gl, MIT license\n\nexport type {\n BoundingVolumes,\n Mbs,\n Obb,\n SceneLayer3D,\n AttributeStorageInfo,\n Field,\n ESRIField,\n PopupInfo,\n Node3DIndexDocument,\n LodSelection,\n NodeReference,\n Resource,\n MaxScreenThresholdSQ,\n NodeInPage,\n SharedResources,\n Attribute,\n Extent,\n FeatureAttribute,\n FieldInfo,\n I3SMaterialDefinition,\n TextureDefinitionInfo,\n MaterialDefinitionInfo,\n FullExtent,\n StatisticsInfo,\n StatsInfo,\n Histogram,\n ValueCount,\n BuildingSceneSublayer,\n OperationalLayer,\n TextureSetDefinitionFormats\n} from './types';\nexport type {FileProvider} from './lib/parsers/parse-zip/file-provider';\n\nexport {COORDINATE_SYSTEM} from './lib/parsers/constants';\n\nexport {I3SLoader} from './i3s-loader';\nexport {SLPKLoader} from './i3s-slpk-loader';\nexport {I3SContentLoader} from './i3s-content-loader';\nexport {I3SAttributeLoader, loadFeatureAttributes} from './i3s-attribute-loader';\nexport {I3SBuildingSceneLayerLoader} from './i3s-building-scene-layer-loader';\nexport {I3SNodePageLoader} from './i3s-node-page-loader';\nexport {ArcGisWebSceneLoader} from './arcgis-webscene-loader';\nexport {parseZipLocalFileHeader} from './lib/parsers/parse-zip/local-file-header';\nexport {parseSLPK} from './lib/parsers/parse-slpk/parse-slpk';\n"],"mappings":"AAoCA,SAAQA,iBAAiB,QAAO,yBAAyB;AAEzD,SAAQC,SAAS,QAAO,cAAc;AACtC,SAAQC,UAAU,QAAO,mBAAmB;AAC5C,SAAQC,gBAAgB,QAAO,sBAAsB;AACrD,SAAQC,kBAAkB,EAAEC,qBAAqB,QAAO,wBAAwB;AAChF,SAAQC,2BAA2B,QAAO,mCAAmC;AAC7E,SAAQC,iBAAiB,QAAO,wBAAwB;AACxD,SAAQC,oBAAoB,QAAO,0BAA0B;AAC7D,SAAQC,uBAAuB,QAAO,2CAA2C;AACjF,SAAQC,SAAS,QAAO,qCAAqC"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import GL from '@luma.gl/constants';
|
|
2
|
-
import { DATA_TYPE } from '../../types';
|
|
3
2
|
export function getConstructorForDataFormat(dataType) {
|
|
4
3
|
switch (dataType) {
|
|
5
|
-
case
|
|
4
|
+
case 'UInt8':
|
|
6
5
|
return Uint8Array;
|
|
7
|
-
case
|
|
6
|
+
case 'UInt16':
|
|
8
7
|
return Uint16Array;
|
|
9
|
-
case
|
|
8
|
+
case 'UInt32':
|
|
10
9
|
return Uint32Array;
|
|
11
|
-
case
|
|
10
|
+
case 'Float32':
|
|
12
11
|
return Float32Array;
|
|
13
|
-
case
|
|
12
|
+
case 'UInt64':
|
|
14
13
|
return Float64Array;
|
|
15
14
|
default:
|
|
16
15
|
throw new Error("parse i3s tile content: unknown type of data: ".concat(dataType));
|
|
@@ -25,18 +24,18 @@ export const GL_TYPE_MAP = {
|
|
|
25
24
|
};
|
|
26
25
|
export function sizeOf(dataType) {
|
|
27
26
|
switch (dataType) {
|
|
28
|
-
case
|
|
27
|
+
case 'UInt8':
|
|
29
28
|
return 1;
|
|
30
|
-
case
|
|
31
|
-
case
|
|
29
|
+
case 'UInt16':
|
|
30
|
+
case 'Int16':
|
|
32
31
|
return 2;
|
|
33
|
-
case
|
|
34
|
-
case
|
|
35
|
-
case
|
|
32
|
+
case 'UInt32':
|
|
33
|
+
case 'Int32':
|
|
34
|
+
case 'Float32':
|
|
36
35
|
return 4;
|
|
37
|
-
case
|
|
38
|
-
case
|
|
39
|
-
case
|
|
36
|
+
case 'UInt64':
|
|
37
|
+
case 'Int64':
|
|
38
|
+
case 'Float64':
|
|
40
39
|
return 8;
|
|
41
40
|
default:
|
|
42
41
|
throw new Error("parse i3s tile content: unknown size of data: ".concat(dataType));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":["GL","
|
|
1
|
+
{"version":3,"file":"constants.js","names":["GL","getConstructorForDataFormat","dataType","Uint8Array","Uint16Array","Uint32Array","Float32Array","Float64Array","Error","concat","GL_TYPE_MAP","UInt8","UNSIGNED_BYTE","UInt16","UNSIGNED_SHORT","Float32","FLOAT","UInt32","UNSIGNED_INT","UInt64","DOUBLE","sizeOf","STRING_ATTRIBUTE_TYPE","OBJECT_ID_ATTRIBUTE_TYPE","FLOAT_64_TYPE","INT_16_ATTRIBUTE_TYPE","COORDINATE_SYSTEM"],"sources":["../../../../src/lib/parsers/constants.ts"],"sourcesContent":["import GL from '@luma.gl/constants';\n\nexport function getConstructorForDataFormat(dataType: string) {\n switch (dataType) {\n case 'UInt8':\n return Uint8Array;\n case 'UInt16':\n return Uint16Array;\n case 'UInt32':\n return Uint32Array;\n case 'Float32':\n return Float32Array;\n case 'UInt64':\n return Float64Array;\n default:\n throw new Error(`parse i3s tile content: unknown type of data: ${dataType}`);\n }\n}\n\nexport const GL_TYPE_MAP: {[key: string]: number} = {\n UInt8: GL.UNSIGNED_BYTE,\n UInt16: GL.UNSIGNED_SHORT,\n Float32: GL.FLOAT,\n UInt32: GL.UNSIGNED_INT,\n UInt64: GL.DOUBLE\n};\n/**\n * Returns how many bytes a type occupies\n * @param dataType\n * @returns\n */\nexport function sizeOf(dataType: string): number {\n switch (dataType) {\n case 'UInt8':\n return 1;\n case 'UInt16':\n case 'Int16':\n return 2;\n case 'UInt32':\n case 'Int32':\n case 'Float32':\n return 4;\n case 'UInt64':\n case 'Int64':\n case 'Float64':\n return 8;\n default:\n throw new Error(`parse i3s tile content: unknown size of data: ${dataType}`);\n }\n}\n\nexport const STRING_ATTRIBUTE_TYPE = 'String';\nexport const OBJECT_ID_ATTRIBUTE_TYPE = 'Oid32';\nexport const FLOAT_64_TYPE = 'Float64';\nexport const INT_16_ATTRIBUTE_TYPE = 'Int16';\n\n// https://github.com/visgl/deck.gl/blob/9548f43cba2234a1f4877b6b17f6c88eb35b2e08/modules/core/src/lib/constants.js#L27\n// Describes the format of positions\nexport enum COORDINATE_SYSTEM {\n /**\n * `LNGLAT` if rendering into a geospatial viewport, `CARTESIAN` otherwise\n */\n DEFAULT = -1,\n /**\n * Positions are interpreted as [lng, lat, elevation]\n * lng lat are degrees, elevation is meters. distances as meters.\n */\n LNGLAT = 1,\n /**\n * Positions are interpreted as meter offsets, distances as meters\n */\n METER_OFFSETS = 2,\n /**\n * Positions are interpreted as lng lat offsets: [deltaLng, deltaLat, elevation]\n * deltaLng, deltaLat are delta degrees, elevation is meters.\n * distances as meters.\n */\n LNGLAT_OFFSETS = 3,\n /**\n * Non-geospatial\n */\n CARTESIAN = 0\n}\n"],"mappings":"AAAA,OAAOA,EAAE,MAAM,oBAAoB;AAEnC,OAAO,SAASC,2BAA2BA,CAACC,QAAgB,EAAE;EAC5D,QAAQA,QAAQ;IACd,KAAK,OAAO;MACV,OAAOC,UAAU;IACnB,KAAK,QAAQ;MACX,OAAOC,WAAW;IACpB,KAAK,QAAQ;MACX,OAAOC,WAAW;IACpB,KAAK,SAAS;MACZ,OAAOC,YAAY;IACrB,KAAK,QAAQ;MACX,OAAOC,YAAY;IACrB;MACE,MAAM,IAAIC,KAAK,kDAAAC,MAAA,CAAkDP,QAAQ,CAAE,CAAC;EAChF;AACF;AAEA,OAAO,MAAMQ,WAAoC,GAAG;EAClDC,KAAK,EAAEX,EAAE,CAACY,aAAa;EACvBC,MAAM,EAAEb,EAAE,CAACc,cAAc;EACzBC,OAAO,EAAEf,EAAE,CAACgB,KAAK;EACjBC,MAAM,EAAEjB,EAAE,CAACkB,YAAY;EACvBC,MAAM,EAAEnB,EAAE,CAACoB;AACb,CAAC;AAMD,OAAO,SAASC,MAAMA,CAACnB,QAAgB,EAAU;EAC/C,QAAQA,QAAQ;IACd,KAAK,OAAO;MACV,OAAO,CAAC;IACV,KAAK,QAAQ;IACb,KAAK,OAAO;MACV,OAAO,CAAC;IACV,KAAK,QAAQ;IACb,KAAK,OAAO;IACZ,KAAK,SAAS;MACZ,OAAO,CAAC;IACV,KAAK,QAAQ;IACb,KAAK,OAAO;IACZ,KAAK,SAAS;MACZ,OAAO,CAAC;IACV;MACE,MAAM,IAAIM,KAAK,kDAAAC,MAAA,CAAkDP,QAAQ,CAAE,CAAC;EAChF;AACF;AAEA,OAAO,MAAMoB,qBAAqB,GAAG,QAAQ;AAC7C,OAAO,MAAMC,wBAAwB,GAAG,OAAO;AAC/C,OAAO,MAAMC,aAAa,GAAG,SAAS;AACtC,OAAO,MAAMC,qBAAqB,GAAG,OAAO;AAI5C,WAAYC,iBAAiB,aAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAA,OAAjBA,iBAAiB;AAAA"}
|
|
@@ -1,23 +1,56 @@
|
|
|
1
|
-
import
|
|
1
|
+
import md5 from 'md5';
|
|
2
|
+
import { parseZipCDFileHeader, signature as cdHeaderSignature } from '../parse-zip/cd-file-header';
|
|
3
|
+
import { parseEoCDRecord } from '../parse-zip/end-of-central-directory';
|
|
2
4
|
import { parseZipLocalFileHeader } from '../parse-zip/local-file-header';
|
|
3
|
-
import { searchFromTheEnd } from '
|
|
4
|
-
import { SLPKArchive } from './slpk-archieve';
|
|
5
|
-
export const parseSLPK = async fileProvider => {
|
|
6
|
-
const
|
|
7
|
-
const hashCDOffset = await searchFromTheEnd(fileProvider, cdFileHeaderSignature);
|
|
5
|
+
import { searchFromTheEnd } from '../parse-zip/search-from-the-end';
|
|
6
|
+
import { SLPKArchive, compareHashes } from './slpk-archieve';
|
|
7
|
+
export const parseSLPK = async (fileProvider, cb) => {
|
|
8
|
+
const hashCDOffset = await searchFromTheEnd(fileProvider, cdHeaderSignature);
|
|
8
9
|
const cdFileHeader = await parseZipCDFileHeader(hashCDOffset, fileProvider);
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
let hashData;
|
|
11
|
+
if ((cdFileHeader === null || cdFileHeader === void 0 ? void 0 : cdFileHeader.fileName) !== '@specialIndexFileHASH128@') {
|
|
12
|
+
cb === null || cb === void 0 ? void 0 : cb('SLPK doesnt contain hash file');
|
|
13
|
+
hashData = await generateHashInfo(fileProvider);
|
|
14
|
+
cb === null || cb === void 0 ? void 0 : cb('hash info has been composed according to central directory records');
|
|
15
|
+
} else {
|
|
16
|
+
cb === null || cb === void 0 ? void 0 : cb('SLPK contains hash file');
|
|
17
|
+
const localFileHeader = await parseZipLocalFileHeader(cdFileHeader.localHeaderOffset, fileProvider);
|
|
18
|
+
if (!localFileHeader) {
|
|
19
|
+
throw new Error('corrupted SLPK');
|
|
20
|
+
}
|
|
21
|
+
const fileDataOffset = localFileHeader.fileDataOffset;
|
|
22
|
+
const hashFile = await fileProvider.slice(fileDataOffset, fileDataOffset + localFileHeader.compressedSize);
|
|
23
|
+
hashData = parseHashFile(hashFile);
|
|
11
24
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
25
|
+
return new SLPKArchive(fileProvider, hashData);
|
|
26
|
+
};
|
|
27
|
+
const generateHashInfo = async fileProvider => {
|
|
28
|
+
const {
|
|
29
|
+
cdStartOffset
|
|
30
|
+
} = await parseEoCDRecord(fileProvider);
|
|
31
|
+
let cdHeader = await parseZipCDFileHeader(cdStartOffset, fileProvider);
|
|
32
|
+
const hashInfo = [];
|
|
33
|
+
while (cdHeader) {
|
|
34
|
+
hashInfo.push({
|
|
35
|
+
hash: Buffer.from(md5(cdHeader.fileName.split('\\').join('/').toLocaleLowerCase()), 'hex'),
|
|
36
|
+
offset: cdHeader.localHeaderOffset
|
|
37
|
+
});
|
|
38
|
+
cdHeader = await parseZipCDFileHeader(cdHeader.extraOffset + BigInt(cdHeader.extraFieldLength), fileProvider);
|
|
15
39
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
40
|
+
hashInfo.sort((a, b) => compareHashes(a.hash, b.hash));
|
|
41
|
+
return hashInfo;
|
|
42
|
+
};
|
|
43
|
+
const parseHashFile = hashFile => {
|
|
44
|
+
const hashFileBuffer = Buffer.from(hashFile);
|
|
45
|
+
const hashArray = [];
|
|
46
|
+
for (let i = 0; i < hashFileBuffer.buffer.byteLength; i = i + 24) {
|
|
47
|
+
const offsetBuffer = new DataView(hashFileBuffer.buffer.slice(hashFileBuffer.byteOffset + i + 16, hashFileBuffer.byteOffset + i + 24));
|
|
48
|
+
const offset = offsetBuffer.getBigUint64(offsetBuffer.byteOffset, true);
|
|
49
|
+
hashArray.push({
|
|
50
|
+
hash: Buffer.from(hashFileBuffer.subarray(hashFileBuffer.byteOffset + i, hashFileBuffer.byteOffset + i + 16)),
|
|
51
|
+
offset
|
|
52
|
+
});
|
|
20
53
|
}
|
|
21
|
-
return
|
|
54
|
+
return hashArray;
|
|
22
55
|
};
|
|
23
56
|
//# sourceMappingURL=parse-slpk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-slpk.js","names":["parseZipCDFileHeader","parseZipLocalFileHeader","searchFromTheEnd","SLPKArchive","parseSLPK","fileProvider","
|
|
1
|
+
{"version":3,"file":"parse-slpk.js","names":["md5","parseZipCDFileHeader","signature","cdHeaderSignature","parseEoCDRecord","parseZipLocalFileHeader","searchFromTheEnd","SLPKArchive","compareHashes","parseSLPK","fileProvider","cb","hashCDOffset","cdFileHeader","hashData","fileName","generateHashInfo","localFileHeader","localHeaderOffset","Error","fileDataOffset","hashFile","slice","compressedSize","parseHashFile","cdStartOffset","cdHeader","hashInfo","push","hash","Buffer","from","split","join","toLocaleLowerCase","offset","extraOffset","BigInt","extraFieldLength","sort","a","b","hashFileBuffer","hashArray","i","buffer","byteLength","offsetBuffer","DataView","byteOffset","getBigUint64","subarray"],"sources":["../../../../../src/lib/parsers/parse-slpk/parse-slpk.ts"],"sourcesContent":["import md5 from 'md5';\nimport {parseZipCDFileHeader, signature as cdHeaderSignature} from '../parse-zip/cd-file-header';\nimport {parseEoCDRecord} from '../parse-zip/end-of-central-directory';\nimport {FileProvider} from '../parse-zip/file-provider';\nimport {parseZipLocalFileHeader} from '../parse-zip/local-file-header';\nimport {searchFromTheEnd} from '../parse-zip/search-from-the-end';\nimport {HashElement, SLPKArchive, compareHashes} from './slpk-archieve';\n\n/**\n * Creates slpk file handler from raw file\n * @param fileProvider raw file data\n * @param cb is called with information message during parsing\n * @returns slpk file handler\n */\nexport const parseSLPK = async (\n fileProvider: FileProvider,\n cb?: (msg: string) => void\n): Promise<SLPKArchive> => {\n const hashCDOffset = await searchFromTheEnd(fileProvider, cdHeaderSignature);\n\n const cdFileHeader = await parseZipCDFileHeader(hashCDOffset, fileProvider);\n\n let hashData: HashElement[];\n if (cdFileHeader?.fileName !== '@specialIndexFileHASH128@') {\n cb?.('SLPK doesnt contain hash file');\n hashData = await generateHashInfo(fileProvider);\n cb?.('hash info has been composed according to central directory records');\n } else {\n cb?.('SLPK contains hash file');\n const localFileHeader = await parseZipLocalFileHeader(\n cdFileHeader.localHeaderOffset,\n fileProvider\n );\n if (!localFileHeader) {\n throw new Error('corrupted SLPK');\n }\n\n const fileDataOffset = localFileHeader.fileDataOffset;\n const hashFile = await fileProvider.slice(\n fileDataOffset,\n fileDataOffset + localFileHeader.compressedSize\n );\n\n hashData = parseHashFile(hashFile);\n }\n\n return new SLPKArchive(fileProvider, hashData);\n};\n\n/**\n * generates hash info from central directory\n * @param fileProvider - provider of the archive\n * @returns ready to use hash info\n */\nconst generateHashInfo = async (fileProvider: FileProvider): Promise<HashElement[]> => {\n const {cdStartOffset} = await parseEoCDRecord(fileProvider);\n let cdHeader = await parseZipCDFileHeader(cdStartOffset, fileProvider);\n const hashInfo: HashElement[] = [];\n while (cdHeader) {\n hashInfo.push({\n hash: Buffer.from(md5(cdHeader.fileName.split('\\\\').join('/').toLocaleLowerCase()), 'hex'),\n offset: cdHeader.localHeaderOffset\n });\n cdHeader = await parseZipCDFileHeader(\n cdHeader.extraOffset + BigInt(cdHeader.extraFieldLength),\n fileProvider\n );\n }\n hashInfo.sort((a, b) => compareHashes(a.hash, b.hash));\n return hashInfo;\n};\n\n/**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param hashFile - bufer containing hash file\n * @returns Array containing file info\n */\nconst parseHashFile = (hashFile: ArrayBuffer): HashElement[] => {\n const hashFileBuffer = Buffer.from(hashFile);\n const hashArray: HashElement[] = [];\n for (let i = 0; i < hashFileBuffer.buffer.byteLength; i = i + 24) {\n const offsetBuffer = new DataView(\n hashFileBuffer.buffer.slice(\n hashFileBuffer.byteOffset + i + 16,\n hashFileBuffer.byteOffset + i + 24\n )\n );\n const offset = offsetBuffer.getBigUint64(offsetBuffer.byteOffset, true);\n hashArray.push({\n hash: Buffer.from(\n hashFileBuffer.subarray(hashFileBuffer.byteOffset + i, hashFileBuffer.byteOffset + i + 16)\n ),\n offset\n });\n }\n return hashArray;\n};\n"],"mappings":"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"}
|
|
@@ -2,6 +2,17 @@ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
|
2
2
|
import md5 from 'md5';
|
|
3
3
|
import { parseZipLocalFileHeader } from '../parse-zip/local-file-header';
|
|
4
4
|
import { GZipCompression } from '@loaders.gl/compression';
|
|
5
|
+
export const compareHashes = (hash1, hash2) => {
|
|
6
|
+
const h1 = new BigUint64Array(hash1.buffer, hash1.byteOffset, 2);
|
|
7
|
+
const h2 = new BigUint64Array(hash2.buffer, hash2.byteOffset, 2);
|
|
8
|
+
const diff = h1[0] === h2[0] ? h1[1] - h2[1] : h1[0] - h2[0];
|
|
9
|
+
if (diff < 0n) {
|
|
10
|
+
return -1;
|
|
11
|
+
} else if (diff === 0n) {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
return 1;
|
|
15
|
+
};
|
|
5
16
|
const PATH_DESCRIPTIONS = [{
|
|
6
17
|
test: /^$/,
|
|
7
18
|
extensions: ['3dSceneLayer.json.gz']
|
|
@@ -9,7 +20,7 @@ const PATH_DESCRIPTIONS = [{
|
|
|
9
20
|
test: /^nodepages\/\d+$/,
|
|
10
21
|
extensions: ['.json.gz']
|
|
11
22
|
}, {
|
|
12
|
-
test: /^nodes
|
|
23
|
+
test: /^nodes\/(\d+|root)$/,
|
|
13
24
|
extensions: ['/3dNodeIndexDocument.json.gz']
|
|
14
25
|
}, {
|
|
15
26
|
test: /^nodes\/\d+\/textures\/.+$/,
|
|
@@ -31,21 +42,24 @@ export class SLPKArchive {
|
|
|
31
42
|
constructor(slpkArchive, hashFile) {
|
|
32
43
|
_defineProperty(this, "slpkArchive", void 0);
|
|
33
44
|
_defineProperty(this, "hashArray", void 0);
|
|
45
|
+
_defineProperty(this, "findBin", hashToSearch => {
|
|
46
|
+
let lowerBorder = 0;
|
|
47
|
+
let upperBorder = this.hashArray.length;
|
|
48
|
+
while (upperBorder - lowerBorder > 1) {
|
|
49
|
+
const middle = lowerBorder + Math.floor((upperBorder - lowerBorder) / 2);
|
|
50
|
+
const value = compareHashes(this.hashArray[middle].hash, hashToSearch);
|
|
51
|
+
if (value === 0) {
|
|
52
|
+
return this.hashArray[middle];
|
|
53
|
+
} else if (value < 0) {
|
|
54
|
+
lowerBorder = middle;
|
|
55
|
+
} else {
|
|
56
|
+
upperBorder = middle;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
});
|
|
34
61
|
this.slpkArchive = slpkArchive;
|
|
35
|
-
this.hashArray =
|
|
36
|
-
}
|
|
37
|
-
parseHashFile(hashFile) {
|
|
38
|
-
const hashFileBuffer = Buffer.from(hashFile);
|
|
39
|
-
const hashArray = [];
|
|
40
|
-
for (let i = 0; i < hashFileBuffer.buffer.byteLength; i = i + 24) {
|
|
41
|
-
const offsetBuffer = new DataView(hashFileBuffer.buffer.slice(hashFileBuffer.byteOffset + i + 16, hashFileBuffer.byteOffset + i + 24));
|
|
42
|
-
const offset = offsetBuffer.getBigUint64(offsetBuffer.byteOffset, true);
|
|
43
|
-
hashArray.push({
|
|
44
|
-
hash: Buffer.from(hashFileBuffer.subarray(hashFileBuffer.byteOffset + i, hashFileBuffer.byteOffset + i + 16)),
|
|
45
|
-
offset
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
return hashArray;
|
|
62
|
+
this.hashArray = hashFile;
|
|
49
63
|
}
|
|
50
64
|
async getFile(path) {
|
|
51
65
|
let mode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'raw';
|
|
@@ -78,7 +92,10 @@ export class SLPKArchive {
|
|
|
78
92
|
throw new Error('No such file in the archieve');
|
|
79
93
|
}
|
|
80
94
|
async getDataByPath(path) {
|
|
81
|
-
|
|
95
|
+
let data = await this.getFileBytes(path.toLocaleLowerCase());
|
|
96
|
+
if (!data) {
|
|
97
|
+
data = await this.getFileBytes(path);
|
|
98
|
+
}
|
|
82
99
|
if (!data) {
|
|
83
100
|
return undefined;
|
|
84
101
|
}
|
|
@@ -91,11 +108,11 @@ export class SLPKArchive {
|
|
|
91
108
|
}
|
|
92
109
|
async getFileBytes(path) {
|
|
93
110
|
const nameHash = Buffer.from(md5(path), 'hex');
|
|
94
|
-
const fileInfo = this.
|
|
111
|
+
const fileInfo = this.findBin(nameHash);
|
|
95
112
|
if (!fileInfo) {
|
|
96
113
|
return undefined;
|
|
97
114
|
}
|
|
98
|
-
const localFileHeader = await parseZipLocalFileHeader(fileInfo
|
|
115
|
+
const localFileHeader = await parseZipLocalFileHeader(fileInfo.offset, this.slpkArchive);
|
|
99
116
|
if (!localFileHeader) {
|
|
100
117
|
return undefined;
|
|
101
118
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slpk-archieve.js","names":["md5","parseZipLocalFileHeader","GZipCompression","PATH_DESCRIPTIONS","test","extensions","SLPKArchive","constructor","slpkArchive","hashFile","_defineProperty","hashArray","parseHashFile","hashFileBuffer","Buffer","from","i","buffer","byteLength","offsetBuffer","DataView","slice","byteOffset","offset","getBigUint64","push","hash","subarray","getFile","path","mode","arguments","length","undefined","_PATH_DESCRIPTIONS$fi","find","val","data","ext","getDataByPath","concat","decompressedFile","fileWithoutCompression","getFileBytes","Error","compression","decompressedData","decompress","nameHash","fileInfo","compare","localFileHeader","compressedFile","fileDataOffset","compressedSize"],"sources":["../../../../../src/lib/parsers/parse-slpk/slpk-archieve.ts"],"sourcesContent":["import md5 from 'md5';\nimport {parseZipLocalFileHeader} from '../parse-zip/local-file-header';\nimport {GZipCompression} from '@loaders.gl/compression';\nimport {FileProvider} from '../parse-zip/file-provider';\n\n/** Element of hash array */\ntype HashElement = {\n /**\n * File name hash\n */\n hash: Buffer;\n /**\n * File offset in the archive\n */\n offset: bigint;\n};\n\n/** Description of real paths for different file types */\nconst PATH_DESCRIPTIONS: {test: RegExp; extensions: string[]}[] = [\n {\n test: /^$/,\n extensions: ['3dSceneLayer.json.gz']\n },\n {\n test: /^nodepages\\/\\d+$/,\n extensions: ['.json.gz']\n },\n {\n test: /^nodes\\/\\d+$/,\n extensions: ['/3dNodeIndexDocument.json.gz']\n },\n {\n test: /^nodes\\/\\d+\\/textures\\/.+$/,\n extensions: ['.jpg', '.png', '.bin.dds.gz', '.ktx']\n },\n {\n test: /^nodes\\/\\d+\\/geometries\\/\\d+$/,\n extensions: ['.bin.gz', '.draco.gz']\n },\n {\n test: /^nodes\\/\\d+\\/attributes\\/f_\\d+\\/\\d+$/,\n extensions: ['.bin.gz']\n },\n {\n test: /^statistics\\/f_\\d+\\/\\d+$/,\n extensions: ['.json.gz']\n },\n {\n test: /^nodes\\/\\d+\\/shared$/,\n extensions: ['/sharedResource.json.gz']\n }\n];\n\n/**\n * Class for handling information about slpk file\n */\nexport class SLPKArchive {\n slpkArchive: FileProvider;\n hashArray: {hash: Buffer; offset: bigint}[];\n constructor(slpkArchive: FileProvider, hashFile: ArrayBuffer) {\n this.slpkArchive = slpkArchive;\n this.hashArray = this.parseHashFile(hashFile);\n }\n\n /**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param hashFile - bufer containing hash file\n * @returns Array containing file info\n */\n private parseHashFile(hashFile: ArrayBuffer): HashElement[] {\n const hashFileBuffer = Buffer.from(hashFile);\n const hashArray: HashElement[] = [];\n for (let i = 0; i < hashFileBuffer.buffer.byteLength; i = i + 24) {\n const offsetBuffer = new DataView(\n hashFileBuffer.buffer.slice(\n hashFileBuffer.byteOffset + i + 16,\n hashFileBuffer.byteOffset + i + 24\n )\n );\n const offset = offsetBuffer.getBigUint64(offsetBuffer.byteOffset, true);\n hashArray.push({\n hash: Buffer.from(\n hashFileBuffer.subarray(hashFileBuffer.byteOffset + i, hashFileBuffer.byteOffset + i + 16)\n ),\n offset\n });\n }\n return hashArray;\n }\n\n /**\n * Returns file with the given path from slpk archive\n * @param path - path inside the slpk\n * @param mode - currently only raw mode supported\n * @returns buffer with ready to use file\n */\n async getFile(path: string, mode: 'http' | 'raw' = 'raw'): Promise<Buffer> {\n if (mode === 'http') {\n const extensions = PATH_DESCRIPTIONS.find((val) => val.test.test(path))?.extensions;\n if (extensions) {\n let data: ArrayBuffer | undefined;\n for (const ext of extensions) {\n data = await this.getDataByPath(`${path}${ext}`);\n if (data) {\n break;\n }\n }\n if (data) {\n return Buffer.from(data);\n }\n }\n }\n if (mode === 'raw') {\n const decompressedFile = await this.getDataByPath(`${path}.gz`);\n if (decompressedFile) {\n return Buffer.from(decompressedFile);\n }\n const fileWithoutCompression = await this.getFileBytes(path);\n if (fileWithoutCompression) {\n return Buffer.from(fileWithoutCompression);\n }\n }\n\n throw new Error('No such file in the archieve');\n }\n\n /**\n * returning uncompressed data for paths that ends with .gz and raw data for all other paths\n * @param path - path inside the archive\n * @returns buffer with the file data\n */\n private async getDataByPath(path: string): Promise<ArrayBuffer | undefined> {\n const data = await this.getFileBytes(path);\n if (!data) {\n return undefined;\n }\n if (/\\.gz$/.test(path)) {\n const compression = new GZipCompression();\n\n const decompressedData = await compression.decompress(data);\n return decompressedData;\n }\n return Buffer.from(data);\n }\n\n /**\n * Trying to get raw file data by adress\n * @param path - path inside the archive\n * @returns buffer with the raw file data\n */\n private async getFileBytes(path: string): Promise<ArrayBuffer | undefined> {\n const nameHash = Buffer.from(md5(path), 'hex');\n const fileInfo = this.hashArray.find((val) => Buffer.compare(val.hash, nameHash) === 0);\n if (!fileInfo) {\n return undefined;\n }\n\n const localFileHeader = await parseZipLocalFileHeader(fileInfo?.offset, this.slpkArchive);\n if (!localFileHeader) {\n return undefined;\n }\n\n const compressedFile = this.slpkArchive.slice(\n localFileHeader.fileDataOffset,\n localFileHeader.fileDataOffset + localFileHeader.compressedSize\n );\n\n return compressedFile;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slpk-archieve.js","names":["md5","parseZipLocalFileHeader","GZipCompression","compareHashes","hash1","hash2","h1","BigUint64Array","buffer","byteOffset","h2","diff","PATH_DESCRIPTIONS","test","extensions","SLPKArchive","constructor","slpkArchive","hashFile","_defineProperty","hashToSearch","lowerBorder","upperBorder","hashArray","length","middle","Math","floor","value","hash","undefined","getFile","path","mode","arguments","_PATH_DESCRIPTIONS$fi","find","val","data","ext","getDataByPath","concat","Buffer","from","decompressedFile","fileWithoutCompression","getFileBytes","Error","toLocaleLowerCase","compression","decompressedData","decompress","nameHash","fileInfo","findBin","localFileHeader","offset","compressedFile","slice","fileDataOffset","compressedSize"],"sources":["../../../../../src/lib/parsers/parse-slpk/slpk-archieve.ts"],"sourcesContent":["import md5 from 'md5';\nimport {parseZipLocalFileHeader} from '../parse-zip/local-file-header';\nimport {GZipCompression} from '@loaders.gl/compression';\nimport {FileProvider} from '../parse-zip/file-provider';\n\n/** Element of hash array */\nexport type HashElement = {\n /** File name hash */\n hash: Buffer;\n /** File offset in the archive */\n offset: bigint;\n};\n\n/**\n * Comparing md5 hashes according to https://github.com/Esri/i3s-spec/blob/master/docs/2.0/slpk_hashtable.pcsl.md step 5\n * @param hash1 hash to compare\n * @param hash2 hash to compare\n * @returns -1 if hash1 < hash2, 0 of hash1 === hash2, 1 if hash1 > hash2\n */\nexport const compareHashes = (hash1: Buffer, hash2: Buffer): number => {\n const h1 = new BigUint64Array(hash1.buffer, hash1.byteOffset, 2);\n const h2 = new BigUint64Array(hash2.buffer, hash2.byteOffset, 2);\n\n const diff = h1[0] === h2[0] ? h1[1] - h2[1] : h1[0] - h2[0];\n\n if (diff < 0n) {\n return -1;\n } else if (diff === 0n) {\n return 0;\n }\n return 1;\n};\n\n/** Description of real paths for different file types */\nconst PATH_DESCRIPTIONS: {test: RegExp; extensions: string[]}[] = [\n {\n test: /^$/,\n extensions: ['3dSceneLayer.json.gz']\n },\n {\n test: /^nodepages\\/\\d+$/,\n extensions: ['.json.gz']\n },\n {\n test: /^nodes\\/(\\d+|root)$/,\n extensions: ['/3dNodeIndexDocument.json.gz']\n },\n {\n test: /^nodes\\/\\d+\\/textures\\/.+$/,\n extensions: ['.jpg', '.png', '.bin.dds.gz', '.ktx']\n },\n {\n test: /^nodes\\/\\d+\\/geometries\\/\\d+$/,\n extensions: ['.bin.gz', '.draco.gz']\n },\n {\n test: /^nodes\\/\\d+\\/attributes\\/f_\\d+\\/\\d+$/,\n extensions: ['.bin.gz']\n },\n {\n test: /^statistics\\/f_\\d+\\/\\d+$/,\n extensions: ['.json.gz']\n },\n {\n test: /^nodes\\/\\d+\\/shared$/,\n extensions: ['/sharedResource.json.gz']\n }\n];\n\n/**\n * Class for handling information about slpk file\n */\nexport class SLPKArchive {\n private slpkArchive: FileProvider;\n private hashArray: HashElement[];\n constructor(slpkArchive: FileProvider, hashFile: HashElement[]) {\n this.slpkArchive = slpkArchive;\n this.hashArray = hashFile;\n }\n\n /**\n * Binary search in the hash info\n * @param hashToSearch hash that we need to find\n * @returns required hash element or undefined if not found\n */\n private findBin = (hashToSearch: Buffer): HashElement | undefined => {\n let lowerBorder = 0;\n let upperBorder = this.hashArray.length;\n\n while (upperBorder - lowerBorder > 1) {\n const middle = lowerBorder + Math.floor((upperBorder - lowerBorder) / 2);\n const value = compareHashes(this.hashArray[middle].hash, hashToSearch);\n if (value === 0) {\n return this.hashArray[middle];\n } else if (value < 0) {\n lowerBorder = middle;\n } else {\n upperBorder = middle;\n }\n }\n return undefined;\n };\n\n /**\n * Returns file with the given path from slpk archive\n * @param path - path inside the slpk\n * @param mode - currently only raw mode supported\n * @returns buffer with ready to use file\n */\n async getFile(path: string, mode: 'http' | 'raw' = 'raw'): Promise<Buffer> {\n if (mode === 'http') {\n const extensions = PATH_DESCRIPTIONS.find((val) => val.test.test(path))?.extensions;\n if (extensions) {\n let data: ArrayBuffer | undefined;\n for (const ext of extensions) {\n data = await this.getDataByPath(`${path}${ext}`);\n if (data) {\n break;\n }\n }\n if (data) {\n return Buffer.from(data);\n }\n }\n }\n if (mode === 'raw') {\n const decompressedFile = await this.getDataByPath(`${path}.gz`);\n if (decompressedFile) {\n return Buffer.from(decompressedFile);\n }\n const fileWithoutCompression = await this.getFileBytes(path);\n if (fileWithoutCompression) {\n return Buffer.from(fileWithoutCompression);\n }\n }\n\n throw new Error('No such file in the archieve');\n }\n\n /**\n * returning uncompressed data for paths that ends with .gz and raw data for all other paths\n * @param path - path inside the archive\n * @returns buffer with the file data\n */\n private async getDataByPath(path: string): Promise<ArrayBuffer | undefined> {\n // sometimes paths are not in lower case when hash file is created,\n // so first we're looking for lower case file name and then for original one\n let data = await this.getFileBytes(path.toLocaleLowerCase());\n if (!data) {\n data = await this.getFileBytes(path);\n }\n if (!data) {\n return undefined;\n }\n if (/\\.gz$/.test(path)) {\n const compression = new GZipCompression();\n\n const decompressedData = await compression.decompress(data);\n return decompressedData;\n }\n return Buffer.from(data);\n }\n\n /**\n * Trying to get raw file data by adress\n * @param path - path inside the archive\n * @returns buffer with the raw file data\n */\n private async getFileBytes(path: string): Promise<ArrayBuffer | undefined> {\n const nameHash = Buffer.from(md5(path), 'hex');\n const fileInfo = this.findBin(nameHash); // implement binary search\n if (!fileInfo) {\n return undefined;\n }\n\n const localFileHeader = await parseZipLocalFileHeader(fileInfo.offset, this.slpkArchive);\n if (!localFileHeader) {\n return undefined;\n }\n\n const compressedFile = this.slpkArchive.slice(\n localFileHeader.fileDataOffset,\n localFileHeader.fileDataOffset + localFileHeader.compressedSize\n );\n\n return compressedFile;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
const offsets = {
|
|
2
|
+
CD_COMPRESSED_SIZE_OFFSET: 20n,
|
|
3
|
+
CD_UNCOMPRESSED_SIZE_OFFSET: 24n,
|
|
4
|
+
CD_FILE_NAME_LENGTH_OFFSET: 28n,
|
|
5
|
+
CD_EXTRA_FIELD_LENGTH_OFFSET: 30n,
|
|
6
|
+
CD_LOCAL_HEADER_OFFSET_OFFSET: 42n,
|
|
7
|
+
CD_FILE_NAME_OFFSET: 46n
|
|
8
|
+
};
|
|
9
|
+
export const signature = [0x50, 0x4b, 0x01, 0x02];
|
|
1
10
|
export const parseZipCDFileHeader = async (headerOffset, buffer) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
CD_FILE_NAME_LENGTH_OFFSET: 28n,
|
|
6
|
-
CD_EXTRA_FIELD_LENGTH_OFFSET: 30n,
|
|
7
|
-
CD_LOCAL_HEADER_OFFSET_OFFSET: 42n,
|
|
8
|
-
CD_FILE_NAME_OFFSET: 46n
|
|
9
|
-
};
|
|
11
|
+
if (Buffer.from(await buffer.slice(headerOffset, headerOffset + 4n)).compare(Buffer.from(signature)) !== 0) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
10
14
|
let compressedSize = BigInt(await buffer.getUint32(headerOffset + offsets.CD_COMPRESSED_SIZE_OFFSET));
|
|
11
15
|
let uncompressedSize = BigInt(await buffer.getUint32(headerOffset + offsets.CD_UNCOMPRESSED_SIZE_OFFSET));
|
|
16
|
+
const extraFieldLength = await buffer.getUint16(headerOffset + offsets.CD_EXTRA_FIELD_LENGTH_OFFSET);
|
|
12
17
|
const fileNameLength = await buffer.getUint16(headerOffset + offsets.CD_FILE_NAME_LENGTH_OFFSET);
|
|
13
18
|
const fileName = new TextDecoder().decode(await buffer.slice(headerOffset + offsets.CD_FILE_NAME_OFFSET, headerOffset + offsets.CD_FILE_NAME_OFFSET + BigInt(fileNameLength)));
|
|
14
19
|
const extraOffset = headerOffset + offsets.CD_FILE_NAME_OFFSET + BigInt(fileNameLength);
|
|
@@ -30,6 +35,7 @@ export const parseZipCDFileHeader = async (headerOffset, buffer) => {
|
|
|
30
35
|
return {
|
|
31
36
|
compressedSize,
|
|
32
37
|
uncompressedSize,
|
|
38
|
+
extraFieldLength,
|
|
33
39
|
fileNameLength,
|
|
34
40
|
fileName,
|
|
35
41
|
extraOffset,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cd-file-header.js","names":["
|
|
1
|
+
{"version":3,"file":"cd-file-header.js","names":["offsets","CD_COMPRESSED_SIZE_OFFSET","CD_UNCOMPRESSED_SIZE_OFFSET","CD_FILE_NAME_LENGTH_OFFSET","CD_EXTRA_FIELD_LENGTH_OFFSET","CD_LOCAL_HEADER_OFFSET_OFFSET","CD_FILE_NAME_OFFSET","signature","parseZipCDFileHeader","headerOffset","buffer","Buffer","from","slice","compare","compressedSize","BigInt","getUint32","uncompressedSize","extraFieldLength","getUint16","fileNameLength","fileName","TextDecoder","decode","extraOffset","oldFormatOffset","fileDataOffset","offsetInZip64Data","getBigUint64","localHeaderOffset"],"sources":["../../../../../src/lib/parsers/parse-zip/cd-file-header.ts"],"sourcesContent":["import {FileProvider} from './file-provider';\nimport {ZipSignature} from './search-from-the-end';\n\n/**\n * zip central directory file header info\n * according to https://en.wikipedia.org/wiki/ZIP_(file_format)\n */\nexport type ZipCDFileHeader = {\n /** Compressed size */\n compressedSize: bigint;\n /** Uncompressed size */\n uncompressedSize: bigint;\n /** Extra field size */\n extraFieldLength: number;\n /** File name length */\n fileNameLength: number;\n /** File name */\n fileName: string;\n /** Extra field offset */\n extraOffset: bigint;\n /** Relative offset of local file header */\n localHeaderOffset: bigint;\n};\n\nconst offsets = {\n CD_COMPRESSED_SIZE_OFFSET: 20n,\n CD_UNCOMPRESSED_SIZE_OFFSET: 24n,\n CD_FILE_NAME_LENGTH_OFFSET: 28n,\n CD_EXTRA_FIELD_LENGTH_OFFSET: 30n,\n CD_LOCAL_HEADER_OFFSET_OFFSET: 42n,\n CD_FILE_NAME_OFFSET: 46n\n};\n\nexport const signature: ZipSignature = [0x50, 0x4b, 0x01, 0x02];\n\n/**\n * Parses central directory file header of zip file\n * @param headerOffset - offset in the archive where header starts\n * @param buffer - buffer containing whole array\n * @returns Info from the header\n */\nexport const parseZipCDFileHeader = async (\n headerOffset: bigint,\n buffer: FileProvider\n): Promise<ZipCDFileHeader | null> => {\n if (\n Buffer.from(await buffer.slice(headerOffset, headerOffset + 4n)).compare(\n Buffer.from(signature)\n ) !== 0\n ) {\n return null;\n }\n\n let compressedSize = BigInt(\n await buffer.getUint32(headerOffset + offsets.CD_COMPRESSED_SIZE_OFFSET)\n );\n\n let uncompressedSize = BigInt(\n await buffer.getUint32(headerOffset + offsets.CD_UNCOMPRESSED_SIZE_OFFSET)\n );\n\n const extraFieldLength = await buffer.getUint16(\n headerOffset + offsets.CD_EXTRA_FIELD_LENGTH_OFFSET\n );\n\n const fileNameLength = await buffer.getUint16(headerOffset + offsets.CD_FILE_NAME_LENGTH_OFFSET);\n\n const fileName = new TextDecoder().decode(\n await buffer.slice(\n headerOffset + offsets.CD_FILE_NAME_OFFSET,\n headerOffset + offsets.CD_FILE_NAME_OFFSET + BigInt(fileNameLength)\n )\n );\n\n const extraOffset = headerOffset + offsets.CD_FILE_NAME_OFFSET + BigInt(fileNameLength);\n\n const oldFormatOffset = await buffer.getUint32(\n headerOffset + offsets.CD_LOCAL_HEADER_OFFSET_OFFSET\n );\n\n let fileDataOffset = BigInt(oldFormatOffset);\n let offsetInZip64Data = 4n;\n // looking for info that might be also be in zip64 extra field\n if (uncompressedSize === BigInt(0xffffffff)) {\n uncompressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);\n offsetInZip64Data += 8n;\n }\n if (compressedSize === BigInt(0xffffffff)) {\n compressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);\n offsetInZip64Data += 8n;\n }\n if (fileDataOffset === BigInt(0xffffffff)) {\n fileDataOffset = await buffer.getBigUint64(extraOffset + offsetInZip64Data); // setting it to the one from zip64\n }\n const localHeaderOffset = fileDataOffset;\n\n return {\n compressedSize,\n uncompressedSize,\n extraFieldLength,\n fileNameLength,\n fileName,\n extraOffset,\n localHeaderOffset\n };\n};\n"],"mappings":"AAwBA,MAAMA,OAAO,GAAG;EACdC,yBAAyB,EAAE,GAAG;EAC9BC,2BAA2B,EAAE,GAAG;EAChCC,0BAA0B,EAAE,GAAG;EAC/BC,4BAA4B,EAAE,GAAG;EACjCC,6BAA6B,EAAE,GAAG;EAClCC,mBAAmB,EAAE;AACvB,CAAC;AAED,OAAO,MAAMC,SAAuB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAQ/D,OAAO,MAAMC,oBAAoB,GAAG,MAAAA,CAClCC,YAAoB,EACpBC,MAAoB,KACgB;EACpC,IACEC,MAAM,CAACC,IAAI,CAAC,MAAMF,MAAM,CAACG,KAAK,CAACJ,YAAY,EAAEA,YAAY,GAAG,EAAE,CAAC,CAAC,CAACK,OAAO,CACtEH,MAAM,CAACC,IAAI,CAACL,SAAS,CACvB,CAAC,KAAK,CAAC,EACP;IACA,OAAO,IAAI;EACb;EAEA,IAAIQ,cAAc,GAAGC,MAAM,CACzB,MAAMN,MAAM,CAACO,SAAS,CAACR,YAAY,GAAGT,OAAO,CAACC,yBAAyB,CACzE,CAAC;EAED,IAAIiB,gBAAgB,GAAGF,MAAM,CAC3B,MAAMN,MAAM,CAACO,SAAS,CAACR,YAAY,GAAGT,OAAO,CAACE,2BAA2B,CAC3E,CAAC;EAED,MAAMiB,gBAAgB,GAAG,MAAMT,MAAM,CAACU,SAAS,CAC7CX,YAAY,GAAGT,OAAO,CAACI,4BACzB,CAAC;EAED,MAAMiB,cAAc,GAAG,MAAMX,MAAM,CAACU,SAAS,CAACX,YAAY,GAAGT,OAAO,CAACG,0BAA0B,CAAC;EAEhG,MAAMmB,QAAQ,GAAG,IAAIC,WAAW,CAAC,CAAC,CAACC,MAAM,CACvC,MAAMd,MAAM,CAACG,KAAK,CAChBJ,YAAY,GAAGT,OAAO,CAACM,mBAAmB,EAC1CG,YAAY,GAAGT,OAAO,CAACM,mBAAmB,GAAGU,MAAM,CAACK,cAAc,CACpE,CACF,CAAC;EAED,MAAMI,WAAW,GAAGhB,YAAY,GAAGT,OAAO,CAACM,mBAAmB,GAAGU,MAAM,CAACK,cAAc,CAAC;EAEvF,MAAMK,eAAe,GAAG,MAAMhB,MAAM,CAACO,SAAS,CAC5CR,YAAY,GAAGT,OAAO,CAACK,6BACzB,CAAC;EAED,IAAIsB,cAAc,GAAGX,MAAM,CAACU,eAAe,CAAC;EAC5C,IAAIE,iBAAiB,GAAG,EAAE;EAE1B,IAAIV,gBAAgB,KAAKF,MAAM,CAAC,UAAU,CAAC,EAAE;IAC3CE,gBAAgB,GAAG,MAAMR,MAAM,CAACmB,YAAY,CAACJ,WAAW,GAAGG,iBAAiB,CAAC;IAC7EA,iBAAiB,IAAI,EAAE;EACzB;EACA,IAAIb,cAAc,KAAKC,MAAM,CAAC,UAAU,CAAC,EAAE;IACzCD,cAAc,GAAG,MAAML,MAAM,CAACmB,YAAY,CAACJ,WAAW,GAAGG,iBAAiB,CAAC;IAC3EA,iBAAiB,IAAI,EAAE;EACzB;EACA,IAAID,cAAc,KAAKX,MAAM,CAAC,UAAU,CAAC,EAAE;IACzCW,cAAc,GAAG,MAAMjB,MAAM,CAACmB,YAAY,CAACJ,WAAW,GAAGG,iBAAiB,CAAC;EAC7E;EACA,MAAME,iBAAiB,GAAGH,cAAc;EAExC,OAAO;IACLZ,cAAc;IACdG,gBAAgB;IAChBC,gBAAgB;IAChBE,cAAc;IACdC,QAAQ;IACRG,WAAW;IACXK;EACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { searchFromTheEnd } from './search-from-the-end';
|
|
2
|
+
const eoCDSignature = [0x50, 0x4b, 0x05, 0x06];
|
|
3
|
+
const zip64EoCDLocatorSignature = Buffer.from([0x50, 0x4b, 0x06, 0x07]);
|
|
4
|
+
const zip64EoCDSignature = Buffer.from([0x50, 0x4b, 0x06, 0x06]);
|
|
5
|
+
const offsets = {
|
|
6
|
+
CD_RECORDS_NUMBER_OFFSET: 8n,
|
|
7
|
+
CD_START_OFFSET_OFFSET: 16n,
|
|
8
|
+
ZIP64_EOCD_START_OFFSET_OFFSET: 8n,
|
|
9
|
+
ZIP64_CD_RECORDS_NUMBER_OFFSET: 24n,
|
|
10
|
+
ZIP64_CD_START_OFFSET_OFFSET: 48n
|
|
11
|
+
};
|
|
12
|
+
export const parseEoCDRecord = async fileProvider => {
|
|
13
|
+
const zipEoCDOffset = await searchFromTheEnd(fileProvider, eoCDSignature);
|
|
14
|
+
let cdRecordsNumber = BigInt(await fileProvider.getUint16(zipEoCDOffset + offsets.CD_RECORDS_NUMBER_OFFSET));
|
|
15
|
+
let cdStartOffset = BigInt(await fileProvider.getUint32(zipEoCDOffset + offsets.CD_START_OFFSET_OFFSET));
|
|
16
|
+
if (cdStartOffset === BigInt(0xffffffff) || cdRecordsNumber === BigInt(0xffffffff)) {
|
|
17
|
+
const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
|
|
18
|
+
if (Buffer.from(await fileProvider.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n)).compare(zip64EoCDLocatorSignature) !== 0) {
|
|
19
|
+
throw new Error('zip64 EoCD locator not found');
|
|
20
|
+
}
|
|
21
|
+
const zip64EoCDOffset = await fileProvider.getBigUint64(zip64EoCDLocatorOffset + offsets.ZIP64_EOCD_START_OFFSET_OFFSET);
|
|
22
|
+
if (Buffer.from(await fileProvider.slice(zip64EoCDOffset, zip64EoCDOffset + 4n)).compare(zip64EoCDSignature) !== 0) {
|
|
23
|
+
throw new Error('zip64 EoCD not found');
|
|
24
|
+
}
|
|
25
|
+
cdRecordsNumber = await fileProvider.getBigUint64(zip64EoCDOffset + offsets.ZIP64_CD_RECORDS_NUMBER_OFFSET);
|
|
26
|
+
cdStartOffset = await fileProvider.getBigUint64(zip64EoCDOffset + offsets.ZIP64_CD_START_OFFSET_OFFSET);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
cdRecordsNumber,
|
|
30
|
+
cdStartOffset
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=end-of-central-directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"end-of-central-directory.js","names":["searchFromTheEnd","eoCDSignature","zip64EoCDLocatorSignature","Buffer","from","zip64EoCDSignature","offsets","CD_RECORDS_NUMBER_OFFSET","CD_START_OFFSET_OFFSET","ZIP64_EOCD_START_OFFSET_OFFSET","ZIP64_CD_RECORDS_NUMBER_OFFSET","ZIP64_CD_START_OFFSET_OFFSET","parseEoCDRecord","fileProvider","zipEoCDOffset","cdRecordsNumber","BigInt","getUint16","cdStartOffset","getUint32","zip64EoCDLocatorOffset","slice","compare","Error","zip64EoCDOffset","getBigUint64"],"sources":["../../../../../src/lib/parsers/parse-zip/end-of-central-directory.ts"],"sourcesContent":["import {FileProvider} from './file-provider';\nimport {ZipSignature, searchFromTheEnd} from './search-from-the-end';\n\n/**\n * End of central directory info\n * according to https://en.wikipedia.org/wiki/ZIP_(file_format)\n */\nexport type ZipEoCDRecord = {\n /** Relative offset of local file header */\n cdStartOffset: bigint;\n /** Relative offset of local file header */\n cdRecordsNumber: bigint;\n};\n\nconst eoCDSignature: ZipSignature = [0x50, 0x4b, 0x05, 0x06];\nconst zip64EoCDLocatorSignature = Buffer.from([0x50, 0x4b, 0x06, 0x07]);\nconst zip64EoCDSignature = Buffer.from([0x50, 0x4b, 0x06, 0x06]);\n\nconst offsets = {\n CD_RECORDS_NUMBER_OFFSET: 8n,\n CD_START_OFFSET_OFFSET: 16n,\n\n ZIP64_EOCD_START_OFFSET_OFFSET: 8n,\n\n ZIP64_CD_RECORDS_NUMBER_OFFSET: 24n,\n ZIP64_CD_START_OFFSET_OFFSET: 48n\n};\n\n/**\n * Parses end of central directory record of zip file\n * @param fileProvider - FileProvider instance\n * @returns Info from the header\n */\nexport const parseEoCDRecord = async (fileProvider: FileProvider): Promise<ZipEoCDRecord> => {\n const zipEoCDOffset = await searchFromTheEnd(fileProvider, eoCDSignature);\n\n let cdRecordsNumber = BigInt(\n await fileProvider.getUint16(zipEoCDOffset + offsets.CD_RECORDS_NUMBER_OFFSET)\n );\n let cdStartOffset = BigInt(\n await fileProvider.getUint32(zipEoCDOffset + offsets.CD_START_OFFSET_OFFSET)\n );\n\n if (cdStartOffset === BigInt(0xffffffff) || cdRecordsNumber === BigInt(0xffffffff)) {\n const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;\n\n if (\n Buffer.from(\n await fileProvider.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n)\n ).compare(zip64EoCDLocatorSignature) !== 0\n ) {\n throw new Error('zip64 EoCD locator not found');\n }\n const zip64EoCDOffset = await fileProvider.getBigUint64(\n zip64EoCDLocatorOffset + offsets.ZIP64_EOCD_START_OFFSET_OFFSET\n );\n\n if (\n Buffer.from(await fileProvider.slice(zip64EoCDOffset, zip64EoCDOffset + 4n)).compare(\n zip64EoCDSignature\n ) !== 0\n ) {\n throw new Error('zip64 EoCD not found');\n }\n\n cdRecordsNumber = await fileProvider.getBigUint64(\n zip64EoCDOffset + offsets.ZIP64_CD_RECORDS_NUMBER_OFFSET\n );\n cdStartOffset = await fileProvider.getBigUint64(\n zip64EoCDOffset + offsets.ZIP64_CD_START_OFFSET_OFFSET\n );\n }\n\n return {\n cdRecordsNumber,\n cdStartOffset\n };\n};\n"],"mappings":"AACA,SAAsBA,gBAAgB,QAAO,uBAAuB;AAapE,MAAMC,aAA2B,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAC5D,MAAMC,yBAAyB,GAAGC,MAAM,CAACC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvE,MAAMC,kBAAkB,GAAGF,MAAM,CAACC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAEhE,MAAME,OAAO,GAAG;EACdC,wBAAwB,EAAE,EAAE;EAC5BC,sBAAsB,EAAE,GAAG;EAE3BC,8BAA8B,EAAE,EAAE;EAElCC,8BAA8B,EAAE,GAAG;EACnCC,4BAA4B,EAAE;AAChC,CAAC;AAOD,OAAO,MAAMC,eAAe,GAAG,MAAOC,YAA0B,IAA6B;EAC3F,MAAMC,aAAa,GAAG,MAAMd,gBAAgB,CAACa,YAAY,EAAEZ,aAAa,CAAC;EAEzE,IAAIc,eAAe,GAAGC,MAAM,CAC1B,MAAMH,YAAY,CAACI,SAAS,CAACH,aAAa,GAAGR,OAAO,CAACC,wBAAwB,CAC/E,CAAC;EACD,IAAIW,aAAa,GAAGF,MAAM,CACxB,MAAMH,YAAY,CAACM,SAAS,CAACL,aAAa,GAAGR,OAAO,CAACE,sBAAsB,CAC7E,CAAC;EAED,IAAIU,aAAa,KAAKF,MAAM,CAAC,UAAU,CAAC,IAAID,eAAe,KAAKC,MAAM,CAAC,UAAU,CAAC,EAAE;IAClF,MAAMI,sBAAsB,GAAGN,aAAa,GAAG,GAAG;IAElD,IACEX,MAAM,CAACC,IAAI,CACT,MAAMS,YAAY,CAACQ,KAAK,CAACD,sBAAsB,EAAEA,sBAAsB,GAAG,EAAE,CAC9E,CAAC,CAACE,OAAO,CAACpB,yBAAyB,CAAC,KAAK,CAAC,EAC1C;MACA,MAAM,IAAIqB,KAAK,CAAC,8BAA8B,CAAC;IACjD;IACA,MAAMC,eAAe,GAAG,MAAMX,YAAY,CAACY,YAAY,CACrDL,sBAAsB,GAAGd,OAAO,CAACG,8BACnC,CAAC;IAED,IACEN,MAAM,CAACC,IAAI,CAAC,MAAMS,YAAY,CAACQ,KAAK,CAACG,eAAe,EAAEA,eAAe,GAAG,EAAE,CAAC,CAAC,CAACF,OAAO,CAClFjB,kBACF,CAAC,KAAK,CAAC,EACP;MACA,MAAM,IAAIkB,KAAK,CAAC,sBAAsB,CAAC;IACzC;IAEAR,eAAe,GAAG,MAAMF,YAAY,CAACY,YAAY,CAC/CD,eAAe,GAAGlB,OAAO,CAACI,8BAC5B,CAAC;IACDQ,aAAa,GAAG,MAAML,YAAY,CAACY,YAAY,CAC7CD,eAAe,GAAGlB,OAAO,CAACK,4BAC5B,CAAC;EACH;EAEA,OAAO;IACLI,eAAe;IACfG;EACF,CAAC;AACH,CAAC"}
|
|
@@ -8,7 +8,7 @@ const offsets = {
|
|
|
8
8
|
export const signature = Buffer.from([0x50, 0x4b, 0x03, 0x04]);
|
|
9
9
|
export const parseZipLocalFileHeader = async (headerOffset, buffer) => {
|
|
10
10
|
if (Buffer.from(await buffer.slice(headerOffset, headerOffset + 4n)).compare(signature) !== 0) {
|
|
11
|
-
return
|
|
11
|
+
return null;
|
|
12
12
|
}
|
|
13
13
|
const fileNameLength = await buffer.getUint16(headerOffset + offsets.FILE_NAME_LENGTH_OFFSET);
|
|
14
14
|
const fileName = new TextDecoder().decode(await buffer.slice(headerOffset + offsets.FILE_NAME_OFFSET, headerOffset + offsets.FILE_NAME_OFFSET + BigInt(fileNameLength))).split('\\').join('/');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-file-header.js","names":["offsets","COMPRESSED_SIZE_OFFSET","UNCOMPRESSED_SIZE_OFFSET","FILE_NAME_LENGTH_OFFSET","EXTRA_FIELD_LENGTH_OFFSET","FILE_NAME_OFFSET","signature","Buffer","from","parseZipLocalFileHeader","headerOffset","buffer","slice","compare","
|
|
1
|
+
{"version":3,"file":"local-file-header.js","names":["offsets","COMPRESSED_SIZE_OFFSET","UNCOMPRESSED_SIZE_OFFSET","FILE_NAME_LENGTH_OFFSET","EXTRA_FIELD_LENGTH_OFFSET","FILE_NAME_OFFSET","signature","Buffer","from","parseZipLocalFileHeader","headerOffset","buffer","slice","compare","fileNameLength","getUint16","fileName","TextDecoder","decode","BigInt","split","join","extraFieldLength","fileDataOffset","compressedSize","getUint32","uncompressedSize","extraOffset","offsetInZip64Data","getBigUint64"],"sources":["../../../../../src/lib/parsers/parse-zip/local-file-header.ts"],"sourcesContent":["import {FileProvider} from './file-provider';\n\n/**\n * zip local file header info\n * according to https://en.wikipedia.org/wiki/ZIP_(file_format)\n */\nexport type ZipLocalFileHeader = {\n /** File name length */\n fileNameLength: number;\n /** File name */\n fileName: string;\n /** Extra field length */\n extraFieldLength: number;\n /** Offset of the file data */\n fileDataOffset: bigint;\n /** Compressed size */\n compressedSize: bigint;\n};\n\nconst offsets = {\n COMPRESSED_SIZE_OFFSET: 18n,\n UNCOMPRESSED_SIZE_OFFSET: 22n,\n FILE_NAME_LENGTH_OFFSET: 26n,\n EXTRA_FIELD_LENGTH_OFFSET: 28n,\n FILE_NAME_OFFSET: 30n\n};\n\nexport const signature = Buffer.from([0x50, 0x4b, 0x03, 0x04]);\n\n/**\n * Parses local file header of zip file\n * @param headerOffset - offset in the archive where header starts\n * @param buffer - buffer containing whole array\n * @returns Info from the header\n */\nexport const parseZipLocalFileHeader = async (\n headerOffset: bigint,\n buffer: FileProvider\n): Promise<ZipLocalFileHeader | null> => {\n if (Buffer.from(await buffer.slice(headerOffset, headerOffset + 4n)).compare(signature) !== 0) {\n return null;\n }\n\n const fileNameLength = await buffer.getUint16(headerOffset + offsets.FILE_NAME_LENGTH_OFFSET);\n\n const fileName = new TextDecoder()\n .decode(\n await buffer.slice(\n headerOffset + offsets.FILE_NAME_OFFSET,\n headerOffset + offsets.FILE_NAME_OFFSET + BigInt(fileNameLength)\n )\n )\n .split('\\\\')\n .join('/');\n const extraFieldLength = await buffer.getUint16(headerOffset + offsets.EXTRA_FIELD_LENGTH_OFFSET);\n\n let fileDataOffset =\n headerOffset + offsets.FILE_NAME_OFFSET + BigInt(fileNameLength + extraFieldLength);\n\n let compressedSize = BigInt(\n await buffer.getUint32(headerOffset + offsets.COMPRESSED_SIZE_OFFSET)\n ); // add zip 64 logic\n\n let uncompressedSize = BigInt(\n await buffer.getUint32(headerOffset + offsets.UNCOMPRESSED_SIZE_OFFSET)\n ); // add zip 64 logic\n\n const extraOffset = headerOffset + offsets.FILE_NAME_OFFSET + BigInt(fileNameLength);\n\n let offsetInZip64Data = 4n;\n // looking for info that might be also be in zip64 extra field\n if (uncompressedSize === BigInt(0xffffffff)) {\n uncompressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);\n offsetInZip64Data += 8n;\n }\n if (compressedSize === BigInt(0xffffffff)) {\n compressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);\n offsetInZip64Data += 8n;\n }\n if (fileDataOffset === BigInt(0xffffffff)) {\n fileDataOffset = await buffer.getBigUint64(extraOffset + offsetInZip64Data); // setting it to the one from zip64\n }\n\n return {\n fileNameLength,\n fileName,\n extraFieldLength,\n fileDataOffset,\n compressedSize\n };\n};\n"],"mappings":"AAmBA,MAAMA,OAAO,GAAG;EACdC,sBAAsB,EAAE,GAAG;EAC3BC,wBAAwB,EAAE,GAAG;EAC7BC,uBAAuB,EAAE,GAAG;EAC5BC,yBAAyB,EAAE,GAAG;EAC9BC,gBAAgB,EAAE;AACpB,CAAC;AAED,OAAO,MAAMC,SAAS,GAAGC,MAAM,CAACC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAQ9D,OAAO,MAAMC,uBAAuB,GAAG,MAAAA,CACrCC,YAAoB,EACpBC,MAAoB,KACmB;EACvC,IAAIJ,MAAM,CAACC,IAAI,CAAC,MAAMG,MAAM,CAACC,KAAK,CAACF,YAAY,EAAEA,YAAY,GAAG,EAAE,CAAC,CAAC,CAACG,OAAO,CAACP,SAAS,CAAC,KAAK,CAAC,EAAE;IAC7F,OAAO,IAAI;EACb;EAEA,MAAMQ,cAAc,GAAG,MAAMH,MAAM,CAACI,SAAS,CAACL,YAAY,GAAGV,OAAO,CAACG,uBAAuB,CAAC;EAE7F,MAAMa,QAAQ,GAAG,IAAIC,WAAW,CAAC,CAAC,CAC/BC,MAAM,CACL,MAAMP,MAAM,CAACC,KAAK,CAChBF,YAAY,GAAGV,OAAO,CAACK,gBAAgB,EACvCK,YAAY,GAAGV,OAAO,CAACK,gBAAgB,GAAGc,MAAM,CAACL,cAAc,CACjE,CACF,CAAC,CACAM,KAAK,CAAC,IAAI,CAAC,CACXC,IAAI,CAAC,GAAG,CAAC;EACZ,MAAMC,gBAAgB,GAAG,MAAMX,MAAM,CAACI,SAAS,CAACL,YAAY,GAAGV,OAAO,CAACI,yBAAyB,CAAC;EAEjG,IAAImB,cAAc,GAChBb,YAAY,GAAGV,OAAO,CAACK,gBAAgB,GAAGc,MAAM,CAACL,cAAc,GAAGQ,gBAAgB,CAAC;EAErF,IAAIE,cAAc,GAAGL,MAAM,CACzB,MAAMR,MAAM,CAACc,SAAS,CAACf,YAAY,GAAGV,OAAO,CAACC,sBAAsB,CACtE,CAAC;EAED,IAAIyB,gBAAgB,GAAGP,MAAM,CAC3B,MAAMR,MAAM,CAACc,SAAS,CAACf,YAAY,GAAGV,OAAO,CAACE,wBAAwB,CACxE,CAAC;EAED,MAAMyB,WAAW,GAAGjB,YAAY,GAAGV,OAAO,CAACK,gBAAgB,GAAGc,MAAM,CAACL,cAAc,CAAC;EAEpF,IAAIc,iBAAiB,GAAG,EAAE;EAE1B,IAAIF,gBAAgB,KAAKP,MAAM,CAAC,UAAU,CAAC,EAAE;IAC3CO,gBAAgB,GAAG,MAAMf,MAAM,CAACkB,YAAY,CAACF,WAAW,GAAGC,iBAAiB,CAAC;IAC7EA,iBAAiB,IAAI,EAAE;EACzB;EACA,IAAIJ,cAAc,KAAKL,MAAM,CAAC,UAAU,CAAC,EAAE;IACzCK,cAAc,GAAG,MAAMb,MAAM,CAACkB,YAAY,CAACF,WAAW,GAAGC,iBAAiB,CAAC;IAC3EA,iBAAiB,IAAI,EAAE;EACzB;EACA,IAAIL,cAAc,KAAKJ,MAAM,CAAC,UAAU,CAAC,EAAE;IACzCI,cAAc,GAAG,MAAMZ,MAAM,CAACkB,YAAY,CAACF,WAAW,GAAGC,iBAAiB,CAAC;EAC7E;EAEA,OAAO;IACLd,cAAc;IACdE,QAAQ;IACRM,gBAAgB;IAChBC,cAAc;IACdC;EACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-from-the-end.js","names":["searchFromTheEnd","file","target","searchWindow","getUint8","length","undefined","targetOffset","i","every","val","index"],"sources":["../../../../../src/lib/parsers/parse-zip/search-from-the-end.ts"],"sourcesContent":["import {FileProvider} from 'modules/i3s/src/lib/parsers/parse-zip/file-provider';\n\n/** Description of zip signature type */\nexport type ZipSignature = [number, number, number, number];\n\n/**\n * looking for the last occurrence of the provided\n * @param file\n * @param target\n * @returns\n */\nexport const searchFromTheEnd = async (\n file: FileProvider,\n target: ZipSignature\n): Promise<bigint> => {\n const searchWindow = [\n await file.getUint8(file.length - 1n),\n await file.getUint8(file.length - 2n),\n await file.getUint8(file.length - 3n),\n undefined\n ];\n\n let targetOffset = 0n;\n\n // looking for the last record in the central directory\n for (let i = file.length - 4n; i > -1; i--) {\n searchWindow[3] = searchWindow[2];\n searchWindow[2] = searchWindow[1];\n searchWindow[1] = searchWindow[0];\n searchWindow[0] = await file.getUint8(i);\n if (searchWindow.every((val, index) => val === target[index])) {\n targetOffset = i;\n break;\n }\n }\n\n return targetOffset;\n};\n"],"mappings":"AAWA,OAAO,MAAMA,gBAAgB,GAAG,MAAAA,CAC9BC,IAAkB,EAClBC,MAAoB,KACA;EACpB,MAAMC,YAAY,GAAG,CACnB,MAAMF,IAAI,CAACG,QAAQ,CAACH,IAAI,CAACI,MAAM,GAAG,EAAE,CAAC,EACrC,MAAMJ,IAAI,CAACG,QAAQ,CAACH,IAAI,CAACI,MAAM,GAAG,EAAE,CAAC,EACrC,MAAMJ,IAAI,CAACG,QAAQ,CAACH,IAAI,CAACI,MAAM,GAAG,EAAE,CAAC,EACrCC,SAAS,CACV;EAED,IAAIC,YAAY,GAAG,EAAE;EAGrB,KAAK,IAAIC,CAAC,GAAGP,IAAI,CAACI,MAAM,GAAG,EAAE,EAAEG,CAAC,GAAG,CAAC,CAAC,EAAEA,CAAC,EAAE,EAAE;IAC1CL,YAAY,CAAC,CAAC,CAAC,GAAGA,YAAY,CAAC,CAAC,CAAC;IACjCA,YAAY,CAAC,CAAC,CAAC,GAAGA,YAAY,CAAC,CAAC,CAAC;IACjCA,YAAY,CAAC,CAAC,CAAC,GAAGA,YAAY,CAAC,CAAC,CAAC;IACjCA,YAAY,CAAC,CAAC,CAAC,GAAG,MAAMF,IAAI,CAACG,QAAQ,CAACI,CAAC,CAAC;IACxC,IAAIL,YAAY,CAACM,KAAK,CAAC,CAACC,GAAG,EAAEC,KAAK,KAAKD,GAAG,KAAKR,MAAM,CAACS,KAAK,CAAC,CAAC,EAAE;MAC7DJ,YAAY,GAAGC,CAAC;MAChB;IACF;EACF;EAEA,OAAOD,YAAY;AACrB,CAAC"}
|
package/dist/esm/types.js
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
export let DATA_TYPE = function (DATA_TYPE) {
|
|
2
|
-
DATA_TYPE["UInt8"] = "UInt8";
|
|
3
|
-
DATA_TYPE["UInt16"] = "UInt16";
|
|
4
|
-
DATA_TYPE["UInt32"] = "UInt32";
|
|
5
|
-
DATA_TYPE["UInt64"] = "UInt64";
|
|
6
|
-
DATA_TYPE["Int16"] = "Int16";
|
|
7
|
-
DATA_TYPE["Int32"] = "Int32";
|
|
8
|
-
DATA_TYPE["Int64"] = "Int64";
|
|
9
|
-
DATA_TYPE["Float32"] = "Float32";
|
|
10
|
-
DATA_TYPE["Float64"] = "Float64";
|
|
11
|
-
return DATA_TYPE;
|
|
12
|
-
}({});
|
|
13
1
|
export let HeaderAttributeProperty = function (HeaderAttributeProperty) {
|
|
14
2
|
HeaderAttributeProperty["vertexCount"] = "vertexCount";
|
|
15
3
|
HeaderAttributeProperty["featureCount"] = "featureCount";
|