@ifc-lite/parser 4.3.2 → 5.0.0
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/attribute-helpers.d.ts +38 -4
- package/dist/attribute-helpers.d.ts.map +1 -1
- package/dist/attribute-helpers.js +71 -4
- package/dist/attribute-helpers.js.map +1 -1
- package/dist/columnar-parser-attributes.d.ts.map +1 -1
- package/dist/columnar-parser-attributes.js +35 -5
- package/dist/columnar-parser-attributes.js.map +1 -1
- package/dist/columnar-parser-indexes.d.ts.map +1 -1
- package/dist/columnar-parser-indexes.js +14 -2
- package/dist/columnar-parser-indexes.js.map +1 -1
- package/dist/columnar-parser-relationships.d.ts.map +1 -1
- package/dist/columnar-parser-relationships.js +6 -1
- package/dist/columnar-parser-relationships.js.map +1 -1
- package/dist/columnar-parser.d.ts +3 -1
- package/dist/columnar-parser.d.ts.map +1 -1
- package/dist/columnar-parser.js +16 -25
- package/dist/columnar-parser.js.map +1 -1
- package/dist/compact-entity-index-transport.d.ts +23 -0
- package/dist/compact-entity-index-transport.d.ts.map +1 -0
- package/dist/compact-entity-index-transport.js +28 -0
- package/dist/compact-entity-index-transport.js.map +1 -0
- package/dist/compact-entity-index.d.ts +0 -10
- package/dist/compact-entity-index.d.ts.map +1 -1
- package/dist/compact-entity-index.js +31 -24
- package/dist/compact-entity-index.js.map +1 -1
- package/dist/data-store-transport.d.ts +2 -12
- package/dist/data-store-transport.d.ts.map +1 -1
- package/dist/data-store-transport.js +7 -20
- package/dist/data-store-transport.js.map +1 -1
- package/dist/entity-extractor.d.ts.map +1 -1
- package/dist/entity-extractor.js +101 -6
- package/dist/entity-extractor.js.map +1 -1
- package/dist/entity-refs-from-index.d.ts.map +1 -1
- package/dist/entity-refs-from-index.js +12 -2
- package/dist/entity-refs-from-index.js.map +1 -1
- package/dist/entity-scanner.d.ts +63 -0
- package/dist/entity-scanner.d.ts.map +1 -1
- package/dist/entity-scanner.js +79 -2
- package/dist/entity-scanner.js.map +1 -1
- package/dist/express-id.d.ts +47 -0
- package/dist/express-id.d.ts.map +1 -0
- package/dist/express-id.js +57 -0
- package/dist/express-id.js.map +1 -0
- package/dist/generated/entities.d.ts +1 -1
- package/dist/generated/entities.d.ts.map +1 -1
- package/dist/generated/schema-registry.js +146 -146
- package/dist/generated/schema-registry.js.map +1 -1
- package/dist/georef-epset.d.ts +25 -0
- package/dist/georef-epset.d.ts.map +1 -0
- package/dist/georef-epset.js +214 -0
- package/dist/georef-epset.js.map +1 -0
- package/dist/georef-extractor.d.ts.map +1 -1
- package/dist/georef-extractor.js +38 -175
- package/dist/georef-extractor.js.map +1 -1
- package/dist/georef-map-conversion.d.ts +29 -0
- package/dist/georef-map-conversion.d.ts.map +1 -0
- package/dist/georef-map-conversion.js +75 -0
- package/dist/georef-map-conversion.js.map +1 -0
- package/dist/ifc-schema.d.ts +4 -2
- package/dist/ifc-schema.d.ts.map +1 -1
- package/dist/ifc-schema.js +15 -5
- package/dist/ifc-schema.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/material-extractor.d.ts +2 -17
- package/dist/material-extractor.d.ts.map +1 -1
- package/dist/material-extractor.js +12 -37
- package/dist/material-extractor.js.map +1 -1
- package/dist/material-layer-reader.d.ts +45 -0
- package/dist/material-layer-reader.d.ts.map +1 -0
- package/dist/material-layer-reader.js +63 -0
- package/dist/material-layer-reader.js.map +1 -0
- package/dist/material-resolver.d.ts.map +1 -1
- package/dist/material-resolver.js +14 -14
- package/dist/material-resolver.js.map +1 -1
- package/dist/measure-unit-scale.d.ts +41 -0
- package/dist/measure-unit-scale.d.ts.map +1 -0
- package/dist/measure-unit-scale.js +53 -0
- package/dist/measure-unit-scale.js.map +1 -0
- package/dist/on-demand-extractors.d.ts +3 -19
- package/dist/on-demand-extractors.d.ts.map +1 -1
- package/dist/on-demand-extractors.js +54 -264
- package/dist/on-demand-extractors.js.map +1 -1
- package/dist/owning-project.d.ts +54 -0
- package/dist/owning-project.d.ts.map +1 -0
- package/dist/owning-project.js +76 -0
- package/dist/owning-project.js.map +1 -0
- package/dist/parser.worker.d.ts +14 -0
- package/dist/parser.worker.d.ts.map +1 -1
- package/dist/parser.worker.js +2 -0
- package/dist/parser.worker.js.map +1 -1
- package/dist/project-units-symbols.d.ts +33 -0
- package/dist/project-units-symbols.d.ts.map +1 -0
- package/dist/project-units-symbols.js +265 -0
- package/dist/project-units-symbols.js.map +1 -0
- package/dist/project-units.d.ts +11 -19
- package/dist/project-units.d.ts.map +1 -1
- package/dist/project-units.js +9 -267
- package/dist/project-units.js.map +1 -1
- package/dist/property-set-merge.d.ts +65 -8
- package/dist/property-set-merge.d.ts.map +1 -1
- package/dist/property-set-merge.js +130 -29
- package/dist/property-set-merge.js.map +1 -1
- package/dist/property-value-parser.d.ts +55 -0
- package/dist/property-value-parser.d.ts.map +1 -0
- package/dist/property-value-parser.js +277 -0
- package/dist/property-value-parser.js.map +1 -0
- package/dist/quantity-collect.d.ts +42 -3
- package/dist/quantity-collect.d.ts.map +1 -1
- package/dist/quantity-collect.js +114 -7
- package/dist/quantity-collect.js.map +1 -1
- package/dist/query-backend-maps.d.ts +5 -8
- package/dist/query-backend-maps.d.ts.map +1 -1
- package/dist/query-backend-maps.js +155 -15
- package/dist/query-backend-maps.js.map +1 -1
- package/dist/relationship-extractor.d.ts.map +1 -1
- package/dist/relationship-extractor.js +18 -0
- package/dist/relationship-extractor.js.map +1 -1
- package/dist/scan-entities-balanced.d.ts +38 -0
- package/dist/scan-entities-balanced.d.ts.map +1 -0
- package/dist/scan-entities-balanced.js +258 -0
- package/dist/scan-entities-balanced.js.map +1 -0
- package/dist/scan-worker-inline.d.ts +17 -11
- package/dist/scan-worker-inline.d.ts.map +1 -1
- package/dist/scan-worker-inline.js +9 -235
- package/dist/scan-worker-inline.js.map +1 -1
- package/dist/scan-worker-source.d.ts +9 -0
- package/dist/scan-worker-source.d.ts.map +1 -0
- package/dist/scan-worker-source.js +383 -0
- package/dist/scan-worker-source.js.map +1 -0
- package/dist/spatial-hierarchy-builder.js +3 -3
- package/dist/spatial-hierarchy-builder.js.map +1 -1
- package/dist/step-lexing.d.ts +2 -0
- package/dist/step-lexing.d.ts.map +1 -1
- package/dist/step-lexing.js +116 -18
- package/dist/step-lexing.js.map +1 -1
- package/dist/step-trivia.d.ts +60 -0
- package/dist/step-trivia.d.ts.map +1 -0
- package/dist/step-trivia.js +63 -0
- package/dist/step-trivia.js.map +1 -0
- package/dist/tokenizer.d.ts +20 -21
- package/dist/tokenizer.d.ts.map +1 -1
- package/dist/tokenizer.js +164 -203
- package/dist/tokenizer.js.map +1 -1
- package/dist/unit-extractor.d.ts +43 -1
- package/dist/unit-extractor.d.ts.map +1 -1
- package/dist/unit-extractor.js +63 -4
- package/dist/unit-extractor.js.map +1 -1
- package/dist/worker-parser.d.ts +11 -1
- package/dist/worker-parser.d.ts.map +1 -1
- package/dist/worker-parser.js +16 -2
- package/dist/worker-parser.js.map +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* The balanced-parenthesis entity scan: closes a record on the ')' that
|
|
6
|
+
* balances its argument list, rather than on the terminating ';'.
|
|
7
|
+
*
|
|
8
|
+
* Split out of `tokenizer.ts`, which holds the fast semicolon scan
|
|
9
|
+
* (`StepTokenizer.scanEntitiesFast`). The two share nothing but the
|
|
10
|
+
* `step-lexing` helpers -- the cursor helpers below (`readExpressId`,
|
|
11
|
+
* `readTypeName`, `skipTrivia`) exist only for this scan, because the fast one
|
|
12
|
+
* inlines its equivalents for speed. `StepTokenizer.scanEntities` is the
|
|
13
|
+
* public entry point and delegates here.
|
|
14
|
+
*/
|
|
15
|
+
import { safeUtf8Decode } from '@ifc-lite/data';
|
|
16
|
+
import { isIndexableExpressId } from './express-id.js';
|
|
17
|
+
import { countNewlines, findEntityLength, opensLiteralOrComment, skipLexical, skipTrivia, } from './step-lexing.js';
|
|
18
|
+
/**
|
|
19
|
+
* One balanced-parenthesis scan over one buffer.
|
|
20
|
+
*
|
|
21
|
+
* The cursor and the refusal count are bound to the scan rather than kept on
|
|
22
|
+
* `StepTokenizer`, so a second scan cannot read the first one's leftovers.
|
|
23
|
+
*/
|
|
24
|
+
export class BalancedEntityScan {
|
|
25
|
+
buffer;
|
|
26
|
+
position = 0;
|
|
27
|
+
lineNumber = 1;
|
|
28
|
+
oversizedIds = 0;
|
|
29
|
+
malformed = 0;
|
|
30
|
+
constructor(buffer) {
|
|
31
|
+
this.buffer = buffer;
|
|
32
|
+
}
|
|
33
|
+
/** Records this scan refused for an out-of-contract express id (#3395). */
|
|
34
|
+
get oversizedIdCount() {
|
|
35
|
+
return this.oversizedIds;
|
|
36
|
+
}
|
|
37
|
+
/** Mirrors `StepTokenizer.malformedRecordCount`'s contract: 0 or 1, set by
|
|
38
|
+
* the single post-loop check at the end of `run()`. */
|
|
39
|
+
get malformedRecordCount() {
|
|
40
|
+
return this.malformed;
|
|
41
|
+
}
|
|
42
|
+
/** Every entity declaration (`#EXPRESS_ID = TYPE(...)`) in the buffer. */
|
|
43
|
+
*run() {
|
|
44
|
+
this.position = 0;
|
|
45
|
+
this.lineNumber = 1;
|
|
46
|
+
this.oversizedIds = 0;
|
|
47
|
+
this.malformed = 0;
|
|
48
|
+
// Set on the way to the single post-loop check below: `stopped` for an
|
|
49
|
+
// unclosed string or comment that ran the scan to end of buffer with
|
|
50
|
+
// nothing left to find, `declOpen` while a `#id=TYPE(` header is
|
|
51
|
+
// incomplete. `declOpen` stays armed ONLY when the reason for abandoning
|
|
52
|
+
// is running out of buffer; a mismatch with buffer still left clears it,
|
|
53
|
+
// because the scan resumes byte-by-byte from wherever it gave up, and a
|
|
54
|
+
// `#ref` token inside the abandoned record's own argument list reads as
|
|
55
|
+
// a fresh, equally incomplete attempt that must not report "cut off"
|
|
56
|
+
// just because nothing later happens to clear it.
|
|
57
|
+
let stopped = false;
|
|
58
|
+
let declOpen = false;
|
|
59
|
+
while (this.position < this.buffer.length) {
|
|
60
|
+
// Look for '#' character (entity ID marker)
|
|
61
|
+
if (this.buffer[this.position] === 0x23) { // '#'
|
|
62
|
+
const startOffset = this.position;
|
|
63
|
+
const startLine = this.lineNumber;
|
|
64
|
+
// Read express ID
|
|
65
|
+
const expressId = this.readExpressId();
|
|
66
|
+
if (expressId === null) {
|
|
67
|
+
this.position++;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
declOpen = true;
|
|
71
|
+
// Whitespace AND comments: 10303-21 allows a comment wherever
|
|
72
|
+
// whitespace is allowed, so `#1 /* was #7 */ =` is a declaration.
|
|
73
|
+
if (this.skipTrivia()) {
|
|
74
|
+
stopped = true;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
// Check for '=' (assignment). Not a truncation when buffer is still
|
|
78
|
+
// left to scan -- clear declOpen so a reference token inside a LATER
|
|
79
|
+
// abandoned record's argument list (walked byte-by-byte once this
|
|
80
|
+
// one is given up on) cannot leave it stuck armed with nothing left
|
|
81
|
+
// to clear it.
|
|
82
|
+
if (this.position >= this.buffer.length) {
|
|
83
|
+
this.position++;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (this.buffer[this.position] !== 0x3D) {
|
|
87
|
+
declOpen = false;
|
|
88
|
+
this.position++;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
this.position++; // Skip '='
|
|
92
|
+
if (this.skipTrivia()) {
|
|
93
|
+
stopped = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
// Read type name. `readTypeName` returns null both on EOF and on a
|
|
97
|
+
// bad start byte, and leaves `position` untouched either way, so
|
|
98
|
+
// check `position` here to tell the two apart the same way the '='
|
|
99
|
+
// and '(' checks do.
|
|
100
|
+
const type = this.readTypeName();
|
|
101
|
+
if (!type) {
|
|
102
|
+
if (this.position < this.buffer.length)
|
|
103
|
+
declOpen = false;
|
|
104
|
+
this.position++;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (this.skipTrivia()) {
|
|
108
|
+
stopped = true;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
// Check for '(' (start of parameters). Same EOF-vs-mismatch split.
|
|
112
|
+
if (this.position >= this.buffer.length) {
|
|
113
|
+
this.position++;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (this.buffer[this.position] !== 0x28) {
|
|
117
|
+
declOpen = false;
|
|
118
|
+
this.position++;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
declOpen = false; // header complete: '(' found
|
|
122
|
+
// Find matching closing parenthesis to get full entity length
|
|
123
|
+
const entityLength = findEntityLength(this.buffer, this.position, startOffset);
|
|
124
|
+
if (entityLength > 0) {
|
|
125
|
+
// Step past the whole record, as Rust's next_entity does. Leaving
|
|
126
|
+
// `position` at the '(' made this loop re-walk the body, which was
|
|
127
|
+
// harmless only while it ignored quotes and comments.
|
|
128
|
+
//
|
|
129
|
+
// Count from `position`, not from `startOffset`: `position` is on the
|
|
130
|
+
// '(' here, and every newline before it was already counted by the
|
|
131
|
+
// three skipTrivia calls above. Counting the whole record instead
|
|
132
|
+
// double-counts a newline written between `#1=` and its type name,
|
|
133
|
+
// which is ordinary whitespace and legal.
|
|
134
|
+
this.lineNumber += countNewlines(this.buffer, this.position, startOffset + entityLength);
|
|
135
|
+
this.position = startOffset + entityLength;
|
|
136
|
+
yield {
|
|
137
|
+
expressId,
|
|
138
|
+
type,
|
|
139
|
+
offset: startOffset,
|
|
140
|
+
length: entityLength,
|
|
141
|
+
line: startLine,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// 0 means findEntityLength ran off the end of the buffer without
|
|
146
|
+
// ever balancing the '(' -- an unterminated literal or comment
|
|
147
|
+
// inside the argument list, or no closing ')' at all. Its own loop
|
|
148
|
+
// has no other exit, so this is always the EOF case, never a
|
|
149
|
+
// mid-file syntax choice to resume past.
|
|
150
|
+
stopped = true;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (this.buffer[this.position] === 0x0A) {
|
|
155
|
+
// Newline
|
|
156
|
+
this.lineNumber++;
|
|
157
|
+
this.position++;
|
|
158
|
+
}
|
|
159
|
+
else if (opensLiteralOrComment(this.buffer, this.position, this.buffer.length)) {
|
|
160
|
+
// A commented-out record satisfies every check above, so a comment has
|
|
161
|
+
// to be skipped as a region; a literal has to be skipped so its
|
|
162
|
+
// contents cannot look like one. See step-lexing.
|
|
163
|
+
const skip = skipLexical(this.buffer, this.position, this.buffer.length);
|
|
164
|
+
this.lineNumber += skip.lines;
|
|
165
|
+
this.position = skip.next;
|
|
166
|
+
if (skip.stop) {
|
|
167
|
+
stopped = true;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
this.position++;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ONE post-loop check, not an increment at every exit site above: the
|
|
176
|
+
// scan stopped early if it hit an explicit "no terminator" boundary, or
|
|
177
|
+
// the last `#id=TYPE(` header was cut short before its '(' was found.
|
|
178
|
+
// Always 0 or 1 -- the scan stops at the first one, so there is nothing
|
|
179
|
+
// to accumulate past that.
|
|
180
|
+
if (stopped || declOpen)
|
|
181
|
+
this.malformed = 1;
|
|
182
|
+
}
|
|
183
|
+
readExpressId() {
|
|
184
|
+
let id = 0;
|
|
185
|
+
let digits = 0;
|
|
186
|
+
let pos = this.position + 1; // Skip '#'
|
|
187
|
+
while (pos < this.buffer.length) {
|
|
188
|
+
const char = this.buffer[pos];
|
|
189
|
+
if (char >= 0x30 && char <= 0x39) { // '0'-'9'
|
|
190
|
+
id = id * 10 + (char - 0x30);
|
|
191
|
+
digits++;
|
|
192
|
+
pos++;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (digits === 0)
|
|
199
|
+
return null;
|
|
200
|
+
// Same storage contract as scanEntitiesFast; see express-id.ts (#3395).
|
|
201
|
+
// And the same rule about WHICH refusals count: only a declaration,
|
|
202
|
+
// `#<trivia>=`. This scan resumes one byte into a refused record and
|
|
203
|
+
// walks its argument list, so an oversized `#ref` in there reaches this
|
|
204
|
+
// method too. Look ahead rather than consume — `position` must stay where
|
|
205
|
+
// the caller's recovery expects it.
|
|
206
|
+
if (!isIndexableExpressId(id)) {
|
|
207
|
+
// Trivia, not just whitespace, so this probe recognises exactly the
|
|
208
|
+
// declarations the accept path above does. Skipping only whitespace here
|
|
209
|
+
// would let `#4294967297 /* n */ =` be dropped without being counted.
|
|
210
|
+
const probe = skipTrivia(this.buffer, pos, this.buffer.length).next;
|
|
211
|
+
if (probe < this.buffer.length && this.buffer[probe] === 0x3D)
|
|
212
|
+
this.oversizedIds++;
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
this.position = pos;
|
|
216
|
+
return id;
|
|
217
|
+
}
|
|
218
|
+
readTypeName() {
|
|
219
|
+
const start = this.position;
|
|
220
|
+
let end = start;
|
|
221
|
+
// Type names start with uppercase letter
|
|
222
|
+
if (this.position >= this.buffer.length || this.buffer[this.position] < 0x41 || this.buffer[this.position] > 0x5A) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
while (end < this.buffer.length) {
|
|
226
|
+
const char = this.buffer[end];
|
|
227
|
+
// Allow letters, numbers, and underscore
|
|
228
|
+
if ((char >= 0x41 && char <= 0x5A) || // A-Z
|
|
229
|
+
(char >= 0x61 && char <= 0x7A) || // a-z
|
|
230
|
+
(char >= 0x30 && char <= 0x39) || // 0-9
|
|
231
|
+
char === 0x5F // _
|
|
232
|
+
) {
|
|
233
|
+
end++;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (end === start)
|
|
240
|
+
return null;
|
|
241
|
+
const typeName = safeUtf8Decode(this.buffer, start, end);
|
|
242
|
+
this.position = end;
|
|
243
|
+
return typeName;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Advance past whitespace and comments (see `skipTrivia` in step-lexing).
|
|
247
|
+
* Returns true when the comment it was in never closed, so the caller's
|
|
248
|
+
* single post-loop check can count it instead of reading a false '0' from
|
|
249
|
+
* a scan that actually ran out of buffer mid-header.
|
|
250
|
+
*/
|
|
251
|
+
skipTrivia() {
|
|
252
|
+
const skip = skipTrivia(this.buffer, this.position, this.buffer.length);
|
|
253
|
+
this.lineNumber += skip.lines;
|
|
254
|
+
this.position = skip.next;
|
|
255
|
+
return skip.stop;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=scan-entities-balanced.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-entities-balanced.js","sourceRoot":"","sources":["../src/scan-entities-balanced.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Inline Web Worker for IFC entity scanning.
|
|
3
3
|
*
|
|
4
4
|
* Moves the 7-8s entity scanning off the main thread so geometry streaming
|
|
5
|
-
* and UI remain responsive. The scanning logic is embedded as a string
|
|
6
|
-
* avoid bundler/import issues with Web Workers.
|
|
5
|
+
* and UI remain responsive. The scanning logic is embedded as a string (see
|
|
6
|
+
* `scan-worker-source.ts`) to avoid bundler/import issues with Web Workers.
|
|
7
7
|
*/
|
|
8
|
+
import { WORKER_CODE } from './scan-worker-source.js';
|
|
8
9
|
export interface EntityRefWorkerResult {
|
|
9
10
|
expressId: number;
|
|
10
11
|
type: string;
|
|
@@ -12,18 +13,23 @@ export interface EntityRefWorkerResult {
|
|
|
12
13
|
byteLength: number;
|
|
13
14
|
lineNumber: number;
|
|
14
15
|
}
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
/** What one worker scan produced: the records it accepted, and how many it
|
|
17
|
+
* refused for an out-of-contract express id (#3395). The second half is not
|
|
18
|
+
* decoration — a guard that acts without reporting turns a corrupted index
|
|
19
|
+
* into a silently short one, which reads exactly like success. */
|
|
20
|
+
export interface EntityScanWorkerResult {
|
|
21
|
+
refs: EntityRefWorkerResult[];
|
|
22
|
+
oversizedIdCount: number;
|
|
23
|
+
/** See {@link StepTokenizer.malformedRecordCount} in tokenizer.ts — same
|
|
24
|
+
* condition, same recovery, counted by this worker's own copy of the
|
|
25
|
+
* scan loop. */
|
|
26
|
+
malformedRecordCount: number;
|
|
27
|
+
}
|
|
28
|
+
export { WORKER_CODE };
|
|
23
29
|
/**
|
|
24
30
|
* Scan IFC entities in a Web Worker (non-blocking).
|
|
25
31
|
* Sends a structured clone of the buffer to the worker (browser handles copy).
|
|
26
32
|
* Caller keeps the original buffer intact for columnar parsing.
|
|
27
33
|
*/
|
|
28
|
-
export declare function scanEntitiesInWorker(buffer: ArrayBuffer | SharedArrayBuffer): Promise<
|
|
34
|
+
export declare function scanEntitiesInWorker(buffer: ArrayBuffer | SharedArrayBuffer): Promise<EntityScanWorkerResult>;
|
|
29
35
|
//# sourceMappingURL=scan-worker-inline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan-worker-inline.d.ts","sourceRoot":"","sources":["../src/scan-worker-inline.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED
|
|
1
|
+
{"version":3,"file":"scan-worker-inline.d.ts","sourceRoot":"","sources":["../src/scan-worker-inline.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;mEAGmE;AACnE,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,qBAAqB,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB;;qBAEiB;IACjB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,OAAO,EAAE,WAAW,EAAE,CAAC;AAYvB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GACtC,OAAO,CAAC,sBAAsB,CAAC,CAsDjC"}
|
|
@@ -2,240 +2,14 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Inline Web Worker for IFC entity scanning.
|
|
6
|
+
*
|
|
7
|
+
* Moves the 7-8s entity scanning off the main thread so geometry streaming
|
|
8
|
+
* and UI remain responsive. The scanning logic is embedded as a string (see
|
|
9
|
+
* `scan-worker-source.ts`) to avoid bundler/import issues with Web Workers.
|
|
8
10
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const WORKER_CODE = `
|
|
12
|
-
'use strict';
|
|
13
|
-
self.onmessage = function(e) {
|
|
14
|
-
var buf = new Uint8Array(e.data);
|
|
15
|
-
var len = buf.length;
|
|
16
|
-
var pos = 0;
|
|
17
|
-
var line = 1;
|
|
18
|
-
|
|
19
|
-
// Pre-allocate result array (estimate ~13,500 entities per MB)
|
|
20
|
-
var estimatedCount = Math.max((len / 1024 / 1024) * 13500, 1000) | 0;
|
|
21
|
-
// Pack results into typed arrays for fast transfer
|
|
22
|
-
var ids = new Uint32Array(estimatedCount);
|
|
23
|
-
var offsets = new Uint32Array(estimatedCount);
|
|
24
|
-
var lengths = new Uint32Array(estimatedCount);
|
|
25
|
-
var lines = new Uint32Array(estimatedCount);
|
|
26
|
-
// Type names stored separately (strings)
|
|
27
|
-
var types = new Array(estimatedCount);
|
|
28
|
-
var count = 0;
|
|
29
|
-
|
|
30
|
-
// Type name cache (IFC files have ~776 unique types across millions of entities)
|
|
31
|
-
var typeCache = new Map();
|
|
32
|
-
|
|
33
|
-
function growArrays() {
|
|
34
|
-
var newSize = (count * 2) | 0;
|
|
35
|
-
var newIds = new Uint32Array(newSize);
|
|
36
|
-
newIds.set(ids);
|
|
37
|
-
ids = newIds;
|
|
38
|
-
var newOffsets = new Uint32Array(newSize);
|
|
39
|
-
newOffsets.set(offsets);
|
|
40
|
-
offsets = newOffsets;
|
|
41
|
-
var newLengths = new Uint32Array(newSize);
|
|
42
|
-
newLengths.set(lengths);
|
|
43
|
-
lengths = newLengths;
|
|
44
|
-
var newLines = new Uint32Array(newSize);
|
|
45
|
-
newLines.set(lines);
|
|
46
|
-
lines = newLines;
|
|
47
|
-
types.length = newSize;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
while (pos < len) {
|
|
51
|
-
var ch = buf[pos];
|
|
52
|
-
|
|
53
|
-
if (ch === 0x23) { // '#'
|
|
54
|
-
var startOffset = pos;
|
|
55
|
-
var startLine = line;
|
|
56
|
-
pos++;
|
|
57
|
-
|
|
58
|
-
// Read express ID
|
|
59
|
-
var expressId = 0;
|
|
60
|
-
var hasDigits = false;
|
|
61
|
-
while (pos < len) {
|
|
62
|
-
var c = buf[pos];
|
|
63
|
-
if (c >= 0x30 && c <= 0x39) {
|
|
64
|
-
expressId = expressId * 10 + (c - 0x30);
|
|
65
|
-
hasDigits = true;
|
|
66
|
-
pos++;
|
|
67
|
-
} else {
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (!hasDigits) continue;
|
|
72
|
-
|
|
73
|
-
// Skip whitespace
|
|
74
|
-
while (pos < len) {
|
|
75
|
-
var c2 = buf[pos];
|
|
76
|
-
if (c2 === 0x20 || c2 === 0x09 || c2 === 0x0D) { pos++; }
|
|
77
|
-
else if (c2 === 0x0A) { line++; pos++; }
|
|
78
|
-
else break;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Check for '='
|
|
82
|
-
if (pos >= len || buf[pos] !== 0x3D) continue;
|
|
83
|
-
pos++;
|
|
84
|
-
|
|
85
|
-
// Skip whitespace
|
|
86
|
-
while (pos < len) {
|
|
87
|
-
var c3 = buf[pos];
|
|
88
|
-
if (c3 === 0x20 || c3 === 0x09 || c3 === 0x0D) { pos++; }
|
|
89
|
-
else if (c3 === 0x0A) { line++; pos++; }
|
|
90
|
-
else break;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Read type name
|
|
94
|
-
var typeStart = pos;
|
|
95
|
-
if (pos >= len || buf[pos] < 0x41 || buf[pos] > 0x5A) continue;
|
|
96
|
-
|
|
97
|
-
while (pos < len) {
|
|
98
|
-
var c4 = buf[pos];
|
|
99
|
-
if ((c4 >= 0x41 && c4 <= 0x5A) || (c4 >= 0x61 && c4 <= 0x7A) ||
|
|
100
|
-
(c4 >= 0x30 && c4 <= 0x39) || c4 === 0x5F) {
|
|
101
|
-
pos++;
|
|
102
|
-
} else {
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (pos === typeStart) continue;
|
|
107
|
-
|
|
108
|
-
// Cache type name — use length + hash compound key and verify the actual
|
|
109
|
-
// bytes on a hit. Length alone can't disambiguate a 32-bit hash collision
|
|
110
|
-
// (e.g. "Aa"/"BB"), so without the byte compare a crafted/unlucky file
|
|
111
|
-
// could have one type silently misread as another. Mirrors tokenizer.ts.
|
|
112
|
-
var typeLen = pos - typeStart;
|
|
113
|
-
var typeHash = typeLen;
|
|
114
|
-
for (var i = typeStart; i < pos; i++) {
|
|
115
|
-
typeHash = (typeHash * 31 + buf[i]) | 0;
|
|
116
|
-
}
|
|
117
|
-
var cacheKey = typeLen + ':' + typeHash;
|
|
118
|
-
var typeName = typeCache.get(cacheKey);
|
|
119
|
-
var cacheHitMatches = false;
|
|
120
|
-
if (typeName !== undefined && typeName.length === typeLen) {
|
|
121
|
-
cacheHitMatches = true;
|
|
122
|
-
for (var v = 0; v < typeLen; v++) {
|
|
123
|
-
if (typeName.charCodeAt(v) !== buf[typeStart + v]) {
|
|
124
|
-
cacheHitMatches = false;
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (typeName === undefined || !cacheHitMatches) {
|
|
130
|
-
typeName = String.fromCharCode.apply(null, buf.subarray(typeStart, pos));
|
|
131
|
-
typeCache.set(cacheKey, typeName);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Skip whitespace
|
|
135
|
-
while (pos < len) {
|
|
136
|
-
var c5 = buf[pos];
|
|
137
|
-
if (c5 === 0x20 || c5 === 0x09 || c5 === 0x0D) { pos++; }
|
|
138
|
-
else if (c5 === 0x0A) { line++; pos++; }
|
|
139
|
-
else break;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Check for '('
|
|
143
|
-
if (pos >= len || buf[pos] !== 0x28) continue;
|
|
144
|
-
|
|
145
|
-
// Skip to semicolon (handling strings)
|
|
146
|
-
var inString = false;
|
|
147
|
-
while (pos < len) {
|
|
148
|
-
var c6 = buf[pos];
|
|
149
|
-
if (c6 === 0x27) { // quote
|
|
150
|
-
if (inString && pos + 1 < len && buf[pos + 1] === 0x27) {
|
|
151
|
-
pos += 2;
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
inString = !inString;
|
|
155
|
-
} else if (c6 === 0x3B && !inString) { // semicolon
|
|
156
|
-
var entityLength = pos - startOffset + 1;
|
|
157
|
-
|
|
158
|
-
// Grow if needed
|
|
159
|
-
if (count >= ids.length) growArrays();
|
|
160
|
-
|
|
161
|
-
ids[count] = expressId;
|
|
162
|
-
offsets[count] = startOffset;
|
|
163
|
-
lengths[count] = entityLength;
|
|
164
|
-
lines[count] = startLine;
|
|
165
|
-
types[count] = typeName;
|
|
166
|
-
count++;
|
|
167
|
-
|
|
168
|
-
pos++;
|
|
169
|
-
break;
|
|
170
|
-
} else if (c6 === 0x0A) {
|
|
171
|
-
line++;
|
|
172
|
-
}
|
|
173
|
-
pos++;
|
|
174
|
-
}
|
|
175
|
-
} else if (ch === 0x0A) {
|
|
176
|
-
line++;
|
|
177
|
-
pos++;
|
|
178
|
-
} else if (ch === 0x27) { // quote
|
|
179
|
-
// Consume a string literal whole. HEADER records carry no '#', so this
|
|
180
|
-
// loop walks them byte by byte, and a '/*' inside a description would
|
|
181
|
-
// otherwise open a comment that never closes and take DATA with it.
|
|
182
|
-
var sp = pos + 1;
|
|
183
|
-
while (sp < len) {
|
|
184
|
-
if (buf[sp] === 0x27) {
|
|
185
|
-
if (sp + 1 < len && buf[sp + 1] === 0x27) { sp += 2; continue; }
|
|
186
|
-
sp++;
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
if (buf[sp] === 0x0A) { line++; }
|
|
190
|
-
sp++;
|
|
191
|
-
}
|
|
192
|
-
pos = sp;
|
|
193
|
-
} else if (ch === 0x2F && pos + 1 < len && buf[pos + 1] === 0x2A) {
|
|
194
|
-
// Skip a /* */ region. A record that is commented out is still a
|
|
195
|
-
// well-formed #id = TYPE(...), so every check above accepts it and only
|
|
196
|
-
// skipping the region rejects it. Kept byte-identical to
|
|
197
|
-
// step-lexing.ts, which this cannot import: the worker source is a
|
|
198
|
-
// string, so the third copy of this loop has to carry its own copy of
|
|
199
|
-
// the rule. Comments do not nest, per ISO 10303-21.
|
|
200
|
-
var cp = pos + 2;
|
|
201
|
-
var closed = false;
|
|
202
|
-
while (cp + 1 < len) {
|
|
203
|
-
if (buf[cp] === 0x2A && buf[cp + 1] === 0x2F) { closed = true; break; }
|
|
204
|
-
if (buf[cp] === 0x0A) { line++; }
|
|
205
|
-
cp++;
|
|
206
|
-
}
|
|
207
|
-
if (!closed) {
|
|
208
|
-
// Unterminated: everything to EOF is commented out.
|
|
209
|
-
pos = len;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
pos = cp + 2;
|
|
213
|
-
} else {
|
|
214
|
-
pos++;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Trim arrays once, reuse for both message and transfer list
|
|
219
|
-
var needsTrim = ids.buffer.byteLength > count * 4;
|
|
220
|
-
var trimmedIds = needsTrim ? ids.slice(0, count) : ids;
|
|
221
|
-
var trimmedOffsets = needsTrim ? offsets.slice(0, count) : offsets;
|
|
222
|
-
var trimmedLengths = needsTrim ? lengths.slice(0, count) : lengths;
|
|
223
|
-
var trimmedLines = needsTrim ? lines.slice(0, count) : lines;
|
|
224
|
-
self.postMessage({
|
|
225
|
-
ids: trimmedIds.buffer,
|
|
226
|
-
offsets: trimmedOffsets.buffer,
|
|
227
|
-
lengths: trimmedLengths.buffer,
|
|
228
|
-
lines: trimmedLines.buffer,
|
|
229
|
-
types: types.slice(0, count),
|
|
230
|
-
count: count,
|
|
231
|
-
}, [
|
|
232
|
-
trimmedIds.buffer,
|
|
233
|
-
trimmedOffsets.buffer,
|
|
234
|
-
trimmedLengths.buffer,
|
|
235
|
-
trimmedLines.buffer,
|
|
236
|
-
]);
|
|
237
|
-
};
|
|
238
|
-
`;
|
|
11
|
+
import { WORKER_CODE } from './scan-worker-source.js';
|
|
12
|
+
export { WORKER_CODE };
|
|
239
13
|
let workerBlobUrl = null;
|
|
240
14
|
function getWorkerBlobUrl() {
|
|
241
15
|
if (!workerBlobUrl) {
|
|
@@ -268,7 +42,7 @@ export function scanEntitiesInWorker(buffer) {
|
|
|
268
42
|
// checker.
|
|
269
43
|
const activeWorker = worker;
|
|
270
44
|
activeWorker.onmessage = (e) => {
|
|
271
|
-
const { ids, offsets, lengths, lines, types, count } = e.data;
|
|
45
|
+
const { ids, offsets, lengths, lines, types, count, oversizedIds, malformedRecords } = e.data;
|
|
272
46
|
const idArr = new Uint32Array(ids);
|
|
273
47
|
const offsetArr = new Uint32Array(offsets);
|
|
274
48
|
const lengthArr = new Uint32Array(lengths);
|
|
@@ -284,7 +58,7 @@ export function scanEntitiesInWorker(buffer) {
|
|
|
284
58
|
};
|
|
285
59
|
}
|
|
286
60
|
activeWorker.terminate();
|
|
287
|
-
resolve(refs);
|
|
61
|
+
resolve({ refs, oversizedIdCount: oversizedIds, malformedRecordCount: malformedRecords ?? 0 });
|
|
288
62
|
};
|
|
289
63
|
activeWorker.onerror = (e) => {
|
|
290
64
|
activeWorker.terminate();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan-worker-inline.js","sourceRoot":"","sources":["../src/scan-worker-inline.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"scan-worker-inline.js","sourceRoot":"","sources":["../src/scan-worker-inline.ts"],"names":[],"mappings":"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"}
|