• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DomCR / ACadSharp / 10438237818

18 Aug 2024 05:48AM UTC coverage: 75.966% (+0.08%) from 75.891%
10438237818

push

github

web-flow
Merge pull request #425 from DomCR/Issue-421_dxf-irregular-no-header

Issue-421_dxf-irregular-no-header

4815 of 7003 branches covered (68.76%)

Branch coverage included in aggregate %.

16 of 33 new or added lines in 9 files covered. (48.48%)

19 existing lines in 6 files now uncovered.

19217 of 24632 relevant lines covered (78.02%)

33169.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.99
/src/ACadSharp/IO/DXF/DxfStreamReader/DxfSectionReaderBase.cs
1
using ACadSharp.Entities;
2
using ACadSharp.IO.Templates;
3
using CSMath;
4
using System;
5
using System.Collections.Generic;
6
using System.Diagnostics;
7
using System.Linq;
8

9
namespace ACadSharp.IO.DXF
10
{
11
        internal abstract class DxfSectionReaderBase
12
        {
13
                public delegate bool ReadEntityDelegate<T>(CadEntityTemplate template, DxfMap map, string subclass = null) where T : Entity;
14

15
                protected readonly IDxfStreamReader _reader;
16
                protected readonly DxfDocumentBuilder _builder;
17

18
                public DxfSectionReaderBase(IDxfStreamReader reader, DxfDocumentBuilder builder)
508✔
19
                {
508✔
20
                        this._reader = reader;
508✔
21
                        this._builder = builder;
508✔
22
                }
508✔
23

24
                public abstract void Read();
25

26
                protected void readCommonObjectData(out string name, out ulong handle, out ulong? ownerHandle, out ulong? xdictHandle, out List<ulong> reactors)
27
                {
1,224✔
28
                        name = null;
1,224✔
29
                        handle = 0;
1,224✔
30
                        ownerHandle = null;
1,224✔
31
                        xdictHandle = null;
1,224✔
32
                        reactors = new List<ulong>();
1,224✔
33

34
                        if (this._reader.DxfCode == DxfCode.Start
1,224!
35
                                        || this._reader.DxfCode == DxfCode.Subclass)
1,224✔
36
                                this._reader.ReadNext();
×
37

38
                        //Loop until the common data end
39
                        while (this._reader.DxfCode != DxfCode.Start
4,860✔
40
                                        && this._reader.DxfCode != DxfCode.Subclass)
4,860✔
41
                        {
3,636✔
42
                                switch (this._reader.Code)
3,636!
43
                                {
44
                                        //Table name
45
                                        case 2:
46
                                                name = this._reader.ValueAsString;
1,224✔
47
                                                break;
1,224✔
48
                                        //Handle
49
                                        case 5:
50
                                        case 105:
51
                                                handle = this._reader.ValueAsHandle;
1,080✔
52
                                                break;
1,080✔
53
                                        //Start of application - defined group
54
                                        case 102:
55
                                                this.readDefinedGroups(out xdictHandle, out reactors);
108✔
56
                                                break;
108✔
57
                                        //Soft - pointer ID / handle to owner BLOCK_RECORD object
58
                                        case 330:
59
                                                ownerHandle = this._reader.ValueAsHandle;
1,080✔
60
                                                break;
1,080✔
61
                                        case 71:
62
                                        //Number of entries for dimension style table
63
                                        case 340:
64
                                        //Dimension table has the handles of the styles at the begining
65
                                        default:
66
                                                this._builder.Notify($"Unhandeled dxf code {this._reader.Code} at line {this._reader.Position}.");
144✔
67
                                                break;
144✔
68
                                }
69

70
                                this._reader.ReadNext();
3,636✔
71
                        }
3,636✔
72
                }
1,224✔
73

74
                [Obsolete("Only needed for SortEntitiesTable but it should be removed")]
75
                protected void readCommonObjectData(CadTemplate template)
76
                {
192✔
77
                        while (this._reader.DxfCode != DxfCode.Subclass)
768✔
78
                        {
576✔
79
                                switch (this._reader.Code)
576!
80
                                {
81
                                        //object name
82
                                        case 0:
83
                                                Debug.Assert(template.CadObject.ObjectName == this._reader.ValueAsString);
×
84
                                                break;
×
85
                                        //Handle
86
                                        case 5:
87
                                                template.CadObject.Handle = this._reader.ValueAsHandle;
192✔
88
                                                break;
192✔
89
                                        //Start of application - defined group
90
                                        case 102:
91
                                                this.readDefinedGroups(template);
192✔
92
                                                break;
192✔
93
                                        //Soft - pointer ID / handle to owner BLOCK_RECORD object
94
                                        case 330:
95
                                                template.OwnerHandle = this._reader.ValueAsHandle;
192✔
96
                                                break;
192✔
97
                                        default:
98
                                                this._builder.Notify($"Unhandeled dxf code {this._reader.Code} at line {this._reader.Position}.", NotificationType.None);
×
99
                                                break;
×
100
                                }
101

102
                                this._reader.ReadNext();
576✔
103
                        }
576✔
104
                }
192✔
105

106
                protected void readCommonCodes(CadTemplate template, out bool isExtendedData, DxfMap map = null)
107
                {
357,648✔
108
                        isExtendedData = false;
357,648✔
109

110
                        switch (this._reader.Code)
357,648✔
111
                        {
112
                                //Handle
113
                                case 5:
114
                                        template.CadObject.Handle = this._reader.ValueAsHandle;
94,642✔
115
                                        break;
94,642✔
116
                                //Check with mapper
117
                                case 100:
118
                                        if (map != null && !map.SubClasses.ContainsKey(this._reader.ValueAsString))
66,328!
119
                                                this._builder.Notify($"[{template.CadObject.ObjectName}] Unidentified subclass {this._reader.ValueAsString}", NotificationType.Warning);
60✔
120
                                        break;
66,328✔
121
                                //Start of application - defined group
122
                                case 102:
123
                                        this.readDefinedGroups(template);
22,062✔
124
                                        break;
22,062✔
125
                                //Soft - pointer ID / handle to owner BLOCK_RECORD object
126
                                case 330:
127
                                        template.OwnerHandle = this._reader.ValueAsHandle;
52,130✔
128
                                        break;
52,130✔
129
                                case 1001:
130
                                        isExtendedData = true;
7,512✔
131
                                        this.readExtendedData(template.EDataTemplateByAppName);
7,512✔
132
                                        break;
7,512✔
133
                                default:
134
                                        this._builder.Notify($"[{template.CadObject.SubclassMarker}] Unhandeled dxf code {this._reader.Code} with value {this._reader.ValueAsString}", NotificationType.None);
114,974✔
135
                                        break;
114,974✔
136
                        }
137
                }
357,648✔
138

139
                protected CadEntityTemplate readEntity()
140
                {
62,880✔
141
                        switch (this._reader.ValueAsString)
62,880!
142
                        {
143
                                case DxfFileToken.EntityAttribute:
144
                                        return this.readEntityCodes<AttributeEntity>(new CadTextEntityTemplate(new AttributeEntity()), this.readAttributeDefinition);
504✔
145
                                case DxfFileToken.EntityAttributeDefinition:
146
                                        return this.readEntityCodes<AttributeDefinition>(new CadTextEntityTemplate(new AttributeDefinition()), this.readAttributeDefinition);
560✔
147
                                case DxfFileToken.EntityArc:
148
                                        return this.readEntityCodes<Arc>(new CadEntityTemplate<Arc>(), this.readArc);
350✔
149
                                case DxfFileToken.EntityCircle:
150
                                        return this.readEntityCodes<Circle>(new CadEntityTemplate<Circle>(), this.readEntitySubclassMap);
490✔
151
                                case DxfFileToken.EntityDimension:
152
                                        return this.readEntityCodes<Dimension>(new CadDimensionTemplate(), this.readDimension);
1,008✔
153
                                case DxfFileToken.Entity3DFace:
154
                                        return this.readEntityCodes<Face3D>(new CadEntityTemplate<Face3D>(), this.readEntitySubclassMap);
126✔
155
                                case DxfFileToken.EntityEllipse:
156
                                        return this.readEntityCodes<Ellipse>(new CadEntityTemplate<Ellipse>(), this.readEntitySubclassMap);
108✔
157
                                case DxfFileToken.EntityLeader:
158
                                        return this.readEntityCodes<Leader>(new CadLeaderTemplate(), this.readLeader);
108✔
159
                                case DxfFileToken.EntityLine:
160
                                        return this.readEntityCodes<Line>(new CadEntityTemplate<Line>(), this.readEntitySubclassMap);
11,620✔
161
                                case DxfFileToken.EntityLwPolyline:
162
                                        return this.readEntityCodes<LwPolyline>(new CadEntityTemplate<LwPolyline>(), this.readLwPolyline);
1,164✔
163
                                case DxfFileToken.EntityMesh:
164
                                        return this.readEntityCodes<Mesh>(new CadMeshTemplate(), this.readMesh);
216✔
165
                                case DxfFileToken.EntityHatch:
166
                                        return this.readEntityCodes<Hatch>(new CadHatchTemplate(), this.readHatch);
432✔
167
                                case DxfFileToken.EntityInsert:
168
                                        return this.readEntityCodes<Insert>(new CadInsertTemplate(), this.readInsert);
1,116✔
169
                                case DxfFileToken.EntityMText:
170
                                        return this.readEntityCodes<MText>(new CadTextEntityTemplate(new MText()), this.readTextEntity);
2,076✔
171
                                case DxfFileToken.EntityMLine:
172
                                        return this.readEntityCodes<MLine>(new CadMLineTemplate(), this.readMLine);
324✔
173
                                case DxfFileToken.EntityPdfUnderlay:
174
                                        return this.readEntityCodes<PdfUnderlay>(new CadPdfUnderlayTemplate(), this.readUnderlayEntity);
×
175
                                case DxfFileToken.EntityPoint:
176
                                        return this.readEntityCodes<Point>(new CadEntityTemplate<Point>(), this.readEntitySubclassMap);
3,556✔
177
                                case DxfFileToken.EntityPolyline:
178
                                        return this.readPolyline();
4,692✔
179
                                case DxfFileToken.EntityRay:
180
                                        return this.readEntityCodes<Ray>(new CadEntityTemplate<Ray>(), this.readEntitySubclassMap);
108✔
181
                                case DxfFileToken.EndSequence:
182
                                        return this.readEntityCodes<Seqend>(new CadEntityTemplate<Seqend>(), this.readEntitySubclassMap);
4,944✔
183
                                case DxfFileToken.EntitySolid:
184
                                        return this.readEntityCodes<Solid>(new CadEntityTemplate<Solid>(), this.readEntitySubclassMap);
6,206✔
185
                                case DxfFileToken.EntityText:
186
                                        return this.readEntityCodes<TextEntity>(new CadTextEntityTemplate(new TextEntity()), this.readTextEntity);
3,536✔
187
                                case DxfFileToken.EntityTolerance:
188
                                        return this.readEntityCodes<Tolerance>(new CadToleranceTemplate(new Tolerance()), this.readTolerance);
324✔
189
                                case DxfFileToken.EntityVertex:
190
                                        return this.readEntityCodes<Entity>(new CadVertexTemplate(), this.readVertex);
17,812✔
191
                                case DxfFileToken.EntityViewport:
192
                                        return this.readEntityCodes<Viewport>(new CadViewportTemplate(), this.readViewport);
636✔
193
                                case DxfFileToken.EntityShape:
194
                                        return this.readEntityCodes<Shape>(new CadShapeTemplate(new Shape()), this.readShape);
108✔
195
                                case DxfFileToken.EntitySpline:
196
                                        return this.readEntityCodes<Spline>(new CadSplineTemplate(), this.readSpline);
216✔
197
                                case DxfFileToken.EntityXline:
198
                                        return this.readEntityCodes<XLine>(new CadEntityTemplate<XLine>(), this.readEntitySubclassMap);
108✔
199
                                default:
200
                                        DxfMap map = DxfMap.Create<Entity>();
432✔
201
                                        CadUnknownEntityTemplate unknownEntityTemplate = null;
432✔
202
                                        if (this._builder.DocumentToBuild.Classes.TryGetByName(this._reader.ValueAsString, out Classes.DxfClass dxfClass))
432✔
203
                                        {
384✔
204
                                                this._builder.Notify($"Entity not supported read as an UnknownEntity: {this._reader.ValueAsString}", NotificationType.NotImplemented);
384✔
205
                                                unknownEntityTemplate = new CadUnknownEntityTemplate(new UnknownEntity(dxfClass));
384✔
206
                                        }
384✔
207
                                        else
208
                                        {
48✔
209
                                                this._builder.Notify($"Entity not supported: {this._reader.ValueAsString}", NotificationType.NotImplemented);
48✔
210
                                        }
48✔
211

212
                                        this._reader.ReadNext();
432✔
213

214
                                        do
215
                                        {
69,018✔
216
                                                if (unknownEntityTemplate != null && this._builder.KeepUnknownEntities)
69,018✔
217
                                                {
7,642✔
218
                                                        this.readCommonEntityCodes(unknownEntityTemplate, out bool isExtendedData, map);
7,642✔
219
                                                        if (isExtendedData)
7,642✔
220
                                                                continue;
6✔
221
                                                }
7,636✔
222

223
                                                this._reader.ReadNext();
69,012✔
224
                                        }
69,012✔
225
                                        while (this._reader.DxfCode != DxfCode.Start);
69,018✔
226

227
                                        if (this._builder.Configuration.KeepUnknownEntities)
432✔
228
                                        {
48✔
229
                                                return unknownEntityTemplate;
48✔
230
                                        }
231
                                        else
232
                                        {
384✔
233
                                                return null;
384✔
234
                                        }
235
                        }
236
                }
62,880✔
237

238
                protected CadEntityTemplate readEntityCodes<T>(CadEntityTemplate template, ReadEntityDelegate<T> readEntity)
239
                        where T : Entity
240
                {
62,448✔
241
                        this._reader.ReadNext();
62,448✔
242

243
                        DxfMap map = DxfMap.Create<T>();
62,448✔
244

245
                        while (this._reader.DxfCode != DxfCode.Start)
784,114✔
246
                        {
721,666✔
247
                                if (!readEntity(template, map))
721,666✔
248
                                {
326,702✔
249
                                        this.readCommonEntityCodes(template, out bool isExtendedData, map);
326,702✔
250
                                        if (isExtendedData)
326,702✔
251
                                                continue;
2,602✔
252
                                }
324,100✔
253

254
                                if (this._reader.DxfCode != DxfCode.Start)
719,064✔
255
                                        this._reader.ReadNext();
719,064✔
256
                        }
719,064✔
257

258
                        return template;
62,448✔
259
                }
62,448✔
260

261
                protected void readCommonEntityCodes(CadEntityTemplate template, out bool isExtendedData, DxfMap map = null)
262
                {
351,224✔
263
                        isExtendedData = false;
351,224✔
264
                        switch (this._reader.Code)
351,224✔
265
                        {
266
                                case 6:
267
                                        template.LineTypeName = this._reader.ValueAsString;
9,140✔
268
                                        break;
9,140✔
269
                                case 8:
270
                                        template.LayerName = this._reader.ValueAsString;
67,024✔
271
                                        break;
67,024✔
272
                                //Absent or zero indicates entity is in model space. 1 indicates entity is in paper space (optional).
273
                                case 67:
274
                                        break;
608✔
275
                                //Number of bytes Proxy entity graphics data
276
                                case 92:
277
                                case 160:
278
                                //Proxy entity graphics data
279
                                case 310:
280
                                        break;
17,024✔
281
                                case 347:
282
                                        template.MaterialHandle = this._reader.ValueAsHandle;
72✔
283
                                        break;
72✔
284
                                default:
285
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Entity]))
257,356✔
286
                                        {
229,108✔
287
                                                this.readCommonCodes(template, out isExtendedData, map);
229,108✔
288
                                        }
229,108✔
289
                                        break;
257,356✔
290
                        }
291
                }
351,224✔
292

293
                private bool readArc(CadEntityTemplate template, DxfMap map, string subclass = null)
294
                {
4,576✔
295
                        switch (this._reader.Code)
4,576✔
296
                        {
297
                                default:
298
                                        if (!this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Arc]))
4,576✔
299
                                        {
3,876✔
300
                                                return this.readEntitySubclassMap(template, map, DxfSubclassMarker.Circle);
3,876✔
301
                                        }
302
                                        return true;
700✔
303
                        }
304
                }
4,576✔
305

306
                private bool readAttributeDefinition(CadEntityTemplate template, DxfMap map, string subclass = null)
307
                {
17,524✔
308
                        DxfClassMap emap = map.SubClasses[template.CadObject.SubclassMarker];
17,524✔
309
                        CadTextEntityTemplate tmp = template as CadTextEntityTemplate;
17,524✔
310

311
                        switch (this._reader.Code)
17,524✔
312
                        {
313
                                //TODO: Implement multiline attribute def codes
314
                                case 44:
315
                                case 46:
316
                                case 101:
317
                                        return true;
102✔
318
                                default:
319
                                        if (!this.tryAssignCurrentValue(template.CadObject, emap))
17,422✔
320
                                        {
13,302✔
321
                                                return this.readTextEntity(template, map, DxfSubclassMarker.Text);
13,302✔
322
                                        }
323
                                        return true;
4,120✔
324
                        }
325
                }
17,524✔
326

327
                private bool readTextEntity(CadEntityTemplate template, DxfMap map, string subclass = null)
328
                {
84,100✔
329
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
84,100✔
330
                        CadTextEntityTemplate tmp = template as CadTextEntityTemplate;
84,100✔
331

332
                        switch (this._reader.Code)
84,100✔
333
                        {
334
                                //TODO: Implement multiline text def codes
335
                                case 1 or 3 when tmp.CadObject is MText mtext:
8,114✔
336
                                        mtext.Value += this._reader.ValueAsString;
3,480✔
337
                                        return true;
3,480✔
338
                                case 70:
339
                                case 74:
340
                                case 101:
341
                                        return true;
216✔
342
                                case 7:
343
                                        tmp.StyleName = this._reader.ValueAsString;
504✔
344
                                        return true;
504✔
345
                                default:
346
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
79,900✔
347
                        }
348
                }
84,100✔
349

350
                private bool readTolerance(CadEntityTemplate template, DxfMap map, string subclass = null)
351
                {
3,240✔
352
                        CadToleranceTemplate tmp = template as CadToleranceTemplate;
3,240✔
353

354
                        switch (this._reader.Code)
3,240✔
355
                        {
356
                                case 3:
357
                                        tmp.DimensionStyleName = this._reader.ValueAsString;
324✔
358
                                        return true;
324✔
359
                                default:
360
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
2,916✔
361
                        }
362
                }
3,240✔
363

364
                private bool readDimension(CadEntityTemplate template, DxfMap map, string subclass = null)
365
                {
26,046✔
366
                        CadDimensionTemplate tmp = template as CadDimensionTemplate;
26,046✔
367

368
                        switch (this._reader.Code)
26,046✔
369
                        {
370
                                case 2:
371
                                        tmp.BlockName = this._reader.ValueAsString;
1,008✔
372
                                        return true;
1,008✔
373
                                case 3:
374
                                        tmp.StyleName = this._reader.ValueAsString;
864✔
375
                                        return true;
864✔
376
                                case 50:
377
                                        var dim = new DimensionLinear();
126✔
378
                                        tmp.SetDimensionObject(dim);
126✔
379
                                        dim.Rotation = CSMath.MathUtils.DegToRad(this._reader.ValueAsDouble);
126✔
380
                                        map.SubClasses.Add(DxfSubclassMarker.LinearDimension, DxfClassMap.Create<DimensionLinear>());
126✔
381
                                        return true;
126✔
382
                                case 70:
383
                                        //Flags do not have set
384
                                        tmp.SetDimensionFlags((DimensionType)this._reader.ValueAsShort);
1,008✔
385
                                        return true;
1,008✔
386
                                //Measurement - read only
387
                                case 42:
388
                                        return true;
864✔
389
                                //Undocumented codes
390
                                case 73:
391
                                case 74:
392
                                case 75:
393
                                case 90:
394
                                case 361:
395
                                        return true;
1,728✔
396
                                case 100:
397
                                        switch (this._reader.ValueAsString)
2,700✔
398
                                        {
399
                                                case DxfSubclassMarker.Dimension:
400
                                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Dimension]);
864✔
401
                                                case DxfSubclassMarker.AlignedDimension:
402
                                                        tmp.SetDimensionObject(new DimensionAligned());
216✔
403
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAligned>());
216✔
404
                                                        return true;
216✔
405
                                                case DxfSubclassMarker.DiametricDimension:
406
                                                        tmp.SetDimensionObject(new DimensionDiameter());
108✔
407
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionDiameter>());
108✔
408
                                                        return true;
108✔
409
                                                case DxfSubclassMarker.Angular2LineDimension:
410
                                                        tmp.SetDimensionObject(new DimensionAngular2Line());
108✔
411
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAngular2Line>());
108✔
412
                                                        return true;
108✔
413
                                                case DxfSubclassMarker.Angular3PointDimension:
414
                                                        tmp.SetDimensionObject(new DimensionAngular3Pt());
108✔
415
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionAngular3Pt>());
108✔
416
                                                        return true;
108✔
417
                                                case DxfSubclassMarker.RadialDimension:
418
                                                        tmp.SetDimensionObject(new DimensionRadius());
108✔
419
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionRadius>());
108✔
420
                                                        return true;
108✔
421
                                                case DxfSubclassMarker.OrdinateDimension:
422
                                                        tmp.SetDimensionObject(new DimensionOrdinate());
216✔
423
                                                        map.SubClasses.Add(this._reader.ValueAsString, DxfClassMap.Create<DimensionOrdinate>());
216✔
424
                                                        return true;
216✔
425
                                                case DxfSubclassMarker.LinearDimension:
426
                                                        return true;
108✔
427
                                                default:
428
                                                        return false;
864✔
429
                                        }
430
                                default:
431
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
17,748✔
432
                        }
433
                }
26,046✔
434

435
                protected bool readHatch(CadEntityTemplate template, DxfMap map, string subclass = null)
436
                {
24,840✔
437
                        CadHatchTemplate tmp = template as CadHatchTemplate;
24,840✔
438
                        Hatch hatch = tmp.CadObject;
24,840✔
439

440
                        bool isFirstSeed = true;
24,840✔
441
                        XY seedPoint = new XY();
24,840✔
442

443
                        switch (this._reader.Code)
24,840!
444
                        {
445
                                case 2:
446
                                        tmp.HatchPatternName = this._reader.ValueAsString;
432✔
447
                                        return true;
432✔
448
                                case 10:
449
                                        seedPoint.X = this._reader.ValueAsDouble;
864✔
450
                                        return true;
864✔
451
                                case 20:
452
                                        if (!isFirstSeed)
864!
453
                                        {
×
454
                                                seedPoint.Y = this._reader.ValueAsDouble;
×
455
                                                hatch.SeedPoints.Add(seedPoint);
×
456
                                        }
×
457
                                        return true;
864✔
458
                                case 30:
459
                                        hatch.Elevation = this._reader.ValueAsDouble;
432✔
460
                                        isFirstSeed = false;
432✔
461
                                        return true;
432✔
462
                                //TODO: Check hatch undocumented codes
463
                                case 43:
464
                                case 44:
465
                                case 45:
466
                                case 46:
467
                                case 49:
468
                                case 53:
469
                                case 79:
470
                                case 90:
471
                                        return true;
12,744✔
472
                                //Information about the hatch pattern
473
                                case 75:
474
                                        return true;
×
475
                                //Number of pattern definition lines
476
                                case 78:
477
                                        return true;
216✔
478
                                //Number of boundary paths (loops)
479
                                case 91:
480
                                        this.readLoops(tmp, this._reader.ValueAsInt);
432✔
481
                                        return true;
432✔
482
                                //Number of seed points
483
                                case 98:
484
                                        return true;
432✔
485
                                case 450:
486
                                        hatch.GradientColor.Enabled = this._reader.ValueAsBool;
180✔
487
                                        return true;
180✔
488
                                case 451:
489
                                        hatch.GradientColor.Reserved = this._reader.ValueAsInt;
180✔
490
                                        return true;
180✔
491
                                case 452:
492
                                        hatch.GradientColor.IsSingleColorGradient = this._reader.ValueAsBool;
180✔
493
                                        return true;
180✔
494
                                case 453:
495
                                        //Number of colors
496
                                        return true;
180✔
497
                                case 460:
498
                                        hatch.GradientColor.Angle = this._reader.ValueAsDouble;
180✔
499
                                        return true;
180✔
500
                                case 461:
501
                                        hatch.GradientColor.Shift = this._reader.ValueAsDouble;
180✔
502
                                        return true;
180✔
503
                                case 462:
504
                                        hatch.GradientColor.ColorTint = this._reader.ValueAsDouble;
180✔
505
                                        return true;
180✔
506
                                case 463:
507
                                        GradientColor gradient = new GradientColor();
360✔
508
                                        gradient.Value = this._reader.ValueAsDouble;
360✔
509
                                        hatch.GradientColor.Colors.Add(gradient);
360✔
510
                                        return true;
360✔
511
                                case 63:
512
                                        GradientColor colorByIndex = hatch.GradientColor.Colors.LastOrDefault();
360✔
513
                                        if (colorByIndex != null)
360✔
514
                                        {
360✔
515
                                                colorByIndex.Color = new Color((short)this._reader.ValueAsUShort);
360✔
516
                                        }
360✔
517
                                        return true;
360✔
518
                                case 421:
519
                                        GradientColor colorByRgb = hatch.GradientColor.Colors.LastOrDefault();
360✔
520
                                        if (colorByRgb != null)
360✔
521
                                        {
360✔
522
                                                //TODO: Hatch assign color by true color
523
                                                //TODO: Is always duplicated by 63, is it needed??
524
                                                //colorByRgb.Color = new Color(this._reader.LastValueAsShort);
525
                                        }
360✔
526
                                        return true;
360✔
527
                                case 470:
528
                                        hatch.GradientColor.Name = this._reader.ValueAsString;
180✔
529
                                        return true;
180✔
530
                                default:
531
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[template.CadObject.SubclassMarker]);
5,904✔
532
                        }
533
                }
24,840✔
534

535
                private bool readInsert(CadEntityTemplate template, DxfMap map, string subclass = null)
536
                {
11,264✔
537
                        CadInsertTemplate tmp = template as CadInsertTemplate;
11,264✔
538

539
                        switch (this._reader.Code)
11,264✔
540
                        {
541
                                case 2:
542
                                        tmp.BlockName = this._reader.ValueAsString;
1,116✔
543
                                        return true;
1,116✔
544
                                case 66:
545
                                        return true;
252✔
546
                                default:
547
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
9,896✔
548
                        }
549
                }
11,264✔
550

551
                private CadEntityTemplate readPolyline()
552
                {
4,692✔
553
                        CadPolyLineTemplate template = null;
4,692✔
554

555
                        if (this._builder.Version == ACadVersion.Unknown)
4,692!
556
                        {
×
557
                                var polyline = new Polyline2D();
×
558
                                template = new CadPolyLineTemplate(polyline);
×
559
                                this.readEntityCodes<Polyline2D>(template, this.readPolyline);
×
560

561
                                while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EntityVertex)
×
562
                                {
×
563
                                        Vertex2D v = new Vertex2D();
×
564
                                        CadVertexTemplate vertexTemplate = new CadVertexTemplate(v);
×
565
                                        this.readEntityCodes<Vertex2D>(vertexTemplate, this.readVertex);
×
566

NEW
567
                                        if (vertexTemplate.Vertex.Handle == 0)
×
NEW
568
                                        {
×
NEW
569
                                                template.PolyLine.Vertices.Add(vertexTemplate.Vertex);
×
NEW
570
                                        }
×
571
                                        else
NEW
572
                                        {
×
NEW
573
                                                template.VertexHandles.Add(vertexTemplate.Vertex.Handle);
×
NEW
574
                                                this._builder.AddTemplate(vertexTemplate);
×
NEW
575
                                        }
×
UNCOV
576
                                }
×
577

578
                                while (this._reader.Code == 0 && this._reader.ValueAsString == DxfFileToken.EndSequence)
×
579
                                {
×
580
                                        var seqend = new Seqend();
×
581
                                        var seqendTemplate = new CadEntityTemplate<Seqend>(seqend);
×
582
                                        this.readEntityCodes<Seqend>(seqendTemplate, this.readEntitySubclassMap);
×
583

584
                                        this._builder.AddTemplate(seqendTemplate);
×
585

586
                                        template.SeqendHandle = seqend.Handle;
×
587
                                }
×
588
                        }
×
589
                        else
590
                        {
4,692✔
591
                                template = new CadPolyLineTemplate();
4,692✔
592
                                this.readEntityCodes<Entity>(template, this.readPolyline);
4,692✔
593
                        }
4,692✔
594

595
                        if (template.CadObject is CadPolyLineTemplate.PolyLinePlaceholder)
4,692✔
596
                        {
4,476✔
597
                                this._builder.Notify($"[{DxfFileToken.EntityPolyline}] Subclass not found, entity discarded", NotificationType.Warning);
4,476✔
598
                                return null;
4,476✔
599
                        }
600

601
                        return template;
216✔
602
                }
4,692✔
603

604
                private bool readPolyline(CadEntityTemplate template, DxfMap map, string subclass = null)
605
                {
33,794✔
606
                        CadPolyLineTemplate tmp = template as CadPolyLineTemplate;
33,794✔
607

608
                        switch (this._reader.Code)
33,794✔
609
                        {
610
                                //DXF: always 0
611
                                //APP: a “dummy” point; the X and Y values are always 0, and the Z value is the polyline's elevation (in OCS when 2D, WCS when 3D)
612
                                case 10:
613
                                case 20:
614
                                //Obsolete; formerly an “entities follow flag” (optional; ignore if present)
615
                                case 66:
616
                                //Polygon mesh M vertex count (optional; default = 0)
617
                                case 71:
618
                                //Polygon mesh N vertex count(optional; default = 0)
619
                                case 72:
620
                                //Smooth surface M density(optional; default = 0)
621
                                case 73:
622
                                //Smooth surface N density (optional; default = 0)
623
                                case 74:
624
                                        return true;
14,328✔
625
                                case 100:
626
                                        switch (this._reader.ValueAsString)
432!
627
                                        {
628
                                                case DxfSubclassMarker.Polyline:
629
                                                        tmp.SetPolyLineObject(new Polyline2D());
×
630
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline, DxfClassMap.Create<Polyline2D>());
×
631
                                                        return true;
×
632
                                                case DxfSubclassMarker.Polyline3d:
633
                                                        tmp.SetPolyLineObject(new Polyline3D());
108✔
634
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline3d, DxfClassMap.Create<Polyline3D>());
108✔
635
                                                        return true;
108✔
636
                                                case DxfSubclassMarker.PolyfaceMesh:
637
                                                        tmp.SetPolyLineObject(new PolyfaceMesh());
108✔
638
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMesh, DxfClassMap.Create<PolyfaceMesh>());
108✔
639
                                                        return true;
108✔
640
                                                default:
641
                                                        return false;
216✔
642
                                        }
643
                                default:
644
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
19,034✔
645
                        }
646
                }
33,794✔
647

648
                private bool readLeader(CadEntityTemplate template, DxfMap map, string subclass = null)
649
                {
2,700✔
650
                        CadLeaderTemplate tmp = template as CadLeaderTemplate;
2,700✔
651

652
                        switch (this._reader.Code)
2,700✔
653
                        {
654
                                case 3:
655
                                        tmp.DIMSTYLEName = this._reader.ValueAsString;
108✔
656
                                        return true;
108✔
657
                                case 10:
658
                                        tmp.CadObject.Vertices.Add(new XYZ(this._reader.ValueAsDouble, 0, 0));
432✔
659
                                        return true;
432✔
660
                                case 20:
661
                                        XYZ y = tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1];
432✔
662
                                        y.Y = this._reader.ValueAsDouble;
432✔
663
                                        tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1] = y;
432✔
664
                                        return true;
432✔
665
                                case 30:
666
                                        XYZ z = tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1];
432✔
667
                                        z.Z = this._reader.ValueAsDouble;
432✔
668
                                        tmp.CadObject.Vertices[tmp.CadObject.Vertices.Count - 1] = z;
432✔
669
                                        return true;
432✔
670
                                case 340:
671
                                        tmp.AnnotationHandle = this._reader.ValueAsHandle;
108✔
672
                                        return true;
108✔
673
                                //Vertices count
674
                                case 76:
675
                                        return true;
108✔
676
                                default:
677
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
1,080✔
678
                        }
679
                }
2,700✔
680

681
                private bool readLwPolyline(CadEntityTemplate template, DxfMap map, string subclass = null)
682
                {
24,768✔
683
                        CadEntityTemplate<LwPolyline> tmp = template as CadEntityTemplate<LwPolyline>;
24,768✔
684

685
                        LwPolyline.Vertex last = tmp.CadObject.Vertices.LastOrDefault();
24,768✔
686

687
                        switch (this._reader.Code)
24,768!
688
                        {
689
                                case 10:
690
                                        tmp.CadObject.Vertices.Add(new LwPolyline.Vertex(new XY(this._reader.ValueAsDouble, 0)));
5,724✔
691
                                        return true;
5,724✔
692
                                case 20:
693
                                        if (last is not null)
5,724✔
694
                                        {
5,724✔
695
                                                last.Location = new XY(last.Location.X, this._reader.ValueAsDouble);
5,724✔
696
                                        }
5,724✔
697
                                        return true;
5,724✔
698
                                case 40:
699
                                        if (last is not null)
1,080✔
700
                                        {
1,080✔
701
                                                last.StartWidth = this._reader.ValueAsDouble;
1,080✔
702
                                        }
1,080✔
703
                                        return true;
1,080✔
704
                                case 41:
705
                                        if (last is not null)
1,080✔
706
                                        {
1,080✔
707
                                                last.EndWidth = this._reader.ValueAsDouble;
1,080✔
708
                                        }
1,080✔
709
                                        return true;
1,080✔
710
                                case 42:
711
                                        if (last is not null)
1,440✔
712
                                        {
1,440✔
713
                                                last.Bulge = this._reader.ValueAsDouble;
1,440✔
714
                                        }
1,440✔
715
                                        return true;
1,440✔
716
                                case 50:
717
                                        if (last is not null)
×
718
                                        {
×
719
                                                last.CurveTangent = this._reader.ValueAsDouble;
×
720
                                        }
×
721
                                        return true;
×
722
                                //Obsolete; formerly an “entities follow flag” (optional; ignore if present)
723
                                case 66:
724
                                //Vertex count
725
                                case 90:
726
                                        return true;
1,164✔
727
                                case 91:
728
                                        if (last is not null)
×
729
                                        {
×
730
                                                last.Id = this._reader.ValueAsInt;
×
731
                                        }
×
732
                                        return true;
×
733
                                default:
734
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
8,556✔
735
                        }
736
                }
24,768✔
737

738
                private bool readMesh(CadEntityTemplate template, DxfMap map, string subclass = null)
739
                {
19,008✔
740
                        CadMeshTemplate tmp = template as CadMeshTemplate;
19,008✔
741

742
                        switch (this._reader.Code)
19,008✔
743
                        {
744
                                case 100:
745
                                        if (this._reader.ValueAsString.Equals(DxfSubclassMarker.Mesh, StringComparison.OrdinalIgnoreCase))
432✔
746
                                        {
216✔
747
                                                tmp.SubclassMarker = true;
216✔
748
                                        }
216✔
749
                                        return true;
432✔
750
                                //Count of sub-entity which property has been overridden
751
                                case 90:
752
                                        //TODO: process further entities
753
                                        return true;
216✔
754
                                case 92:
755
                                        if (!tmp.SubclassMarker)
324✔
756
                                        {
108✔
757
                                                return false;
108✔
758
                                        }
759

760
                                        int nvertices = this._reader.ValueAsInt;
216✔
761
                                        for (int i = 0; i < nvertices; i++)
27,648✔
762
                                        {
13,608✔
763
                                                this._reader.ReadNext();
13,608✔
764
                                                double x = this._reader.ValueAsDouble;
13,608✔
765
                                                this._reader.ReadNext();
13,608✔
766
                                                double y = this._reader.ValueAsDouble;
13,608✔
767
                                                this._reader.ReadNext();
13,608✔
768
                                                double z = this._reader.ValueAsDouble;
13,608✔
769
                                                tmp.CadObject.Vertices.Add(new XYZ(x, y, z));
13,608✔
770
                                        }
13,608✔
771
                                        return true;
216✔
772
                                case 93:
773
                                        int size = this._reader.ValueAsInt;
216✔
774
                                        this._reader.ReadNext();
216✔
775

776
                                        int indexes = 0;
216✔
777
                                        for (int i = 0; i < size; i += indexes + 1)
29,808✔
778
                                        {
14,688✔
779
                                                indexes = this._reader.ValueAsInt;
14,688✔
780
                                                this._reader.ReadNext();
14,688✔
781

782
                                                int[] face = new int[indexes];
14,688✔
783
                                                for (int j = 0; j < indexes; j++)
141,696✔
784
                                                {
56,160✔
785
                                                        face[j] = this._reader.ValueAsInt;
56,160✔
786

787
                                                        if ((i + j + 2) < size)
56,160✔
788
                                                        {
55,944✔
789
                                                                this._reader.ReadNext();
55,944✔
790
                                                        }
55,944✔
791
                                                }
56,160✔
792

793
                                                tmp.CadObject.Faces.Add(face);
14,688✔
794
                                        }
14,688✔
795

796
                                        Debug.Assert(this._reader.Code == 90);
216✔
797

798
                                        return true;
216✔
799
                                case 94:
800
                                        int numEdges = this._reader.ValueAsInt;
216✔
801
                                        this._reader.ReadNext();
216✔
802
                                        for (int i = 0; i < numEdges; i++)
56,592✔
803
                                        {
28,080✔
804
                                                Mesh.Edge edge = new Mesh.Edge();
28,080✔
805

806
                                                edge.Start = this._reader.ValueAsInt;
28,080✔
807
                                                this._reader.ReadNext();
28,080✔
808
                                                edge.End = this._reader.ValueAsInt;
28,080✔
809

810
                                                if (i < numEdges - 1)
28,080✔
811
                                                {
27,864✔
812
                                                        this._reader.ReadNext();
27,864✔
813
                                                }
27,864✔
814

815
                                                tmp.CadObject.Edges.Add(edge);
28,080✔
816
                                        }
28,080✔
817

818
                                        Debug.Assert(this._reader.Code == 90);
216✔
819

820
                                        return true;
216✔
821
                                case 95:
822
                                        this._reader.ReadNext();
216✔
823
                                        for (int i = 0; i < tmp.CadObject.Edges.Count; i++)
56,592✔
824
                                        {
28,080✔
825
                                                Mesh.Edge edge = tmp.CadObject.Edges[i];
28,080✔
826
                                                edge.Crease = this._reader.ValueAsDouble;
28,080✔
827

828
                                                tmp.CadObject.Edges[i] = edge;
28,080✔
829

830
                                                if (i < tmp.CadObject.Edges.Count - 1)
28,080✔
831
                                                {
27,864✔
832
                                                        this._reader.ReadNext();
27,864✔
833
                                                }
27,864✔
834
                                        }
28,080✔
835

836
                                        Debug.Assert(this._reader.Code == 140);
216✔
837

838
                                        return true;
216✔
839
                                default:
840
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
17,388✔
841
                        }
842
                }
19,008✔
843

844
                private bool readMLine(CadEntityTemplate template, DxfMap map, string subclass = null)
845
                {
28,080✔
846
                        CadMLineTemplate tmp = template as CadMLineTemplate;
28,080✔
847

848
                        switch (this._reader.Code)
28,080✔
849
                        {
850
                                // String of up to 32 characters. The name of the style used for this mline. An entry for this style must exist in the MLINESTYLE dictionary.
851
                                // Do not modify this field without also updating the associated entry in the MLINESTYLE dictionary
852
                                case 2:
853
                                        tmp.MLineStyleName = this._reader.ValueAsString;
324✔
854
                                        return true;
324✔
855
                                case 72:
856
                                        tmp.NVertex = this._reader.ValueAsInt;
324✔
857
                                        return true;
324✔
858
                                case 73:
859
                                        tmp.NElements = this._reader.ValueAsInt;
324✔
860
                                        return true;
324✔
861
                                case 340:
862
                                        tmp.MLineStyleHandle = this._reader.ValueAsHandle;
324✔
863
                                        return true;
324✔
864
                                default:
865
                                        if (!tmp.TryReadVertex(this._reader.Code, this._reader.Value))
26,784✔
866
                                        {
4,536✔
867
                                                return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
4,536✔
868
                                        }
869
                                        return true;
22,248✔
870
                        }
871
                }
28,080✔
872

873
                private bool readShape(CadEntityTemplate template, DxfMap map, string subclass = null)
874
                {
1,080✔
875
                        CadShapeTemplate tmp = template as CadShapeTemplate;
1,080✔
876

877
                        switch (this._reader.Code)
1,080✔
878
                        {
879
                                case 2:
880
                                        tmp.ShapeFileName = this._reader.ValueAsString;
108✔
881
                                        return true;
108✔
882
                                default:
883
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
972✔
884
                        }
885
                }
1,080✔
886

887
                private bool readSpline(CadEntityTemplate template, DxfMap map, string subclass = null)
888
                {
7,560✔
889
                        CadSplineTemplate tmp = template as CadSplineTemplate;
7,560✔
890

891
                        XYZ controlPoint;
892

893
                        switch (this._reader.Code)
7,560!
894
                        {
895
                                case 10:
896
                                        controlPoint = new CSMath.XYZ(this._reader.ValueAsDouble, 0, 0);
864✔
897
                                        tmp.CadObject.ControlPoints.Add(controlPoint);
864✔
898
                                        return true;
864✔
899
                                case 20:
900
                                        controlPoint = tmp.CadObject.ControlPoints.LastOrDefault();
864✔
901
                                        controlPoint.Y = this._reader.ValueAsDouble;
864✔
902
                                        tmp.CadObject.ControlPoints[tmp.CadObject.ControlPoints.Count - 1] = controlPoint;
864✔
903
                                        return true;
864✔
904
                                case 30:
905
                                        controlPoint = tmp.CadObject.ControlPoints.LastOrDefault();
864✔
906
                                        controlPoint.Z = this._reader.ValueAsDouble;
864✔
907
                                        tmp.CadObject.ControlPoints[tmp.CadObject.ControlPoints.Count - 1] = controlPoint;
864✔
908
                                        return true;
864✔
909
                                case 40:
910
                                        tmp.CadObject.Knots.Add(this._reader.ValueAsDouble);
1,728✔
911
                                        return true;
1,728✔
912
                                case 41:
913
                                        tmp.CadObject.Weights.Add(this._reader.ValueAsDouble);
×
914
                                        return true;
×
915
                                case 72:
916
                                case 73:
917
                                case 74:
918
                                        return true;
648✔
919
                                default:
920
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
2,592✔
921
                        }
922
                }
7,560✔
923

924
                private bool readUnderlayEntity(CadEntityTemplate template, DxfMap map, string subclass = null)
925
                {
×
926
                        CadPdfUnderlayTemplate tmp = template as CadPdfUnderlayTemplate;
×
927

928
                        switch (this._reader.Code)
×
929
                        {
930
                                case 340:
931
                                        tmp.DefinitionHandle = this._reader.ValueAsHandle;
×
932
                                        return true;
×
933
                                default:
934
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
×
935
                        }
936
                }
×
937

938
                private bool readVertex(CadEntityTemplate template, DxfMap map, string subclass = null)
939
                {
112,188✔
940
                        CadVertexTemplate tmp = template as CadVertexTemplate;
112,188✔
941

942
                        switch (this._reader.Code)
112,188✔
943
                        {
944
                                //Polyface mesh vertex index
945
                                case 71:
946
                                case 72:
947
                                case 73:
948
                                case 74:
949
                                        return true;
882✔
950
                                case 100:
951
                                        switch (this._reader.ValueAsString)
3,672!
952
                                        {
953
                                                case DxfSubclassMarker.Vertex:
954
                                                        return true;
1,080✔
955
                                                case DxfSubclassMarker.PolylineVertex:
956
                                                        tmp.SetVertexObject(new Vertex2D());
×
957
                                                        map.SubClasses.Add(DxfSubclassMarker.PolylineVertex, DxfClassMap.Create<Vertex2D>());
×
958
                                                        return true;
×
959
                                                case DxfSubclassMarker.Polyline3dVertex:
960
                                                        tmp.SetVertexObject(new Vertex3D());
540✔
961
                                                        map.SubClasses.Add(DxfSubclassMarker.Polyline3dVertex, DxfClassMap.Create<Vertex3D>());
540✔
962
                                                        return true;
540✔
963
                                                case DxfSubclassMarker.PolyfaceMeshVertex:
964
                                                        tmp.SetVertexObject(new VertexFaceMesh());
540✔
965
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMeshVertex, DxfClassMap.Create<VertexFaceMesh>());
540✔
966
                                                        return true;
540✔
967
                                                case DxfSubclassMarker.PolyfaceMeshFace:
968
                                                        tmp.SetVertexObject(new VertexFaceRecord());
216✔
969
                                                        map.SubClasses.Add(DxfSubclassMarker.PolyfaceMeshFace, DxfClassMap.Create<VertexFaceRecord>());
216✔
970
                                                        return true;
216✔
971
                                                default:
972
                                                        return false;
1,296✔
973
                                        }
974
                                default:
975
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[tmp.CadObject.SubclassMarker]);
107,634✔
976
                        }
977
                }
112,188✔
978

979
                private bool readViewport(CadEntityTemplate template, DxfMap map, string subclass = null)
980
                {
34,696✔
981
                        CadViewportTemplate tmp = template as CadViewportTemplate;
34,696✔
982

983
                        switch (this._reader.Code)
34,696!
984
                        {
985
                                //Undocumented
986
                                case 67:
987
                                case 68:
988
                                        return true;
1,272✔
989
                                case 69:
990
                                        tmp.ViewportId = this._reader.ValueAsShort;
636✔
991
                                        return true;
636✔
992
                                case 331:
993
                                        tmp.FrozenLayerHandles.Add(this._reader.ValueAsHandle);
×
994
                                        return true;
×
995
                                case 348:
996
                                        tmp.VisualStyleHandle = this._reader.ValueAsHandle;
400✔
997
                                        return true;
400✔
998
                                default:
999
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[DxfSubclassMarker.Viewport]);
32,388✔
1000
                        }
1001
                }
34,696✔
1002

1003
                private bool readEntitySubclassMap(CadEntityTemplate template, DxfMap map, string subclass = null)
1004
                {
303,380✔
1005
                        string mapName = string.IsNullOrEmpty(subclass) ? template.CadObject.SubclassMarker : subclass;
303,380✔
1006

1007
                        switch (this._reader.Code)
303,380✔
1008
                        {
1009
                                default:
1010
                                        return this.tryAssignCurrentValue(template.CadObject, map.SubClasses[mapName]);
303,380✔
1011
                        }
1012
                }
303,380✔
1013

1014
                protected void readExtendedData(Dictionary<string, ExtendedData> edata)
1015
                {
10,959✔
1016
                        ExtendedData extendedData = new ExtendedData();
10,959✔
1017
                        edata.Add(this._reader.ValueAsString, extendedData);
10,959✔
1018

1019
                        this._reader.ReadNext();
10,959✔
1020

1021
                        while (this._reader.DxfCode >= DxfCode.ExtendedDataAsciiString)
53,797✔
1022
                        {
46,186✔
1023
                                if (this._reader.DxfCode == DxfCode.ExtendedDataRegAppName)
46,186✔
1024
                                {
3,348✔
1025
                                        this.readExtendedData(edata);
3,348✔
1026
                                        break;
3,348✔
1027
                                }
1028

1029
                                extendedData.Data.Add(new ExtendedDataRecord(this._reader.DxfCode, this._reader.Value));
42,838✔
1030

1031
                                this._reader.ReadNext();
42,838✔
1032
                        }
42,838✔
1033
                }
10,959✔
1034

1035
                private void readLoops(CadHatchTemplate template, int count)
1036
                {
432✔
1037
                        if (this._reader.Code == 91)
432✔
1038
                                this._reader.ReadNext();
432✔
1039

1040
                        for (int i = 0; i < count; i++)
1,728✔
1041
                        {
432✔
1042
                                if (this._reader.Code != 92)
432!
1043
                                {
×
1044
                                        this._builder.Notify($"Boundary path should start with code 92 but was {this._reader.Code}");
×
1045
                                        break;
×
1046
                                }
1047

1048
                                CadHatchTemplate.CadBoundaryPathTemplate path = this.readLoop();
432✔
1049
                                if (path != null)
432✔
1050
                                        template.PathTempaltes.Add(path);
432✔
1051
                        }
432✔
1052
                }
432✔
1053

1054
                private CadHatchTemplate.CadBoundaryPathTemplate readLoop()
1055
                {
432✔
1056
                        CadHatchTemplate.CadBoundaryPathTemplate template = new CadHatchTemplate.CadBoundaryPathTemplate();
432✔
1057
                        template.Path.Flags = (BoundaryPathFlags)this._reader.ValueAsInt;
432✔
1058

1059
                        if (template.Path.Flags.HasFlag(BoundaryPathFlags.Polyline))
432!
1060
                        {
×
1061
                                Hatch.BoundaryPath.Polyline pl = this.readPolylineBoundary();
×
1062
                                template.Path.Edges.Add(pl);
×
1063
                        }
×
1064
                        else
1065
                        {
432✔
1066
                                this._reader.ReadNext();
432✔
1067

1068
                                if (this._reader.Code != 93)
432!
1069
                                {
×
1070
                                        this._builder.Notify($"Edge Boundary path should start with code 93 but was {this._reader.Code}");
×
1071
                                        return null;
×
1072
                                }
1073

1074
                                int edges = this._reader.ValueAsInt;
432✔
1075
                                this._reader.ReadNext();
432✔
1076

1077
                                for (int i = 0; i < edges; i++)
4,320✔
1078
                                {
1,728✔
1079
                                        var edge = this.readEdge();
1,728✔
1080
                                        if (edge != null)
1,728✔
1081
                                                template.Path.Edges.Add(edge);
1,728✔
1082
                                }
1,728✔
1083
                        }
432✔
1084

1085
                        bool end = false;
432✔
1086
                        while (!end)
1,728✔
1087
                        {
1,296✔
1088
                                switch (this._reader.Code)
1,296✔
1089
                                {
1090
                                        //Number of source boundary objects
1091
                                        case 97:
1092
                                                break;
432✔
1093
                                        case 330:
1094
                                                template.Handles.Add(this._reader.ValueAsHandle);
432✔
1095
                                                break;
432✔
1096
                                        default:
1097
                                                end = true;
432✔
1098
                                                continue;
432✔
1099
                                }
1100

1101
                                this._reader.ReadNext();
864✔
1102
                        }
864✔
1103

1104
                        return template;
432✔
1105
                }
432✔
1106

1107
                private Hatch.BoundaryPath.Polyline readPolylineBoundary()
1108
                {
×
1109
                        Hatch.BoundaryPath.Polyline boundary = new Hatch.BoundaryPath.Polyline();
×
1110

1111
                        this._reader.ReadNext();
×
1112

1113
                        if (this._reader.Code != 72)
×
1114
                        {
×
1115
                                this._builder.Notify($"Polyline Boundary path should start with code 72 but was {this._reader.Code}");
×
1116
                                return null;
×
1117
                        }
1118

1119
                        //72
1120
                        bool hasBulge = this._reader.ValueAsBool;
×
1121
                        this._reader.ReadNext();
×
1122

1123
                        //73
1124
                        bool isClosed = this._reader.ValueAsBool;
×
1125
                        this._reader.ReadNext();
×
1126

1127
                        //93
1128
                        int nvertices = this._reader.ValueAsInt;
×
1129
                        this._reader.ReadNext();
×
1130

1131
                        for (int i = 0; i < nvertices; i++)
×
1132
                        {
×
1133
                                double bulge = 0.0;
×
1134

1135
                                //10
1136
                                double x = this._reader.ValueAsDouble;
×
1137
                                this._reader.ReadNext();
×
1138
                                //20
1139
                                double y = this._reader.ValueAsDouble;
×
1140
                                this._reader.ReadNext();
×
1141

1142
                                if (hasBulge)
×
1143
                                {
×
1144
                                        //42
1145
                                        bulge = this._reader.ValueAsDouble;
×
1146
                                        this._reader.ReadNext();
×
1147
                                }
×
1148

1149
                                boundary.Vertices.Add(new XYZ(x, y, bulge));
×
1150
                        }
×
1151

1152
                        return boundary;
×
1153
                }
×
1154

1155
                private Hatch.BoundaryPath.Edge readEdge()
1156
                {
1,728✔
1157
                        if (this._reader.Code != 72)
1,728!
1158
                        {
×
1159
                                this._builder.Notify($"Edge Boundary path should should define the type with code 72 but was {this._reader.Code}");
×
1160
                                return null;
×
1161
                        }
1162

1163
                        Hatch.BoundaryPath.EdgeType type = (Hatch.BoundaryPath.EdgeType)this._reader.ValueAsInt;
1,728✔
1164
                        this._reader.ReadNext();
1,728✔
1165

1166
                        switch (type)
1,728!
1167
                        {
1168
                                case Hatch.BoundaryPath.EdgeType.Line:
1169
                                        Hatch.BoundaryPath.Line line = new Hatch.BoundaryPath.Line();
1,728✔
1170
                                        while (true)
8,640✔
1171
                                        {
8,640✔
1172
                                                switch (this._reader.Code)
8,640✔
1173
                                                {
1174
                                                        case 10:
1175
                                                                line.Start = new XY(this._reader.ValueAsDouble, line.Start.Y);
1,728✔
1176
                                                                break;
1,728✔
1177
                                                        case 20:
1178
                                                                line.Start = new XY(line.Start.X, this._reader.ValueAsDouble);
1,728✔
1179
                                                                break;
1,728✔
1180
                                                        case 11:
1181
                                                                line.End = new XY(this._reader.ValueAsDouble, line.End.Y);
1,728✔
1182
                                                                break;
1,728✔
1183
                                                        case 21:
1184
                                                                line.End = new XY(line.End.X, this._reader.ValueAsDouble);
1,728✔
1185
                                                                break;
1,728✔
1186
                                                        default:
1187
                                                                return line;
1,728✔
1188
                                                }
1189

1190
                                                this._reader.ReadNext();
6,912✔
1191
                                        }
6,912✔
1192
                                case Hatch.BoundaryPath.EdgeType.CircularArc:
1193
                                        Hatch.BoundaryPath.Arc arc = new Hatch.BoundaryPath.Arc();
×
1194
                                        while (true)
×
1195
                                        {
×
1196
                                                switch (this._reader.Code)
×
1197
                                                {
1198
                                                        case 10:
1199
                                                                arc.Center = new XY(this._reader.ValueAsDouble, arc.Center.Y);
×
1200
                                                                break;
×
1201
                                                        case 20:
1202
                                                                arc.Center = new XY(arc.Center.X, this._reader.ValueAsDouble);
×
1203
                                                                break;
×
1204
                                                        case 40:
1205
                                                                arc.Radius = this._reader.ValueAsDouble;
×
1206
                                                                break;
×
1207
                                                        case 50:
1208
                                                                arc.StartAngle = this._reader.ValueAsDouble;
×
1209
                                                                break;
×
1210
                                                        case 51:
1211
                                                                arc.EndAngle = this._reader.ValueAsDouble;
×
1212
                                                                break;
×
1213
                                                        case 73:
1214
                                                                arc.CounterClockWise = this._reader.ValueAsBool;
×
1215
                                                                break;
×
1216
                                                        default:
1217
                                                                return arc;
×
1218
                                                }
1219

1220
                                                this._reader.ReadNext();
×
1221
                                        }
×
1222
                                case Hatch.BoundaryPath.EdgeType.EllipticArc:
1223
                                        Hatch.BoundaryPath.Ellipse ellipse = new Hatch.BoundaryPath.Ellipse();
×
1224
                                        while (true)
×
1225
                                        {
×
1226
                                                switch (this._reader.Code)
×
1227
                                                {
1228
                                                        case 10:
1229
                                                                ellipse.Center = new XY(this._reader.ValueAsDouble, ellipse.Center.Y);
×
1230
                                                                break;
×
1231
                                                        case 20:
1232
                                                                ellipse.Center = new XY(ellipse.Center.X, this._reader.ValueAsDouble);
×
1233
                                                                break;
×
1234
                                                        case 11:
1235
                                                                ellipse.MajorAxisEndPoint = new XY(this._reader.ValueAsDouble, ellipse.Center.Y);
×
1236
                                                                break;
×
1237
                                                        case 21:
1238
                                                                ellipse.MajorAxisEndPoint = new XY(ellipse.Center.X, this._reader.ValueAsDouble);
×
1239
                                                                break;
×
1240
                                                        case 40:
1241
                                                                ellipse.MinorToMajorRatio = this._reader.ValueAsDouble;
×
1242
                                                                break;
×
1243
                                                        case 50:
1244
                                                                ellipse.StartAngle = this._reader.ValueAsDouble;
×
1245
                                                                break;
×
1246
                                                        case 51:
1247
                                                                ellipse.EndAngle = this._reader.ValueAsDouble;
×
1248
                                                                break;
×
1249
                                                        case 73:
1250
                                                                ellipse.CounterClockWise = this._reader.ValueAsBool;
×
1251
                                                                break;
×
1252
                                                        default:
1253
                                                                return ellipse;
×
1254
                                                }
1255

1256
                                                this._reader.ReadNext();
×
1257
                                        }
×
1258
                                case Hatch.BoundaryPath.EdgeType.Spline:
1259
                                        Hatch.BoundaryPath.Spline spline = new Hatch.BoundaryPath.Spline();
×
1260
                                        int nKnots = 0;
×
1261
                                        int nCtrlPoints = 0;
×
1262
                                        int nFitPoints = 0;
×
1263

1264
                                        XYZ controlPoint = new XYZ();
×
1265
                                        XY fitPoint = new XY();
×
1266

1267
                                        while (true)
×
1268
                                        {
×
1269
                                                switch (this._reader.Code)
×
1270
                                                {
1271
                                                        case 10:
1272
                                                                controlPoint = new XYZ(this._reader.ValueAsDouble, 0, 1);
×
1273
                                                                break;
×
1274
                                                        case 20:
1275
                                                                controlPoint = new XYZ(controlPoint.X, this._reader.ValueAsDouble, controlPoint.Z);
×
1276
                                                                spline.ControlPoints.Add(controlPoint);
×
1277
                                                                break;
×
1278
                                                        case 11:
1279
                                                                fitPoint = new XY(this._reader.ValueAsDouble, 0);
×
1280
                                                                break;
×
1281
                                                        case 21:
1282
                                                                fitPoint = new XY(fitPoint.X, this._reader.ValueAsDouble);
×
1283
                                                                spline.FitPoints.Add(fitPoint);
×
1284
                                                                break;
×
1285
                                                        case 42:
1286
                                                                var last = spline.ControlPoints[spline.ControlPoints.Count - 1];
×
1287
                                                                spline.ControlPoints[spline.ControlPoints.Count - 1] = new XYZ(last.X, last.Y, this._reader.ValueAsDouble);
×
1288
                                                                break;
×
1289
                                                        case 12:
1290
                                                                spline.StartTangent = new XY(this._reader.ValueAsDouble, spline.StartTangent.Y);
×
1291
                                                                break;
×
1292
                                                        case 22:
1293
                                                                spline.StartTangent = new XY(spline.StartTangent.X, this._reader.ValueAsDouble);
×
1294
                                                                break;
×
1295
                                                        case 13:
1296
                                                                spline.EndTangent = new XY(this._reader.ValueAsDouble, spline.EndTangent.Y);
×
1297
                                                                break;
×
1298
                                                        case 23:
1299
                                                                spline.EndTangent = new XY(spline.EndTangent.X, this._reader.ValueAsDouble);
×
1300
                                                                break;
×
1301
                                                        case 94:
1302
                                                                spline.Degree = this._reader.ValueAsInt;
×
1303
                                                                break;
×
1304
                                                        case 73:
1305
                                                                spline.Rational = this._reader.ValueAsBool;
×
1306
                                                                break;
×
1307
                                                        case 74:
1308
                                                                spline.Periodic = this._reader.ValueAsBool;
×
1309
                                                                break;
×
1310
                                                        case 95:
1311
                                                                nKnots = this._reader.ValueAsInt;
×
1312
                                                                break;
×
1313
                                                        case 96:
1314
                                                                nCtrlPoints = this._reader.ValueAsInt;
×
1315
                                                                break;
×
1316
                                                        case 97:
1317
                                                                nFitPoints = this._reader.ValueAsInt;
×
1318
                                                                break;
×
1319
                                                        case 40:
1320
                                                                spline.Knots.Add(this._reader.ValueAsDouble);
×
1321
                                                                break;
×
1322
                                                        default:
1323
                                                                return spline;
×
1324
                                                }
1325

1326
                                                this._reader.ReadNext();
×
1327
                                        }
×
1328
                        }
1329

1330
                        return null;
×
1331
                }
1,728✔
1332

1333
                private void readDefinedGroups(CadTemplate template)
1334
                {
22,254✔
1335
                        this.readDefinedGroups(out ulong? xdict, out List<ulong> reactorsHandles);
22,254✔
1336

1337
                        template.XDictHandle = xdict;
22,254✔
1338
                        template.ReactorsHandles = reactorsHandles;
22,254✔
1339
                }
22,254✔
1340

1341
                private void readDefinedGroups(out ulong? xdictHandle, out List<ulong> reactors)
1342
                {
22,362✔
1343
                        xdictHandle = null;
22,362✔
1344
                        reactors = new List<ulong>();
22,362✔
1345

1346
                        switch (this._reader.ValueAsString)
22,362✔
1347
                        {
1348
                                case DxfFileToken.DictionaryToken:
1349
                                        this._reader.ReadNext();
4,298✔
1350
                                        xdictHandle = this._reader.ValueAsHandle;
4,298✔
1351
                                        this._reader.ReadNext();
4,298✔
1352
                                        Debug.Assert(this._reader.DxfCode == DxfCode.ControlString);
4,298✔
1353
                                        return;
4,298✔
1354
                                case DxfFileToken.ReactorsToken:
1355
                                        reactors = this.readReactors();
17,632✔
1356
                                        break;
17,632✔
1357
                                case DxfFileToken.BlkRefToken:
1358
                                default:
1359
                                        do
1360
                                        {
1,080✔
1361
                                                this._reader.ReadNext();
1,080✔
1362
                                        }
1,080✔
1363
                                        while (this._reader.DxfCode != DxfCode.ControlString);
1,080✔
1364
                                        return;
432✔
1365
                        }
1366
                }
22,362✔
1367

1368
                private List<ulong> readReactors()
1369
                {
17,632✔
1370
                        List<ulong> reactors = new List<ulong>();
17,632✔
1371

1372
                        this._reader.ReadNext();
17,632✔
1373

1374
                        while (this._reader.DxfCode != DxfCode.ControlString)
36,668✔
1375
                        {
19,036✔
1376
                                this._reader.ReadNext();
19,036✔
1377
                        }
19,036✔
1378

1379
                        return reactors;
17,632✔
1380
                }
17,632✔
1381

1382
                protected bool tryAssignCurrentValue(CadObject cadObject, DxfClassMap map)
1383
                {
1,224,010✔
1384
                        try
1385
                        {
1,224,010✔
1386
                                //Use this method only if the value is not a link between objects
1387
                                if (map.DxfProperties.TryGetValue(this._reader.Code, out DxfProperty dxfProperty))
1,224,010✔
1388
                                {
508,154✔
1389
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Handle)
508,154✔
1390
                                                || dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Name)
508,154✔
1391
                                                || dxfProperty.ReferenceType.HasFlag(DxfReferenceType.Count))
508,154✔
1392
                                        {
27,576✔
1393
                                                return false;
27,576✔
1394
                                        }
1395

1396
                                        object value = this._reader.Value;
480,578✔
1397

1398
                                        if (dxfProperty.ReferenceType.HasFlag(DxfReferenceType.IsAngle))
480,578✔
1399
                                        {
3,516✔
1400
                                                value = (double)value * MathUtils.DegToRadFactor;
3,516✔
1401
                                        }
3,516✔
1402

1403
                                        dxfProperty.SetValue(this._reader.Code, cadObject, value);
480,578✔
1404

1405
                                        return true;
480,578✔
1406
                                }
1407
                        }
715,856✔
1408
                        catch (Exception ex)
×
1409
                        {
×
1410
                                if (!this._builder.Configuration.Failsafe)
×
1411
                                {
×
1412
                                        throw ex;
×
1413
                                }
1414
                                else
1415
                                {
×
1416
                                        this._builder.Notify("An error occurred while assiging a property using mapper", NotificationType.Error, ex);
×
1417
                                }
×
1418
                        }
×
1419

1420
                        return false;
715,856✔
1421
                }
1,224,010✔
1422
        }
1423
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc